sle7en7 Posted July 1, 2015 Share Posted July 1, 2015 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. Quote Link to comment
Pat Stanford Posted July 3, 2015 Share Posted July 3, 2015 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. Quote Link to comment
Hippocode Posted July 3, 2015 Share Posted July 3, 2015 (edited) Hi, I've got a plug-in that does exactly what you asked for. I'm away from home this week so I'll repost here on sunday with more info. Edited July 3, 2015 by hippothamus Quote Link to comment
Benjamin Weill Posted July 4, 2015 Share Posted July 4, 2015 Hi, I've got a plug-in that does exactly what you asked for. I'm away from home this week so I'll repost here on sunday with more info. That would be fantastic! I posted something similar to this a while ago, but looking to attach the "y" coordinate. https://techboard.vectorworks.net/ubbthreads.php?ubb=showflat&Main=42251&Number=210324#Post210324 THANKS!! Quote Link to comment
sle7en7 Posted July 6, 2015 Author Share Posted July 6, 2015 -Hippo, That would be great if you can share! Thanks. -Pat, The plug-in would run in a loop in the background and would not need maintaining as much as a script? Quote Link to comment
Pat Stanford Posted July 6, 2015 Share Posted July 6, 2015 Plug-ins have the ability to update when they are moved or rotated (as well as other events). So it is not so much running in a loop as being able to update when it is moved. The script would have to be manually invoked after a move for the data to be updated. Quote Link to comment
sle7en7 Posted July 6, 2015 Author Share Posted July 6, 2015 Ok Pat, got it, thanks a lot. Quote Link to comment
Hippocode Posted July 6, 2015 Share Posted July 6, 2015 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. Quote Link to comment
sle7en7 Posted July 6, 2015 Author Share Posted July 6, 2015 (edited) 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 July 6, 2015 by sle7en7 Quote Link to comment
sle7en7 Posted July 6, 2015 Author Share Posted July 6, 2015 Also, is there a tool which converts Python to Vectorscript? That would come in really handy for me Quote Link to comment
Pat Stanford Posted July 6, 2015 Share Posted July 6, 2015 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. Quote Link to comment
Pat Stanford Posted July 6, 2015 Share Posted July 6, 2015 (edited) 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 July 6, 2015 by Pat Stanford Quote Link to comment
Pat Stanford Posted July 6, 2015 Share Posted July 6, 2015 Other commands you might want to consider for getting the point of interest (depending on the objects you are working with) are GetBBox [Get Bounding Box] and Get2DPt [Get 2D Point]. Quote Link to comment
Hippocode Posted July 7, 2015 Share Posted July 7, 2015 (edited) 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 July 7, 2015 by hippothamus Quote Link to comment
sle7en7 Posted July 7, 2015 Author Share Posted July 7, 2015 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. Quote Link to comment
Art V Posted July 7, 2015 Share Posted July 7, 2015 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. Quote Link to comment
sle7en7 Posted July 7, 2015 Author Share Posted July 7, 2015 Wow, that looks awfully applicable to our situation, boy I feel smart now The joys of being oblivion to given tools... thanks a lot Art V. Quote Link to comment
Vectorworks, Inc Employee PVA - Admin Posted July 7, 2015 Vectorworks, Inc Employee Share Posted July 7, 2015 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. Quote Link to comment
sle7en7 Posted July 8, 2015 Author Share Posted July 8, 2015 (edited) 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 July 8, 2015 by sle7en7 Quote Link to comment
Pat Stanford Posted July 8, 2015 Share Posted July 8, 2015 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. Quote Link to comment
sle7en7 Posted July 9, 2015 Author Share Posted July 9, 2015 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. Quote Link to comment
Pat Stanford Posted July 9, 2015 Share Posted July 9, 2015 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]))') Quote Link to comment
sle7en7 Posted July 10, 2015 Author Share Posted July 10, 2015 So have I, but thanks Pat it is working at least, I just wanted to put it out there... Quote Link to comment
sle7en7 Posted July 14, 2015 Author Share Posted July 14, 2015 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); Quote Link to comment
Pat Stanford Posted July 14, 2015 Share Posted July 14, 2015 Option 1. Get rid of the H2 :=FSActLayer. Change the criteria to be (((R IN [MyRec']) & (SEL=TRUE))) Option 2. Begin H2:=FSActLayer; While H2 <> Nil do Begin Put the If statement stuff here; H2:=NextSObj(H2); End; End; Run() Quote Link to comment
Recommended Posts
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.