| Chapter 8 - Sample Macros |
|---|
|
The following is a listing of the
several sample macros included with your DCAL development kit. A
short description is included for each macro so that you may more
easily find those which apply to your development task.
Sample Macro Directory ARROW Specifically designed as an introduction to DCAL for the beginner. The macro enters a simple arrow into a drawing made up of lines. The macro is extensively commented, explaining virtually every line of code in detail. ATR Demonstrates how to create symbols in a drawing, and how to add attributes to entities, symbol descriptions, and to a drawing at the system level. CONCRETE 3D parametric macro using entities of type slab as a basic building block. The macro also contains some good examples of dragging cases. CROP Demonstrates how the function CLIP may be used as an editing tool, as wel* as how to perform a basic editing operation on the database. DAFILE Demonstrates all basic techniques necessary for operating upon a direct access, binary datafile. It uses FORMLIB for capturing and editing input data. DOORLABL Complete source code to theDataCAD DOORLABL macro. DRAG Demonstrates nearly all dragging routines available in DCAL. ENTER3D Demonstrates the techniques used for entering 3D entities from parallel projections (such as elevations). FORMLIB A reusable toolkit for entering and editing collections of data via a forms type screen input system. This library is used by the sample macros FORM, FORMATR, and DAFILE. FORMATR Allows the editing of sytem, symbol, and entity attributes via a forms-like interface. FORM Outlines the steps required for using FORMLIB to create custom input screens. GETARC Demonstrates the use of the function getarc which is used in many DC-Modeler menus. HATCH Demonstrates how to use the hatch_mode function. LYRUTIL Allows saving and reloading collections of layers. Primarily designed for packing large drawing files or recovering corrupted data files. MENU3D Demonstrates all menu calls to the 3D Viewer and DC-Modeler. PLOT Demonstrates the use of the plot_mode procedure. POLYLINE Demonstrates polyvert procedures and functions as well as polyline input. REVSURF Demonstrates techniques for creating surfaces of revolution. READTEXT Demonstrates techniques for reading text files and adding their contents to a drawing. SPIRAL The parametric SPIRAL stair macro included with DataCAD. STAIR The parametric STAIR macro included with DataCAD. STUD The parametric STUD macro for creating drawings of stud wall construction. SYMEXP Takes the instance of a symbol in a drawing and explodes it into individual entities. SYMTMPLT Examines all of the symbols in a drawing and creates a template file from the information. Particularly useful for DXF-IN operations. VIEWMAST Complete source code to the VIEWMAST macro included with the DC- Modeler. Demonstrates nearly all of the functions and procedures related to viewing and saved views. WNDWLABL The WNDWLABL macro included with DataCAD. WRITE Demonstrates how to scan a database and write out the entire contents of each entity to a text file. May be used as a skeleton for macros which interrogate the database and write its contents to a file in one or another form for post processing. WRTUTL A set of utilities for creating messages. WRTUTL is used by many of the sample macros in this collection. Each macro is in a separate sub-directory. Many macros include a .lnk or a .bat file. The .lnk file contains the linker statement used by the dcl.exe linker. When there are more than one object file, the .lnk file simplifies the linking process. Take for example the CONCRETE macro, to link it, use the command: dcl <concrete.lnk The .bat files are like MAKE files in that they recompile all modules of the macro and then relink the macro. To recompile and relink the entire CONCRETE macro, type: CONCRETE The batch and linker files assume that each sample macro is in a separate sub-directory, and that the system includes files are in a sub- directory at the same directory level. As well, macros which use the WRTUTL library also assume that the WRTUTL subdirectory is at the same directory level. MTEC ----|-- DCX ----|-- INC System includes files | |-- WRTUTL Message utilities | |-- ARROW Arrow macro | |-- CONCRETE Concrete macro | . | . etc. | . |-- DWG |-- SUP |-- SYM |-- TPL In each macro and in each .lnk file, the pathnames for system includes files, and for object files are designed with the above directory structure in mind. All pathnames are relative, such that the name of the DCX subdirectory is unimportant, only the location of the INC and WRTUTL directories relative to the macro source code. Hatch This program is a simple example of the routine hatch_mode. It uses a hardwired brick hatch pattern. PROGRAM hatch; #include '../wrtutl/wrtutl.inc' #include '../inc/_hatch.inc' CONST ssNum = 15; PROCEDURE getOrigin (org : IN OUT point); VAR done: boolean; result : integer; key : integer; pt : point; BEGIN done := false; REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtlvl (Hatch); wrtmsg (Enter hatch origin.); result := getpoint (pt, key); IF result = res_escape THEN IF key = s0 THEN done := true; END; ELSIF result = res_normal THEN org := pt; done := true; END; UNTIL done; END getOrigin; PROCEDURE getHtype (htype : IN OUT integer); VAR done : boolean; key : integer; BEGIN done := false; REPEAT lblsinit; lblset ( 1, 'Normal); lblset ( 2, 'Outer); lblset ( 3, 'Ignore); lblset (20, 'Exit); lblson; wrtlvl (Hatch); wrtmsg (Select hatch type.); getesc (key); IF key = f1 THEN htype := htype_normal; done := true; ELSIF key = f2 THEN htype := htype_outer; done := true; ELSIF key = f3 THEN htype := htype_ignore; done := true; ELSIF key = s0 THEN done := true; END; UNTIL done; END getHtype; PROCEDURE hatch_main; VAR sl : scanLineType; done : boolean; result : integer; brk : integer; key : integer; mode : mode_type; mode1 : mode_type; ent : entity; addr : entaddr; minPt : point; maxPt : point; min1 : point; max1 : point; frst : boolean; ang : real; scale : real; org : point; htype : integer; BEGIN done := false; setpoint (org, 0.0); ang := 0.0; htype := htype_normal; scale := 1.0; REPEAT REPEAT lblsinit; lblset (10, 'HtchType); lblset (12, 'Scale); lblset (13, 'Angle); lblset (14, 'Origin); lblset (20, 'Exit); wrtlvl (Hatch); result := getmode (hatch', mode, key); IF result = res_escape THEN IF key = f0 THEN getHtype (htype); ELSIF key = s2 THEN wrtmsg (Enter hatch scale: ); getrll (scale); ELSIF key = s3 THEN wrtmsg (Enter hatch angle: ); getang (ang); ELSIF key = s4 THEN getOrigin (org); ELSIF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN { find the extents of the entities and place them into a selection set } ssClear (ssNum); frst := true; addr := ent_first (mode); WHILE ent_get (ent, addr) DO addr := ent_next (ent, mode); ssAdd (ssNum, ent); ent_extent (ent, min1, max1); IF frst THEN minPt := min1; maxPt := max1; frst := false; ELSE minPt.x := min (min1.x, minPt.x); minPt.y := min (min1.y, minPt.y); minPt.z := min (min1.z, minPt.z); maxPt.x := max (max1.x, maxPt.x); maxPt.y := max (max1.y, maxPt.y); maxPt.z := max (max1.z, maxPt.z); END; END; brk := 0; mode_init (mode); mode_ss (mode, ssNum); { get the entities out of the selection set} { draw the horizontal lines 2 2/3 inches apart } sl.ang := 0.0; setpoint (sl.origin, 0.0); sl.delta.x := 0.0; sl.delta.y := 2.6667 * 32.0; sl.numdash := 0; hatch_mode (mode, sl, zbase, zhite, org, ang, scale, htype, getlyrcurr, minPt, maxPt, true, brk, true); { draw the vertical (dashed) lines every 8 inches } sl.ang := halfpi; { oriented vertically } setpoint (sl.origin, 0.0); sl.delta.x := 2.6667 * 32.0; sl.delta.y := 4.0 * 32.0; sl.numdash := 2; sl.dash [1] := 2.6667 * 32.0; sl.dash [2] := 2.6667 * 32.0; sl.dashDraw [1] := true; sl.dashDraw [2] := false; hatch_mode (mode, sl, zbase, zhite, org, ang, scale, htype, getlyrcurr, minPt, maxPt, true, brk, true); ssClear (ssNum); END; UNTIL done; END hatch_main; BEGIN hatch_main; END hatch. Plot1 This program gives examples of the plotter routines available through a DCAL macro. PROGRAM plot1; #include '../wrtutl/wrtutl.inc' #include '../inc/_plot.inc' VAR done : boolean; key : integer; cent : point; wndwMin : point; wndwMax : point; vwptMin : point; vwptMax : point; tofile : boolean; fname : str80; paperx : real; papery : real; init : boolean; ang : real; ManyPens : boolean; PROCEDURE getPaper (size : integer; custx, custy : real; x, y : IN OUT real); BEGIN IF size = 1 THEN x := 10.5; y := 8.0; ELSIF size = 2 THEN x := 16.0; y := 10.0; ELSIF size = 3 THEN x := 21.0; y := 16.0; ELSIF size = 4 THEN x := 33.0; y := 21.0; ELSIF size = 5 THEN x := 43.0; y := 33.0; ELSE x := custx; y := custy; END; x := x * 32.0; { convert from inches to world coords } y := y * 32.0; { convert from inches to world coords } END getPaper; PROCEDURE wrtPaperErr; BEGIN errStart; errDis (paperx); errStr ( ); errDis (papery); errShow; END wrtPaperErr; PROCEDURE doplot; VAR plot : plot_type; mode : mode_type; key : integer; BEGIN IF plot_open (pltpenwidth, pltpenspeed, paperx, papery, tofile, 'test.plt', 1, plot) = fl_ok THEN wrterr (ok); wrtmsg (Plotting...); mode_init (mode); mode_lyr (mode, lyr_on); plot_mode (plot, mode, ManyPens, pltpensort, pltcolor, vwptMin, vwptMax, wndwMin, wndwMax, cent, ang); plot_close (plot); END; END doplot; PROCEDURE getVwpt (min, max : IN OUT point); VAR minPt, maxPt : point; screenRatio : real; paperRatio : real; minBox, maxBox : point; done : boolean; key : integer; result : integer; pt1 : point; pt2 : point; pt3 : point; BEGIN IF (absr (wndwMax.x - wndwMin.x) < 0.01) OR (absr (wndwMax.y - wndwMin.y) < 0.01) THEN wrterr (Invalid window, select window first.); ELSE { draw the sheet of paper on the screen } vwptClear; currWndw (minPt, maxPt); screenRatio := (maxPt.x - minPt.x) / (maxPt.y - minPt.y); paperRatio := paperx / papery; IF paperRatio < screenRatio THEN ELSE END; done := false; REPEAT REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtmsg (Enter first corner of viewport.); result := getpoint (pt1, key); IF result = res_escape THEN IF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtmsg (Enter second corner of viewport.); ratioBox := true; ratioRatio := (wndwMax.x - wndwMin.x)/(wndwMax.y - wndwMin.y); rubbx := true; result := getpoint (pt2, key); ratioBox := false; IF result = res_escape THEN IF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtmsg (Position viewport.); minBox.x := pt1.x - pt2.x; minBox.y := pt1.y - pt2.y; setPoint (maxBox, 0.0); setpoint (pt3, 0.0); dragBoxMove (pt3, minBox, maxBox, linecolor); result := getpoint (pt3, key); IF result = res_escape THEN IF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN END; END; END; UNTIL done; wrtmsg (Enter vwptMin.x: ); getdis (min.x); wrtmsg (Enter vwptMin.y: ); getdis (min.y); wrtmsg (Enter vwptMax.x: ); getdis (max.x); wrtmsg (Enter vwptMax.y: ); getdis (max.y); END; END getVwpt; PROCEDURE getWndw (min, max : IN OUT point); VAR done : boolean; key: integer; result : integer; pt1: point; pt2: point; BEGIN done := false; REPEAT REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtmsg (Enter first corner of window.); result := getpoint (pt1, key); IF result = res_escape THEN IF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtmsg (Enter second corner of window.); rubbx := true; result := getpoint (pt2, key); IF result = res_escape THEN IF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN order (pt1.x, pt2.x, min.x, max.x); order (pt1.y, pt2.y, min.y, max.y); { if we entered both points, get out } done := true; ELSE { if we pressed exit, go back to the previous loop } done := false; END; END; UNTIL done; END getWndw; PROCEDURE extra; VAR done : boolean; key : integer; BEGIN done := false; REPEAT lblsinit; lblset ( 1, 'Plot); lblsett ( 2, 'To File', tofile); lblset ( 3, 'Vwpt); lblset ( 4, 'Wndw); lblset ( 5, 'Paper); lblset (20, 'Exit); lblson; wrtmsg (Select plotter function.); wrtPaperErr; getesc (key); IF key = f1 THEN doPlot; ELSIF key = f2 THEN tofile := NOT tofile; ELSIF key = f3 THEN getVwpt (vwptMin, vwptMax); ELSIF key = f4 THEN getWndw (wndwMin, wndwMax); ELSIF key = f5 THEN ELSIF key = s0 THEN done := true; END; UNTIL done; END extra; PROCEDURE layout; VAR done : boolean; pt : point; key: integer; result : integer; min: point; max: point; str: str80; fac: real; BEGIN done := false; REPEAT lblsinit; lblset (20, 'Exit); lblson; wrtlvl (Layout); wrtmsg (Enter center of plot.); getPaper (pltPSize, pltPCustx, pltPCusty, paperx, papery); scale_get (pltScaleNum, fac, str); setpoint (pt, 0.0); min.x := -paperx / 2.0 / fac; min.y := -papery / 2.0 / fac; max.x := -min.x; max.y := -min.y; dragBoxMove (pt, min, max, linecolor); result := getpoint (pt, key); IF result = res_escape THEN IF key = s0 THEN done := true; END; END; UNTIL done OR (result = res_normal); IF NOT done THEN pltcentx := pt.x; pltcenty := pt.y; END; END layout; PROCEDURE doplotData; VAR vwptMin : point; vwptMax : point; wndwMin : point; wndwMax : point; str : str80; fac : real; plot : plot_type; mode : mode_type; cent : point; ang : real; BEGIN getPaper (pltPSize, pltPCustx, pltPCusty, paperx, papery); scale_get (pltScaleNum, fac, str); vwptmin.x := 0.0; vwptmin.y := 0.0; vwptmax.x := paperx; vwptmax.y := papery; wndwMin.x := pltCentx - paperx / 2.0 / fac; wndwMin.y := pltCenty - papery / 2.0 / fac; wndwMax.x := pltCentx + paperx / 2.0 / fac; wndwMax.y := pltCenty + papery / 2.0 / fac; setpoint (cent, 0.0); ang := 0.0; IF plot_open (pltpenwidth, pltpenspeed, paperx, papery, false, 'test.plt', 1, plot) = fl_ok THEN wrterr (ok); wrtmsg (Plotting...); mode_init (mode); mode_lyr (mode, lyr_on); plot_mode (plot, mode, ManyPens, pltpensort, pltcolor, vwptMin, vwptMax, wndwMin, wndwMax, cent, ang); plot_close (plot); END; END doplotData; PROCEDURE scale; VAR i : integer; str : str80; done : boolean; fac : real; BEGIN done := false; REPEAT lblsinit; FOR i := 1 TO 18 DO scale_get (i, fac, str); lblset (i, str); cvrllst (fac, str); lblmsg (i, str); END; lblset (20, 'NoChange); lblson; wrtlvl (Scale); wrtmsg (Select plotter scale.); getesc (key); i := fnKeyConv (key); IF ((1 <= i) AND (i <= 18)) THEN pltScaleNum := i; done := true; ELSIF key = s0 THEN done := true; END; UNTIL done; END scale; PROCEDURE doPaper; VAR done: boolean; key : integer; result : integer; r : real; BEGIN done := false; REPEAT lblsinit; lblsett ( 1, '8.5x11A', pltPsize = 1); lblsett ( 2, '11x17 B', pltPsize = 2); lblsett ( 3, '18x24 C', pltPsize = 3); lblsett ( 4, '24x36 D', pltPsize = 4); lblsett ( 5, '36x48 E', pltPsize = 5); lblsett ( 7, ' Custom', pltPsize = 6); lblset (20, 'NoChange); lblson; wrtlvl (PaperSiz); wrtmsg (Select paper size.); getPaper (pltPSize, pltPCustx, pltPCusty, paperx, papery); wrtPaperErr; getesc (key); IF key = f1 THEN pltPsize := 1; ELSIF key = f2 THEN pltPsize := 2; ELSIF key = f3 THEN pltPsize := 3; ELSIF key = f4 THEN pltPsize := 4; ELSIF key = f5 THEN pltPsize := 5; ELSIF key = f7 THEN wrtmsg (Enter plotting width ("X" axis):); r := pltPcustx * 32.0; getdis (r); pltPcustx := r / 32.0; wrtmsg (Enter plotting height ("Y" axis):); r := pltPcusty * 32.0; getdis (r); pltPcusty := r / 32.0; pltPsize := 6; { custom } ELSIF key = s0 THEN done := true; END; UNTIL done; END doPaper; VAR str : str80; str1 : str80; i : integer; fac : real; BEGIN done := false; IF NOT init THEN getPaper (pltPSize, pltPCustx, pltPCusty, paperx, papery); tofile := false; fname := ''; setpoint (vwptMin, 0.0); vwptMax.x := paperx; vwptMax.y := papery; setpoint (wndwMin, 0.0); setpoint (wndwMax, 0.0); setpoint (cent, 0.0); ang := 0.0; ManyPens := false; init := true; END; REPEAT lblsinit; lblset ( 1, 'Plot); lblmsg ( 1, 'Plot all layers that are turned on.); lblset ( 2, 'Backgrnd); lblmsg ( 2, 'Background plotting.); lblset ( 3, 'To File); lblset ( 4, 'Scale); str := 'Current scale = '; scale_get (pltScaleNum, fac, str1); strcat (str, str1); lblmsg ( 4, str); lblset ( 5, 'PaperSiz); lblset ( 6, 'PenSpeed); lblmsg ( 6, 'Set plotter pen speed.); lblset ( 7, 'PenWidth); lblmsg ( 7, 'Set plotter pen width.); lblset ( 8, 'Partial); lblset ( 9, 'Layout); lblset (10, 'Lyout Sz); lblset (11, 'LyoutDiv); lblsett (12, 'Rotate', pltRot); lblsett (13, 'ClrPlot', pltColor); IF ManyPens AND pltColor THEN lblset (14, 'Set Pens); lblsett (15, 'PenSort', pltpensort); END; lblsett (16, 'ManyPens', ManyPens); lblset (19, 'extra); lblset (20, 'Exit); lblson; wrtlvl (Plotter); wrtmsg (Select plotter function.); getesc (key); IF key = f1 THEN doplotData; ELSIF key = f2 THEN ELSIF key = f3 THEN ELSIF key = f4 THEN scale; ELSIF key = f5 THEN doPaper; ELSIF key = f6 THEN wrtlvli (146 {'PenSpeed'}); wrtmsgi (172); i := pltpenspeed; getint (i); pltpenspeed := absi (i); ELSIF key = f7 THEN ELSIF key = f8 THEN ELSIF key = f9 THEN layout; ELSIF key = f0 THEN ELSIF key = s1 THEN ELSIF key = s2 THEN ELSIF key = s3 THEN pltColor := NOT pltColor; ELSIF key = s4 THEN IF pltColor AND ManyPens THEN END; ELSIF key = s5 THEN pltpensort := NOT pltpensort; ELSIF key = s6 THEN ManyPens := NOT ManyPens; ELSIF key = s9 THEN extra; ELSIF key = s0 THEN done := true; END; UNTIL done; END plot1. Stair PROGRAM stair; VAR str1 : string (80); str : string (20); ch : char; init, getout, done1, done : boolean; result, clr, oldcolor, stairtype, key : integer; stairnum, numrisers : integer; angle1, { angle up stairs } angle2: real;{ angle across stairs } cent1, cent, pt1, pt2, pt3, pt4 : point; zstart, riserheight, depth, width : real; { ************************************* * * * <- depth ->* * * * pt4-------pt3 * * | ^ |* * | | |* * | | |* * | w |* * | i |* * | d |* * | t |* * | h |* * | | |* * | | |* * | v |* * pt1-------pt2 * * * ************************************* } PROCEDURE addriser (pt1, pt2, pt3, pt4 : point; num : integer); CONST zero = 0.0; VAR ent : entity; BEGIN ent_init (ent, entblk); ent.blkpnt [ 1].x := pt1.x; ent.blkpnt [ 1].y := pt1.y; ent.blkpnt [ 1].z := zstart + (float (num) * riserheight); ent.blkpnt [ 2].x := pt2.x; ent.blkpnt [ 2].y := pt2.y; ent.blkpnt [ 2].z := zstart + (float (num) * riserheight); ent.blkpnt [ 3].x := pt4.x; ent.blkpnt [ 3].y := pt4.y; ent.blkpnt [ 3].z := zstart + (float (num) * riserheight); ent.blkpnt [ 4].x := pt1.x; ent.blkpnt [ 4].y := pt1.y; ent.blkpnt [ 4].z := zstart + (float (num) * riserheight) + riserheight; ent_add (ent); ent_draw (ent, drmode_white); END addriser; PROCEDURE doesc (key : integer; getout : OUT boolean); BEGIN IF key = f1 THEN wrterr (Drawing stairs by left side.); stairtype := 1; ELSIF key = f2 THEN wrterr (Drawing stairs by right side.); stairtype := 2; ELSIF key = f3 THEN wrterr (Drawing stairs by center line.); stairtype := 3; ELSIF key = f5 THEN wrtmsg (Enter the number of risers: ); getint (numrisers); ELSIF key = f6 THEN wrtmsg (Enter the width of the stairs: ); getdis (width); ELSIF key = f7 THEN wrtmsg (Enter the height of the risers: ); getdis (riserheight); ELSIF key = f8 THEN wrtmsg (Enter the depth of tread: ); getdis (depth); ELSIF key = f9 THEN wrtmsg (Select color of stairs.); getclr (clr); ELSIF key = f0 THEN wrtmsg (Enter the starting height of the stairs: ); getdis (zstart); ELSIF key = s0 THEN getout := true; END; END doesc; PROCEDURE setkeys; BEGIN lblsinit; lblsett ( 1, ' Left', (stairtype = 1)); lblsett ( 2, ' Right', (stairtype = 2)); lblsett ( 3, ' Center', (stairtype = 3)); lblset ( 5, 'NumRisrs); lblset ( 6, 'Width); lblset ( 7, 'Height); lblset ( 8, 'Depth); lblset ( 9, 'Color); lblset (10, 'Start Ht); lblset (20, 'Exit); lblson; END setkeys; PROCEDURE get_point1; BEGIN REPEAT setkeys; IF stairtype = 3 THEN str := 'center'; ELSIF stairtype = 1 THEN str := 'left side'; ELSE str := 'right side'; END; str1 := 'Enter '; strcat (str1, str); strcat (str1, ' of stairs at bottom.); wrtmsg (str1); result := getpoint (cent, key); IF result = res_escape THEN doesc (key, getout); END; UNTIL (result = res_normal) OR getout; END get_point1; PROCEDURE get_point2; BEGIN REPEAT lblsinit; lblset (20, 'Exit); lblson; str1 := 'Enter another point on the '; strcat (str1, str); strcat (str1, ' of the stairs.); wrtmsg (str1); rubln := true; result := getpoint (cent1, key); IF result = res_escape THEN IF key = s0 THEN getout := true; END; END; UNTIL (result = res_normal) OR getout; END get_point2; PROCEDURE setitup; BEGIN light (true); lblsinit; lblset ( 8, '********); lblset (10, 'WORKING); lblset (12, '********); lblson; wrtmsg (Constructing stairs, please wait.); angle1 := angle (cent, cent1); angle2 := angle1 - radians (90.0); { calculate the first point, from now on, all of the cases are the same } IF stairtype = 3 THEN { we have the center, move to the left half the width } polar (cent, angle2, -width / 2.0, pt1); ELSIF stairtype = 1 THEN { we already have the left, don't need to calculate anything } pt1 := cent; ELSE { we have the right side, move to the left by an entire stair width } polar (cent, angle2, -width, pt1); END; oldcolor := linecolor; linecolor := clr; stairnum := 1; END setitup; PROCEDURE doit; BEGIN stopgroup; WHILE stairnum <= numrisers DO polar (pt1, angle1, depth, pt2); polar (pt1, angle2, width, pt4); polar (pt2, angle2, width, pt3); addriser (pt1, pt2, pt3, pt4, stairnum -1); pt1 := pt2; stairnum := stairnum + 1; END; stopgroup; light (false); END doit; PROCEDURE initialize; BEGIN stairtype := 1; clr := linecolor; numrisers := 12; width := 1536.0; riserheight := 192.0; depth := 256.0; zstart := 0.0; init := true; END initialize; BEGIN { set up defaults } IF NOT init THEN initialize; END; getout := false; wrtlvl (Stair); REPEAT get_point1; IF NOT getout THEN get_point2; IF NOT getout THEN setitup; doit; linecolor := oldcolor; END; END; UNTIL getout; END stair. |