Jump to content

Bind X-Coordinate to Record Format


Recommended Posts

Is there a non-script way to bind a record format to its' symbol's x-coordinate?

I want to display the x & y coordinates on a symbol where x & y point to the point of symbol insertion. Is there a way to this with worksheets (without much scripting) ?

Please see the attached the file; as you would notice I can't assign the record format to the x-coordinate, it returns false naturally... is there a way to do this?

Follow-up Question:

Is there a way to turn the X-Coordinate called on a database header in to dimensional value? (e.g; 7'-6 3/8" prints 7.531 on the worksheet; how to keep it as 7'-6 3/8" ?)

Thanks in advance.

Link to comment

First the easy part:

To get the cells to show as dimesions, format the cells as Dimension rather than General. Select the header row (or the entire column) go to the Format menu of the worksheet, choose Cells, Select the Number tab and then choose Dimension.

As to your second question, without scripting, no there is not way to do what you are trying to do.

You could create a Plug-In Object that would automatically use the location of the object for the X and Y locations.

Or you could run a script that would populate the record with the right data.

The first is more work as it has to be set up to handle all of the formatting you might want.

The second is only accurate immediately after you run the script. You would have to rerun the script every time you move a symbol.

Sorry.

Link to comment

Hi,

I think I got a plug-in that does what you require. It is part of a compilation I'm selling (sorry it ain't free, but then again the bundle is a great deal.)

http://hippocode.com/reference-point

Summary of the plug-in:

- You can choose any symbol to display.

- It will keep track of it's location(3D) which can be retrieved in reports and made visible on the screen trough another label symbol. Different record fields can be used to show the coordinates in that label symbol.

- The position of the coordinates is controlled by a control point.

- The object will copy the referenced symbol records on the object and will pass the variables on to the symbol. This way you can still control the symbol's record fields.

Link to comment

Hey Guys,

This is what I have for now, as a little manual script application. I'm not familiar with VectorScript so I'm getting errors (expected DYNARRAY of CHARS) and also, I don't know how to convert the real value turned by the XCoordinate to my desired format display, which is something like this;

