The DataCAD Developer Network (DDN) is an online resource for information and support for DCAL® (DataCAD Applications Language) developers as well as anyone interested in creating fonts, toolbars, hatch patterns, or linetypes for use in DataCAD.
#32068 by shovavnik
Sun Jan 20, 2008 5:27 pm
Hi all,

I have a symbol file that I need to add to a drawing using D4D and then create one or more entities based on the symbol.

The symbol file is located at:
C:\DataCAD 12\Symbols\MySymbol.dsf

Using sym_read, I've managed to add the symbol to the drawing, but I can't figure out how to create the entity.

I've tried this and other variations:
Code: Select allsymread('C:\DataCAD 12\Symbols\MySymbol', 'MySymbol', sym);
ent_init(ent, entsym);
ent.symstart := sym.addr;
ent_add(ent);


But none of them seem to work. Does anyone have any ideas or an example of how to do it correctly?

By the way, it seems that if there is another symbol in the symbol library with the same name (e.g, MySymbol), it will ALSO be added to the drawing, even though a full path is specified in sym_read. Does that make sense?

Regards,
shovavnik
#32072 by Jon C. Hubart
Mon Jan 21, 2008 9:01 am
I'm am not yet familiar with the D4D variations but in classic DCAL I used the following to insert a single instance of a symbol:
Code: Select allsettran (arrowmat, sympos.x, sympos.y, 0.0);
ent_init (ent, entsym);
ent.symname := sym.name;
ent.symaddr := sym.addr;
ent.symmod := arrowmat;
ent_add  (ent);
ent_rotate (ent, sympos, ang1);
ent_enlarge (ent, sympos, globscale, globscale, globscale);
ent_update (ent);
ent_draw (ent, drmode_white);
#32073 by devinder
Mon Jan 21, 2008 10:10 am
You just need to specify the name of symbol when adding entity. DataCAD will automatically look up the addr of the symbol and assign it to ent.symstart.

Code: Select allent_init(ent, entsym);
ent.symname := 'C:\DataCAD 12\Symbols\MySymbol';
ent_add(ent);
#32218 by shovavnik
Thu Jan 24, 2008 6:38 pm
Sorry it took me so long to get back to you. Thanks for the help!

Devinder:
I didn't realize the symname could take a path. From the examples I saw, it always takes just the file name or symbol name.

From what I can see, all 4 of these lines are necessary to add a symbol from a path (as opposed to a symbol from the library?) to a drawing. Without sym_read, it doesn't work.

Code: Select allsymread('C:\DataCAD 12\Symbols\MySymbol', 'MySymbol', sym);
ent_init(ent, entsym);
ent.symname := 'C:\DataCAD 12\Symbols\MySymbol';
ent_add(ent);


However it only seems to add the reference to the symbol and doesn't add it to the drawing surface.


Jon:
I thought your example would help me out in that regard, but I wasn't able to get it to work.

That is, it doesn't look like the entity is actually added to the drawing surface.

How do you know which modmat to use? (from the view? from the entity? from somewhere else?)

Also, how do you calculate the global scale?
#32219 by shovavnik
Thu Jan 24, 2008 6:39 pm
By the way, I noticed one discrepancy in the way symbol entities are loaded. I'm not sure if it's a bug or intentional. If you specify the path for a symbol whose file name is identical to the name of another symbol already in the library, BOTH symbol references are added to the entity, even though the full path was specified.

For example, if you run these statements:
Code: Select allent_init(ent, entsym);
ent.symname := 'C:\DataCAD 12\Symbols\SomeFolder\MySymbol';
ent_add(ent);


and you also have another symbol in the library at 'C:\DataCAD 12\Symbols\ADifferentFolder\MySymbol', then that statement will add both symbols to the drawing.

Is this a bug or by design? (I think it can be justified either way, but I just need to know what to prepare for...)
#32238 by devinder
Fri Jan 25, 2008 9:10 am
Code: Select allsymread(fname, symname: sym_str; var symbol: sym_type)

syread has 2 string parameters. The first one is filename. If this is absolute path DataCAD will use it, if it is relative path(or no path), DataCAD uses various path strings to make the path absolute. If the symbol is found and loads into drawing corrrectly, It then renames itself to symname, if sym_str is not empty string. On symname being empty the symbol name is same as fname. Ex.
Code: Select allsymread('C:\DataCAD 12\Symbols\MySymbol', '', sym)

If you look at the symbol structure, it stores only one string parameter. Once the path is stripped out from, symname , there is no way to tell from where the symbol was loaded. There are no validations on symbol name string. You can give any name with/without any path.

It is not feasible to match all entity parameters to all other entities in other symbols. Consider a drawing with 50 symbols each symbol averaging 50 entities. Now you wish to add a new symbol with 10 entities. The max number of computations to compare entities will be (10*50*50=25000) for it to consider that this symbol is not previously loaded.
#32244 by shovavnik
Fri Jan 25, 2008 9:56 am
So, if I understand correctly, instead of running the intensive comparison, DataCAD just adds all the symbols it can find with that name (e.g., 'MySymbol') to the drawing.

