twk Posted February 12, 2020 Share Posted February 12, 2020 Greetings all, I have a worksheet that shows all windows/doors in the drawing. I was trying to grab handles to these objects from the worksheet database, but could not find any sdk functions to call it. So I added an extra column that calls the GlobalID from the IFCDoor/IFCWindow, and noticed that these are as expected all unique ids. My question is, does this ID, remain throughout the life of the drawing document? as opposed to handles? Could I then use these ID's to uniquely identify these in a script database somehow? Cheers, Tui Quote Link to comment
Pat Stanford Posted February 12, 2020 Share Posted February 12, 2020 I have no idea if the IFC fields are unique or not, but depending on what you are doing I don't know that I would trust them as it is possible for something else to modify them. If you need a unique identifier, VectorScript (so I am sure the SDK does also) has a UUID function. Store this in one of the user fields, or create a custom hidden record and store it there. Alternatively, if you don't need to have it unique for life, but just for now, you could create a very small Worksheet Script that would return the Handle to the object as a LongInt (or String) you could then grab the data from that cell and convert back to a handle. Every time the worksheet runs the handle column would be updated. Quote Link to comment
twk Posted February 12, 2020 Author Share Posted February 12, 2020 Interesting. How do you convert a handle representation back into a handle? Quote Link to comment
JBenghiat Posted February 12, 2020 Share Posted February 12, 2020 A few, possibly separate questions. Are you specifically trying to access the objects that a user has selected for a worksheet database? If you’re just looking to access the underlying data, you can do this directly, without dealing with the worksheet. If you’re trying to access the report criteria, try retrieving column 0 of the database row. You mention the SDK — do you mean the actual SDK, or the Python API? A few versions ago, Vectorworks started adding a UUID to every object. This doesn’t seem to be on the developer wiki, but GetObjectByUuid() and GetObjectUuid() are valid calls. As this ID is core level, it will be a lot more robust than a plug-in code managed ID. 2 Quote Link to comment
MullinRJ Posted February 12, 2020 Share Posted February 12, 2020 14 hours ago, Pat Stanford said: ... return the Handle to the object as a LongInt (or String) you could then grab the data from that cell and convert back to a handle. I wish this were possible. To the best of my knowledge you can only look at a handle value, but you cannot cast the value back to a handle. On a similar track, since the VW App went to 64 bit, I've seen some handle values (not all) that exceed the Longint range. There is no 64-bit integer type in VS that would accommodate really large integers. @Pat Stanford if I'm wrong and you do know of a way to convert values back to a handle, would you mind sharing. I could use this. Thanks, Raymond Quote Link to comment
Pat Stanford Posted February 12, 2020 Share Posted February 12, 2020 @MullinRJ No Raymond, I think you are correct. I don't know if I am mistaken or if the last time I played with this is so long ago that things have changed. I am currently playing with a possible Python solution that would grab the handle as Text, Convert it to a Python integer, and then store that back to a Handle variable. But my Python is so weak as to be really painful. I think @twk is much more of a Python expert, so perhaps he can take my outline below and make it work. 😞 Procedure Test; Var H1,H2: Handle; S1,S2: String; L1: LongInt; Begin H1:=FSActLayer; S1:=Concat(H1); { DselectAll; AlrtDialog(Concat(S1)); } PythonBeginContext; PythonExecute('S1 = vs.GetVSVar("S1")'); {PythonExecute('L2 = int(S1)'); PythonExecute('vs.SetVSVar("H2", "L2")');} PythonEndContext; L1:=Str2Num(Copy(S1,1,10))*10; AlrtDialog(Concat(S1,' - ',L1,' - ',H2)); End; Run(Test); Procedure Test; Var H1,H2: Handle; S1,S2: String; L1: LongInt; Begin H1:=FSActLayer; S1:=Concat(H1); { DselectAll; AlrtDialog(Concat(S1)); } PythonBeginContext; PythonExecute('S1 = vs.GetVSVar("S1")'); {PythonExecute('L2 = int(S1)'); PythonExecute('vs.SetVSVar("H2", "L2")');} PythonEndContext; L1:=Str2Num(Copy(S1,1,10))*10; AlrtDialog(Concat(S1,' - ',L1,' - ',H2)); End; Run(Test); 1 Quote Link to comment
Pat Stanford Posted February 12, 2020 Share Posted February 12, 2020 I responded to Raymond before I digested Joshua's response. Probably a much better way to go. 1 Quote Link to comment
twk Posted February 12, 2020 Author Share Posted February 12, 2020 3 hours ago, JBenghiat said: A few versions ago, Vectorworks started adding a UUID to every object. This doesn’t seem to be on the developer wiki, but GetObjectByUuid() and GetObjectUuid() are valid calls. As this ID is core level, it will be a lot more robust than a plug-in code managed ID. This will actually do it. Thanks a million guys. How do you find these @JBenghiat! On that note, would you know if there is a function call for this for worksheets? I've resorted to creating a script to pull that info into the worksheet, and can then cylce through the worksheet to grab the UUID and the object on the drawing. Would be perfect if I could skip the script part, as everytime the worksheet resets it asks me to execute the script. In any case, thanks again. Quote Link to comment
Pat Stanford Posted February 12, 2020 Share Posted February 12, 2020 You can just click the Always Allow button on the script and it will stop asking. 1 Quote Link to comment
MullinRJ Posted February 12, 2020 Share Posted February 12, 2020 @twk , The Always Execute Scripts button will reset when VW re-launches, so you are not giving up your ability to block script execution forever. That was my biggest concern when I first ran into this dialog. Was afraid to press the button. I don't know if this is documented, I found it out by trial and error and I was very pleased to see the function resets at the end of a VW session. I feared it would open the door for scripts to execute forever. On a tangential note: it would be extremely helpful for this dialog to have a Help window to explain the scope of each button's functionality. HTH, Raymond Quote Link to comment
JBenghiat Posted February 12, 2020 Share Posted February 12, 2020 @twk I use Debug List View from the Debug menu quite a bit. vs.EnableDebugMenu() This reveals the data attached to every object, which includes the UUID. I believe the UUID was necessitated by project sharing. The Debug menu also provides a viewer for the VS reference that comes in the SDK. It is autogenerated, so fairly definitive. I'm unclear whether you are using the worksheet to process data or whether the worksheet is the end goal. If the former and you're creating the script for your own use, you can just use ForEachObject() with the criteria you are using for the worksheet report, and GetRField() to retrieve any data without dealing with the worksheet. If you're starting with a worksheet, as I guessed, using vs.GetWSCellFormulaN() on column 0 will return "=DATABASE({criteria})," which then lets you extract the criteria and pass it to ForEachObject(), eliminating the need to use the worksheet to step through objects. @Pat Stanford and @MullinRJ, I would caution against any routines that try to store a handle. The handle is really just a pointer to a memory block — as objects get removed and added, the same handle can point to different objects or be null. If you know you're not creating any objects (including containers), you may be ok, but it's dangerous. 2 Quote Link to comment
MullinRJ Posted February 12, 2020 Share Posted February 12, 2020 Thanks, Josh. @JBenghiat Advice heeded. I've wanted to do this in the past only for investigative purposes, but never for anything practical. On one occasion (only one) I stored the string values of handles so I could sort them and do a binary search of the Symbol Library. It worked perfectly. Thanks for the warning. Raymond Quote Link to comment
twk Posted February 12, 2020 Author Share Posted February 12, 2020 (edited) 28 minutes ago, JBenghiat said: I'm unclear whether you are using the worksheet to process data or whether the worksheet is the end goal. If the former and you're creating the script for your own use, you can just use ForEachObject() with the criteria you are using for the worksheet report, and GetRField() to retrieve any data without dealing with the worksheet. The aim is to have the worksheet as a sort of staging area for the filtering and sorting of windows/doors. -- (I'm creating an automatic window/door elevation tool for schematic scheduling) Once the filtering was set I found there was no way for me to sift through the displayed subrow data and grab the object handles to create the elevation on the drawing. Now I can! I did use the ForEachObject() on the db criteria, however any sorting that happened on the worksheet was difficult to replicate through my script. I'd rather have the sorting/grouping all done on the worksheet, and then have the graphical display just pull from the UUID on the worksheet. Edited February 12, 2020 by twk 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.