( ##'-## ##/##")

But here is my script, I would love if somebody experienced in Vectorscript take a look at it.

Procedure Set_CoordinateField;
const	MyRec = 'COORDINATE';
	My_Xcoordinate = 'x coordinate';
	My_Ycoordinate = 'y coordinate';

Procedure MyProc(H2:Handle);
Begin
	SetRField(H2,MyRec,My_Xcoordinate,XCoordinate(R IN [MyRec]);
	SetRField(H2,MyRec,My_Ycoordinate,YCoordinate(R IN [MyRec]);
End;

Begin
ForEachObject(MyProc,((R IN [MyRec])));
End;

Run(Set_CoordinateField);

Edited by sle7en7
Link to comment

As far are I know there is not a tool to convert python to VS.

BUT, Vectorworks now supports Python scripting as well as VectorScript. Basically all of the VS calls can be made from Python by prepending them with VS.

Take a look at the online function reference at for example Python (and VS) code for most of the functions and procedures.

That being said, I am a VS guy, and have done almost zero Python coding.

Link to comment
Hey Guys,

This is what I have for now, as a little manual script application. I'm not familiar with VectorScript so I'm getting errors (expected DYNARRAY of CHARS) and also, I don't know how to convert the real value turned by the XCoordinate to my desired format display, which is something like this;

( ##'-## ##/##")

But here is my script, I would love if somebody experienced in Vectorscript take a look at it.

What you don't say is the requirements for using the script.

1. You must have a record in the file named "COORDINATE" in the file.

2. That record must have fields named "x coodinate" and "y coodinate"

3. The record must be attached to each object to want to locate prior to running the script.

4. All the script does is move the X and Y coordinates (insertion point) of the object into the COORDINATE record. Anything else you do with them from there is separate.

So, you formatting of the output of the data will depend on how you are using the record data. A good first step would be to edit the Coordinate format and make sure the x and y fields are defined as Numbers and formatted as Dimensions (click the Format button). The format of the display should then automatically flow from the Unit settings of the file.

If you are using a worksheet make sure the column (or cells) displaying the data is/are also formatted as Dimension.

Two other hints:

1. For a script with this few lines, I would hard code the Record and Field names rather than assigned them to variables. Yes if you have to edit the names you have to change them in two places rather than one, but to me it makes the script easier to understand.

2. I would try to make Record and Field names a single string without the spaces. i.e. x_coordinate rather than x coordinate. There are places where a single "word" can be used without the surrounding quotes necessary when you have spaces.

Here is a script that actually runs. There is no default fields for X and Y in MyRec, so it can't get the data. You have to use some sort of command to query the object and get that data and store it not the record. In this case I chose GetSymLoc, but depending on the object type you have that might or might not get you the point you are interested in.

Procedure Set_CoordinateField;
const	MyRec = 'COORDINATE';
	My_Xcoordinate = 'x coordinate';
	My_Ycoordinate = 'y coordinate';

var		Item_X, Item_Y:Real;

Procedure MyProc(H2:Handle);
Begin
	GetSymLoc(H2,Item_X,Item_Y);
	SetRField(H2,MyRec,My_Xcoordinate,Num2StrF(Item_X));
	SetRField(H2,MyRec,My_Ycoordinate,Num2StrF(Item_Y));
End;

Begin
ForEachObject(MyProc,((R IN [MyRec])));
End;

Run(Set_CoordinateField);

Edited by Pat Stanford
Link to comment

If you want to spend the time creating it why not creating it as a plug-in. It's not that much more work and you will be sure of the data being correct at all times.

Now you depend on the user running the script on each change, something that is easily forgotten...

Edited by hippothamus
Link to comment

Pat - thanks so much again. Since I'm not too familiar with VS or Pascal I'm getting stuck on basic stuff such as this. And on the contrary I started learning Python recently so if I have the time to develop something it would be in Python more often.

Hippo - you're right, might as well turn it into a plug-in but that's gonna take a bit more time which I don't have right now. And if I decide to build a plug-in, I would try to do something more user-friendly and general purpose I guess, rather than just a menu command, like something which asks for input and pops up windows and what not. All in good time :)

Anyhow thanks guys, I will let you know if I improve upon these.

Link to comment
Is there a non-script way to bind a record format to its' symbol's x-coordinate?

I want to display the x & y coordinates on a symbol where x & y point to the point of symbol insertion. Is there a way to this with worksheets (without much scripting) ?

Not sure if it is available in Vectorworks Architect, but in Vectorworks Landscape you have the stake object tool which allows you to set it in such a way that it shows the X/Y coordinates when putting it into the drawing and it updates the coordinates when you move the object. It would look very similar to the symbol you created in your drawing.

If that tool is available in Architect you could use that either on its own or try to make it part of your symbol and see if it would would work too if it is part of a symbol.

Link to comment
  • Vectorworks, Inc Employee

It should be in Architect as well as of 2015, actually because of something similar to this. Support pushed for them to include it in Architect as well as Landmark (used to be Landmark and Designer only) and either in 2014 or 2015 it was done.

Link to comment

Yep it is in VW 2015. but as you guys would suspect architects' wishes never end... For example I can't get the coordinate to show up and write some description with it... Or if I turn the stake into a symbol with a record attached, it defines another origin within the symbol frame. So my boss wants to display our custom symbol "stake" with a definition (e.g. Column Corner (C.C. for short)) and a coordinate dimension depending on the orientation of the symbol. So if the symbol is 0° or -180° rotated then, we want to see the XCoordinate,

if it is 90° or -90° rotated then, we want to see the YCoordinate. I'm trying to write some conditional code to implement this to hundreds of coordinates on 10 floor plans but I'm failing somewhere, I think if you took a look at the code you might spot the small things I'm missing to get it right. It compiles but, only the YCoordinate gets implemented, or the YCoordinate always get implemented to put it another way. Anyway here is the code (credits to Pat of course):

Procedure Set_CoordinateField;

const	MyRec = 'Column Line';
	MyField = 'Number';

var		Item_X, Item_Y:Real;

Procedure MyProc(H2:Handle);
Begin
	IF (GetSymRot(H2) = 90.0) OR (GetSymRot(H2) = -90.0) THEN
		GetSymLoc(H2,Item_X,Item_Y);
		SetRField(H2,MyRec,MyField,Num2StrF(Item_X));
	IF (GetSymRot(H2) = 0.0) OR (GetSymRot(H2) = -180.0) THEN
		GetSymLoc(H2,Item_X,Item_Y);
		SetRField(H2,MyRec,MyField,Num2StrF(Item_Y));
End;

Begin
ForEachObject(MyProc,((R IN [MyRec])));
End;

Run(Set_CoordinateField);

Edited by sle7en7
Link to comment

Can you post a stripped down file with an instance of the symbol and the record format and the script already in it? It will make it much easier to make sure we are setting the symbol and record EXACTLY the same as you are.

BUT, based on a quick read, you are not nesting your IF statements properly. Try this instead:

	IF (GetSymRot(H2) = 90.0) OR (GetSymRot(H2) = -90.0) THEN
                   Begin
		GetSymLoc(H2,Item_X,Item_Y);
		SetRField(H2,MyRec,MyField,Num2StrF(Item_X));
                   end;
	IF (GetSymRot(H2) = 0.0) OR (GetSymRot(H2) = -180.0) THEN
	   Begin
               	GetSymLoc(H2,Item_X,Item_Y);
		SetRField(H2,MyRec,MyField,Num2StrF(Item_Y));
                  End;

The way you have it written the GetSymLoc is part of the If statement and the SetRField is just another line of code that is always run.

Another possibility would be to pull the GetSymLoc up above both Ifs (you only need it once), and then the SetRField would be part of each If.

Link to comment

Ok I got it to work, you were right Pat, embedding IF statements... I'll get the hang of it someday.. those `begin`s and `end`s are driving me crazy...

But this is what I have in VS (don't mind the naming conventions they are company used names, column line is the record and Number is the field where the coordinate is written)


Procedure Set_CoordinateField;

const	MyRec = 'Column Line';
	MyField = 'Number';

var		Item_X, Item_Y:Real;

Procedure MyProc(H2:Handle);
Begin
	IF (Abs(GetSymRot(H2)) = 90.0) THEN
		Begin
			GetSymLoc(H2,Item_X,Item_Y);
			SetRField(H2,MyRec,MyField,Num2StrF(Item_X));
		End;
	IF (Abs(GetSymRot(H2)) = 0.0) OR (Abs(GetSymRot(H2)) = 180.0) THEN
		Begin;
			GetSymLoc(H2,Item_X,Item_Y);
			SetRField(H2,MyRec,MyField,Num2StrF(Item_Y));
		End;
End;

Begin
ForEachObject(MyProc,((R IN [MyRec])));
End;

Run(Set_CoordinateField);

Then I tried to write the Python version, but failure... I don't get HANDLE's ...


def Set_CoordinateField(MyRec, MyField):

MyRec = 'Column Line'
MyField = 'Number'
Item_X = 0
Item_Y = 0
H2 = HANDLE

if (abs(vs.GetSymRot(H2)) == 90.0):
	vs.GetSymLoc(H2,Item_X,Item_Y)
	vs.SetRField(H2,MyRec,MyField,vs.Num2StrF(Item_X))
elif (abs(GetSymRot(H2)) == 0.0) or (abs(GetSymRot(H2)) == 180.0):
	vs.GetSymLoc(H2,Item_X,Item_Y)
	vs.SetRField(H2,MyRec,MyField,vs.Num2StrF(Item_Y))

vs.ForEachObject(Set_CoordinateField,((R == [MyRec])))

Also the file is attached Pat.

Link to comment

This seems to work in Python. But I have done VERY LITTLE (Extremely Little) in Python.

import vs;

def Set_CoordinateField(MyHandle):

MyRec = 'COORDINATE'
MyXfield = 'X Coordinate'
MyYfield = 'Y Coordinate'

MyRot=vs.GetSymRot(MyHandle)
PtXY=vs.GetSymLoc(MyHandle)
if (abs(MyRot) == 90.0):	
	vs.SetRField(MyHandle,MyRec,MyXfield,vs.Num2StrF(PtXY[0]))
if (abs(MyRot) == 0.0 or abs(MyRot) == 180.0):
	vs.SetRField(MyHandle,MyRec,MyYfield,vs.Num2StrF(PtXY[1]))


vs.ForEachObject(Set_CoordinateField,'((R IN [COORDINATE]))')

Link to comment

Hey Pat,

Say if I wanted to do Set_CoordinateField procedure for only the selected objects. What line of code do I need for that? I'm giving this (see code) a try but to no avail, it only does it for the first selected object obviously.

Would a function like ForEachObjectInList or NumSelectedObjects come into play? If so how can I use them?

Thanks a lot again

Procedure Set_CoordinateField;

const	MyRec = 'Column Line';
	MyField = 'Number';

var		Item_X, Item_Y:Real;

Procedure MyProc(H2:Handle);

Begin;
	H2 := FSActLayer;  
	IF (Abs(GetSymRot(H2)) = 90.0) THEN
		Begin;
			GetSymLoc(H2,Item_X,Item_Y);
			SetRField(H2,MyRec,MyField,Num2StrF(Item_X));
		End;
	IF (Abs(GetSymRot(H2)) = 0.0) OR (Abs(GetSymRot(H2)) = 180.0) THEN
		Begin;
			GetSymLoc(H2,Item_X,Item_Y);
			SetRField(H2,MyRec,MyField,Num2StrF(Item_Y));
		End;
End;

Begin
ForEachObject(MyProc,((R IN [MyRec])));
End;

Run(Set_CoordinateField);

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...