In other words, if I want to avoid ambiguity with symbols, it doesn't matter where the symbols are located, just their names.

Am I on the right track here?
#32246 by shovavnik
Fri Jan 25, 2008 10:05 am
I'm still trying to figure out how to actually draw the entity (that's based on the symbol).

I tried Jon's code and various variations (changing the scale, with and without rotation, etc.) but I can't seem to get it to work. I'm sure I'm just missing something simple and basic.

I know the entsym entity is added to the drawing.

Can anyone provide an example or point me to any reference that shows a full example of drawing a symbol entity?
#32248 by devinder
Fri Jan 25, 2008 10:25 am
Am I on the right track here?
Yes

Currently you are adding entity at (0,0,0), and you would need to call
Code: Select allent_draw(ent, drmode_white)
to draw the entity at DataCAD's absolute zero.

If you need to place an entity twice in size at the mouse click location with z base of 12 foot you would do:
Code: Select all...
cattran(ent.modmat, 2, 2, 2);
cattran(ent.modmat, l.getp.curs.x, l.getp.curs.y, 12 * onefoot);
ent_add(...);
ent_draw(...);

NOTE: Please see arrow macro for how to get input co-ordinates, if you have doubt.
#32263 by shovavnik
Fri Jan 25, 2008 11:51 am
I've got the state machine down pat (I think) and I'm already using getpoint to get the cursor location. Also, when you write "ent.modmat", I assume you mean "ent.Matrix". Let me know if I'm wrong.

I'm trying to add a symbol at the point {x: 8832, y: 6400, z: 0} by clicking on that point and catching the cursor point with getpoint.

When I trace using Delphi, I can see that after ent_init, ent.Matrix is 4x4 identity matrix. After using
Code: Select allcattran(ent.Matrix, pt.x, pt.y, pt.z);

ent.Matrix looks like
Code: Select all[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[8832, 6400, 0, 1]


The code I'm using to draw the entity is this:
Code: Select allent_init(ent, entsym);
ent.symname := symName;
ent_add(ent);
cattran(ent.Matrix, pt.x, pt.y, pt.z);
ent_update(ent);
ent_draw(ent, drmode_white);


But it's not working.

Also, I noticed that the coordinates of the point that I click on are always a bit different between what DataCAD says and what DCAL picks up. Instead of (508, 1016, 0) in DataCAD, for example, Delphi shows (512, 1280, 0). Could this be related? I ran the arrow example just to see if I could find something helpful from there, like you suggested, but it also has this discrepancy.

What am I missing?
#32266 by devinder
Fri Jan 25, 2008 12:13 pm
This should work. Could you email the sample source project to techsupport@datacad.com along with the symbol you are trying to load, and I will take a look at it.
#32267 by shovavnik
Fri Jan 25, 2008 12:43 pm
I sent the email with the project. Let me know if it doesn't come through.
#32324 by shovavnik
Mon Jan 28, 2008 1:37 pm
In case anybody else has issues similar to this, the following code works.

This code:
1. loads a symbol from a DSF file,
2. adds an instance of the symbol to the drawing (if it doesn't already exist in the drawing),
3. creates a symbol entity based on the symbol,
4. performs manipulation(s) on the symbol entity,
5. draws the symbol entity at point pt.

Code: Select allif sym_read(symPath, symName, sym) = 0 then // symPath should not contain the file extension
begin
  ent_init(ent, entsym);
  ent.symname := symName; // use symPath if you want to or if symName is empty
  ent_add(ent);
  cattran(ent.Matrix, pt.x, pt.y, pt.z); // translate the symbol to point pt
  // perform additional matrix operations if necessary for rotation, scale, etc.
  ent_update(ent);
  ent_draw(ent, drmode_white);
end;


HTH
#32331 by devinder
Mon Jan 28, 2008 3:56 pm
You can update matrix before adding entity to the database too, to avoid the need of calling ent_update and possibly saving one Undo Recording internally for ent_update.

shovavnik wrote:
Code: Select allif sym_read(symPath, symName, sym) = 0 then // symPath should not contain the file extension
begin
  ent_init(ent, entsym);
  ent.symname := symName; // use symPath if you want to or if symName is empty
  cattran(ent.Matrix, pt.x, pt.y, pt.z); // translate the symbol to point pt
  ent_add(ent);
  ent_draw(ent, drmode_white);
end;


HTH

Who is online

Users browsing this forum: No registered users and 17 guests

About DataCAD Forum

The DataCAD Forum is a FREE online community we provide to enhance your experience with DataCAD.

We hope you'll visit often to get answers, share ideas, and interact with other DataCAD users around the world.

DataCAD

Software for Architects Since 1984