The first thing to learn is that drawing the line is the easy part and is done only after you have defined the line.
Consider the definition of a line. First, you have all the data that is common to all entities such as line type, color, layer, etc. Then for every type of entity that DataCAD understands there is specific data that enables its creation. For our example of a line, all that is required are the two points at either end.
The DCAL manual can elaborate on the fields that make up an entity definition. You do not need to set them all but some must be set or you cannot create your desired entity. For example, if you do not specify a specific color, DataCAD will use the current color. On the other hand, if you try to create a line without defining the endpoints you will have problems.
All of the entity types have specific fields that must be accounted for. A line is one of the simple ones with only the two end points required. Dimensions are an example of a rather complex entity type with many fields required.
So back to the question how do we draw a line?
Here is an outline:
Here is a simple routine from one of my files that I use to create entities.
PROCEDURE add_line ( pnt1, pnt2 : point; line
: line_attribs); PUBLIC;
{* Draws a single line on the screen given two points and the attributes
for the line. *}
VAR
ent : entity;
BEGIN
ent_init (ent, entlin);
ent.linpt1 := pnt1;
ent.linpt2 := pnt2;
ent.linpt1.z := zbase; ! this line will have no height
ent.linpt2.z := zbase;
ent_add (ent);
ent.ltype := line.ltype;
ent.width := line.width;
ent.spacing := line.spacing;
ent.ovrshut := line.ovrshut;
ent.color := line.color;
ent_update (ent);
ent_draw (ent, drmode_white);
END add_line;
OK, what do we have here? This is a procedure that is called with 3 parameters. These parameters are two points (end points for the line) and something described as LINE_ATTRIBS. You will not find line_attribs .html anywhere in the DCAL manual. It is a record structure that I have defined as follows:
TYPE
line_attribs = RECORD
ltype : integer;
width : integer;
spacing : real;
ovrshut : real;
color : integer;
END;
If you recall you can define your own types in DCAL. Then you are free to use your type as if it was one of the predefined types such as string or real. To access the values within this record we use 'dot' notation. So if we go back to the procedure declaration above where the parameter named LINE is of type line_attribs, we can access the individual components of the record as follows:
line.ltype
line.width
etc....
Why would you set up such a thing? The main reason is to simplify passing data back and forth. Without the line_attribs type definition our procedure declaration would look something like the following:
PROCEDURE add_line ( pnt1, pnt2 : point;
ltype : integer;
width : integer;
spacing : real;
ovrshut : real;
color : integer); PUBLIC;
See the difference? By using the type definition we are able to pass one data structure rather than 5 separate parameters.
You do not have to use record structures at all but you should understand them since the entire entity definition is based on one big record structure.
returning to our outline...
1. Tell DCAL our intention to create an entity and initialize a 'blank' entity
ent_init (ent, entlin);
this tells DCAL we want to initialize all the required fields of an entlin. We are using our variable ent of entity type to define our new line entity. All of the possible entities are described in the DCAL manual. Entlin is a constant defined within DCAL. More on this later.
2. Describe the entity by assigning values to it's fields
ent.linpt1 := pnt1;
ent.linpt2 := pnt2;
ent.linpt1.z := zbase; ! this line will have no height
ent.linpt2.z := zbase;
Here we define the required properties of an entity of type entlin. Notice the use of the zbase constant. zbase is the current z base setting. By using this we assure that the line is drawn with no height. A line will be created with its base set to the current z base. By setting it's height to match this we have defined a 'flat' line. If you wanted a line of a specific height simply plug in the desired height. Use care with your units. You may be tempted to describe an 8'-0" height as 8.0 but in DCAL all units are based on 1/32 of an inch. Some math is required to get what you want.
1 unit =1/32, 1 inch = 32 units (1x32), 1 foot = 384 units (12x32)
It is sometimes helpful to define some constants such as:
CONST
inch = 32.0;
feet = 384.0;
Then you are free to do the following:
ent.linpt2.z := (3.0 * feet) + (6.0 * inch); !
this will evaluate to 3'-6"
and it may be easier for you to understand.
back to our example...
3. Add the entity to the database
ent_add (ent);
Does exactly what it says. Adds entity 'ent' to the database. So we are done, right? Nope. We have added the definition of our entity to the database BUT this does not draw it to the screen. So, just do ent_draw then, right? Nope. Not yet.
One quirk of creating entities is you cannot set the color, line type, etc. in the first pass. If you were to draw this entity it would have all the current settings for line type, color, etc. Even if you were to assign values to these fields, as our next few lines of code will do, THEN call ent_add you would not get the desired results. This is simply the way DCAL works. What I like to do is set all the required fields of the entity. By required, I refer to those that are specific to the entity type. Then add the entity. Finally set the common fields such as color, line type, etc and update the entity.
This is what the next few lines of our example do.
4. Optionally set other fields
ent.ltype := line.ltype;
ent.width := line.width;
ent.spacing := line.spacing;
ent.ovrshut := line.ovrshut;
ent.color := line.color;
Here we set these values to those that were passed in the line parameter. Remember the line_attrib record structure we discussed above? This is where it is used. Notice that the names that sounded a little strange when we discussed line_attrib now match up exactly with the DCAL field names for entities. It is a good idea to not mix terms or typos will occur.
5. Update the entity to reflect the optional fields
ent_update (ent);
Now we can update the entity definition to have the color, line type, etc changes stick.
6. Finally, draw the entity to the screen
ent_draw (ent, drmode_white);
Again, an appropriately named procedure. But what is drmode_white? drmode_white is a constant that is available within DCAL. There are three constants to describe how to draw an entity. They are as follows:
Here is a routine that might call the add_line procedure:
var
line : line_attribs
pnt1,
pnt2 : point
begin
pnt1.x := 0.0;
pnt1.y := 0.0;
pnt2.x := 384.0;
pnt2.y := 384.0;
line.ltype := ltype_solid;
line.width := 1;
line.spacing := 1.0;
line.ovrshut := 0.0;
line.color := clr_blue;
add_line (pnt1, pnt2, line);
end;
This will draw a one foot long line at an angle of 45 degrees. It's color will be blue and line type will be solid. It will have a width of 1 and no overshoot.
If you look at the definition of the point type you will see that it too is a record of 3 reals. A point is defined as follows:
point = record
x : real;
y : real;
z : real;
end;
The x, y and z values correspond to the x, y and z coordinates of this point. You can define a point as we do above by setting the values or you can use a function such as getpoint that will return a point. We have already covered the line_attribs definition but you may notice some terms used in conjunction with the fields of this record. For convenience, DCAL defines certain constant values for often-used things like line types or colors. The manual will list them all but some examples are the built-in line types which are defined as:
User line types begin with the number 4 and will go up to the maximum defined user line type.
Colors are similarly defined as:
Entity types such as entlin, entarc, etc are also defined as convenient constants. Again, the manual lists all these values.
That should explain why the record fields are defined as 'integer' but you see some text used as the value. The text corresponds to the predefined constant. Remember from the basic tutorial that you can define your own constants. So I could also have written...
ent.linpt2.x := 1.0 * feet;
assuming I have defined a constant called 'feet' somewhere in my project. You can use any expression in such an assignment as long as it evaluates to the correct data type. What? You could say 2.0 + 2.0 or any complex calculation as long as it evaluates to a real type. If you were to say ABSI(-489) this would fail since it would return the absolute value of the integer expression (489) which is an integer value.
Grab the entity utilities module from DDN. There are plenty of routines in it to make different types of entities.
The code below may be cut and pasted into a text file. Save it as addline.dcs. This example illustrates the use of what we have covered here.
PROGRAM addline; {addline.dcs}
TYPE
line_attribs = RECORD
ltype : integer;
width : integer;
spacing : real;
ovrshut : real;
color : integer;
END;
PROCEDURE add_line ( pnt1, pnt2 : point;
line : line_attribs);
PUBLIC;
{* Draws a single line on the screen given two points and the attributes
* for the line.
*}
VAR
ent : entity;
BEGIN
ent_init (ent, entlin);
ent.linpt1 := pnt1;
ent.linpt2 := pnt2;
ent.linpt1.z := zbase; ! this line will have no height
ent.linpt2.z := zbase;
ent_add (ent);
ent.ltype := line.ltype;
ent.width := line.width;
ent.spacing := line.spacing;
ent.ovrshut := line.ovrshut;
ent.color := line.color;
ent_update (ent);
ent_draw (ent, drmode_white);
END add_line;
PROCEDURE main;
var
line : line_attribs;
pnt1,
pnt2 : point;
begin
pnt1.x := 0.0;
pnt1.y := 0.0;
pnt2.x := 384.0;
pnt2.y := 384.0;
line.ltype := ltype_solid;
line.width := 1;
line.spacing := 1.0;
line.ovrshut := 0.0;
line.color := clrblue;
add_line (pnt1, pnt2, line);
end main;
begin
main;
end addline.
Notes:
This article was originally posted to the DDN mailing list. At the time it was posted, a few questions were asked and points raised. Here is some additional information related to this article:
Always initialize your data. If you look at the addline.dcs sample code above you will notice that pnt1 and pnt2 are given values for their x and y components. What you do not see is a z component. In this case it is not critical since the add_line routine will insert zbase for the z component of any points passed to it. However, it is important to remember that unless you are certain all values will contain valid data, you should initialize them yourself. Never assume that DCAL will handle this or that it is not needed.
Some useful constant values for our metric friends
CONST
mm = 1.25984252; {1.0 / .79375}
cm = 12.5984252;
metre = 1259.84252;
Finally, note that all point locations are based on the drawing origin. The point (0.0, 0.0, 0.0) is equivalent to the drawing origin and a z height of zero. (384.0, 384.0, 384.0) would be a point one foot from the origin in the x, y, and z directions.
Thank you for printing this page. Please feel free to contact us for further assistance. You can call our sales department at +1 (800) 394-2231, Monday through Friday from 8:00 a.m. to 5:00 p.m. Eastern time or send an e-mail message to info@datacad.com.