grant_PD Posted December 6, 2023 Share Posted December 6, 2023 Starting to work with other people on the same file, and noticing that things like crop objects, drawing labels, callouts etc, are ending up on a variety of different classes since some user are more cavalier about classing objects than others. How can I make the work flow for these objects idiot proof? I can create a class for each object, but I can't enforce that class usage...can I? Quote Link to comment
Kevin Allen Posted December 6, 2023 Share Posted December 6, 2023 there oughta be a way, but I don't think there is. This has been to me and others, a matter of contention for many, many years. I want VWX to know that when I Insert a camera object (for example) it should go into the camera object class. It does not. There is a way, in the Plug In Manager, to edit some PIOs and force classing, but that configuration is lost when there is an application update. 1 Quote Link to comment
grant_PD Posted December 6, 2023 Author Share Posted December 6, 2023 @Kevin Allen yes some sort of tool mapping would be ideal. Years ago I recall someone telling me they put all drawing objects into symbols that exploded into groups into a resource folder, so they would never use the tool button for those objects again. Sounds like an idiot proof method, but I don't want to keep looking over to the resource folder everytime I want to place a callout. Quote Link to comment
Kevin Allen Posted December 6, 2023 Share Posted December 6, 2023 I had an interesting panel discussion years ago at a Design Summit with several other designers. We all had different methodologies and we all wanted a conversion methods Quote Link to comment
line-weight Posted December 6, 2023 Share Posted December 6, 2023 There's a column in the table that I made as part of this exercise that's about whether the class can be set... 2 Quote Link to comment
grant_PD Posted December 7, 2023 Author Share Posted December 7, 2023 @line-weight what a labor of love and frustration! The custom modification tool does not work (I've run it thru tech support, they acknowledge the bug) on all items. Custom tool command does.....not really create custom tools with these objects. I have a custom script that forces the class of a few of these items. That seems to be a workable solution. Does anyone else have any workflow ideas? Quote Link to comment
Pat Stanford Posted December 7, 2023 Share Posted December 7, 2023 On 12/6/2023 at 9:16 AM, grant_PD said: How can I make the work flow for these objects idiot proof? I can create a class for each object, but I can't enforce that class usage...can I? Your best option is probably Pink Slips for those who don't comply. 😉 1 Quote Link to comment
grant_PD Posted December 7, 2023 Author Share Posted December 7, 2023 @Pat Stanford But I need to get them to go through 80 pages of drafting first and change all of the callouts and drawing labels to the correct class! 1 Quote Link to comment
Pat Stanford Posted December 7, 2023 Share Posted December 7, 2023 Seriously, there are ways to help automate classing (I am not enough of an expert to be able to offer the best ways as I work almost exclusively solo), but it is going to be very hard to "force" everyone to do the right thing. When they feel rushed they are going to do what they think is fastest, regardless of the issues that causes down stream. I think @michaelk has a bunch of worksheets that he uses to audit drawings and show things that are in the wrong classes. Maybe something like that would help for you? 1 Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 I have a bunch of old worksheets. But - of course - @Jesse Cogswell has a really cool menu command to do exactly this. I used it all the time now 🙂. 3 Quote Link to comment
Rolan Castaneda Posted December 7, 2023 Share Posted December 7, 2023 4 minutes ago, Pat Stanford said: When they feel rushed they are going to do what they think is fastest, regardless of the issues that causes down stream. That hits the nail on the head. I deal with this constantly. Not everyone was trained with the correct "drafting ethics", and for guys like us who were, it can be very frustrating. The only way to go is to set up drafting standards and get everyone trained on those standards. Get the Principal/CEO in involved and on board with enforcing drafting standards. 1 Quote Link to comment
grant_PD Posted December 7, 2023 Author Share Posted December 7, 2023 @Rolan Castaneda I am fully onboard with your sentiment. I'm that type of person where even if I KNOW that the miss-classed object is not going to affect the final outcome, I feel compelled to change it. That being said, I am also wondering why in this day and age vw cannot allow us to map objects to classes as we see fit? Is that what auto-classing does in the architect version? Quote Link to comment
grant_PD Posted December 7, 2023 Author Share Posted December 7, 2023 @michaelkI looked at that thread, I'm not seeing how this helps? What does that worksheet do exactly? Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 I was pointing out the menu commend that Jesse wrote. For example. Using Jesse's menu command, here's a list of all the objects - including objects inside wall comments and symbol definitions! - in the drawing I'm working on now that are in the Demo class. You can go to an object straight from the list or create a worksheet. I'm not as good as Jesse at creating cool dialog boxes. So in the past I've just made my own worksheets and changed the criteria manually to discover how many walls got put into the class Site-DTM-Modifier. 1 Quote Link to comment
Jesse Cogswell Posted December 7, 2023 Share Posted December 7, 2023 I deal with this a lot doing venue drawings with fairly complex class structures. Often these venues are in educational institutions where the students may not have a firm grasp of classes vs. layers, so I do as much as I can to "idiot-proof" the drawings before handing them over. This is pretty easy to do with symbols, since you can set the Assign to Class attribute in the Symbol Options, but that doesn't work with plug-in objects. I think it would be a grand idea for there to be a way to setup default class mapping per PIO, but it would most certainly have to be drawing specific since you might not have the classes in your current drawing. Though I could also see a world in which you could set up the default class attributes and have Vectorworks build the class for you if it doesn't currently exist in the drawing. This would have to be a something that VW adds in the long term, but I wouldn't hold your breath for it. In the short term, it wouldn't be too much work to script up a dialog box that would populate a list of PIO types found in the drawing and let you map a class to them. Then, the script would scour the drawing and change all existing PIOs to their mapped class. I could write such a plug-in pretty quickly, so if I wrap up the drawing I'm currently working on, I might be able to put something together for you later this afternoon. 2 2 Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 I was just having a conversation about this recently. I wrote this script for someone else. It creates/updates classes AND their descriptions in a VW drawing. If you hover over a class in the Nav Palette and the class has a description, that description will pop up. So you can have a description of a class that says "This class is for plumbing fixtures only. NOT windows. NOT lobby furniture!" Run this script and it will create classes and create/update their descriptions. It will NOT delete existing classes. I think it will NOT make anyone check the descriptions, but you will know that you tried. PS. I've always wanted an option to have the screen flash red whenever creating objects while NOT in the None class. And an option to define classes, like the None class, that the Visibility Tool Ignores when the mode is set to invisible. Create Classes From Worksheet v2024.vwx 1 Quote Link to comment
trevorgooch Posted December 7, 2023 Share Posted December 7, 2023 @michaelk "I have a bunch of old worksheets" Probably shortly after I found all of your posts about worksheets, and scripts to improve formatting, I started adding three columns in almost every worksheet: Symbol/type, layer, and class. Always in a kinda grey as a house keeping note. "=FIRSTNONEMPTY(SYMBOLNAME, OBJECTTYPENAME)" for the symbol list - all in a way to reveal where we went wrong! Thanks for the script! This will save some time for sure! 1 Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 @Jesse Cogswell btw, in 2024 I'm getting a error when running this menu command. It's just a warning on Line 67, 68, 69 where you have GOTO 99. The error is Warning: GOTO into a FOR or CASE structure is usually an error. It still runs and works as expected. Maybe it only displays that when running in developer mode? Quote Link to comment
Pat Stanford Posted December 7, 2023 Share Posted December 7, 2023 Yes, that is a Warning and should show in Developer mode only. Quote Link to comment
Jesse Cogswell Posted December 7, 2023 Share Posted December 7, 2023 @michaelk I think I told you when we met up last spring that I use GOTO statements often in my code as quick escape sequences since Pascal doesn't have a more traditional BREAK command (happy to be wrong about this, of course). It's used often in this particular script since the script has to traverse every single object in every single Symbol, Group, and Wall searching for objects of the target class. It uses the standard WHILE loop using FInGroup and NextObj, but if it finds an object using the class, it doesn't need to keep searching that object, so I use a GOTO statement to exit the WHILE loop. It doesn't save a huge amount of time or computational power, but if you run the command on a huge drawing with complicated symbols, it will be noticeable. However, that won't throw the error you're seeing since I'm not using a FOR or CASE structure in that example. In this script, I am using a GOTO in each. For the FOR loop, I'm using it to return the object type constant of a given parent object type name. I have an array of strings that is indexed by the object type constant selectors so that I can populate the Object Type and Parent Type columns of the dialog box. When you click on the Go to Selected button, it feeds the string found in the Parent Type column into a function that will then spit out the object type constant used in a CASE statement to determine how to get to the chosen object. That function is really simple and looks like this: FUNCTION GetObjectTypeIndex(objName:STRING) : INTEGER; {Searches object types for matching string and returns Object Number} LABEL 99; {Escape Sequence} VAR i:INTEGER; BEGIN IF(objName=sMiscResourceManager) THEN BEGIN i:=999; GOTO 99; END; FOR i:=1 TO kNumTypes DO BEGIN IF(objName=objTypes[i]) THEN GOTO 99; END; 99: GetObjectTypeIndex:=i; END; If it gets fed in "Resource Manager" as the parent, it will return 999 since the Resource Manager doesn't have an object type. I don't know for the life of me why I chose to use the GOTO to skip the FOR loop since I could have just put the FOR loop into the ELSE of the IF, but I did and it works, so I'm sticking by it. In the FOR loop, once it finds the match it doesn't need to complete the loop so instead it uses GOTO 99 to exit out. As for using a GOTO in a CASE structure, I wrote in a way to rebuild the list browser anytime you change target class or any of the Search options. The dialog handler is a big event CASE structure, and I have a LABEL in the part of the SetupDialogC event that adds and fills out the list browser. Anytime the user changes the class or the Search option, the list browser data is wiped out and a GOTO statements returns to that LABEL and regenerates the list browser. It's the best way I've found to be able to quickly regen the list browser without copying and pasting the generation code in each event that would require a rebuild. As penance for @grant_PD for hijacking their thread with nonsense, I'll get to writing up that command now. 4 Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 @Jesse Cogswell I think the hijack is my fault. I like your GOTO method! Quote Link to comment
Jesse Cogswell Posted December 7, 2023 Share Posted December 7, 2023 All done. Here you go, lightly tested in VW2023 and VW2024: @michaelk I noticed in your screenshot that the two columns UUID and Parent UUID are visible. These are supposed to be hidden (have a column width of 0), did you expand the columns or is that how it presents on Mac? I'm asking because this plug-in will also use a hidden column to conceal the record name for each plug-in object so that it instead presents the localized name. If the Record Name column is visible when you run this, let me know and I'll change up how the programming works a little bit. To install this plug-in, follow the steps below: Download the attached Reset Plug-in Obj Classes.vsm file Open your Vectorworks User File in a file explorer / Finder window Easiest way to do this to go to your Vectorworks Preferences, select the User Folder tab, and click on the Explore (Windows) or Open in Finder (Mac) button Open the Plug-ins folder Place the downloaded Reset Plug-in Obj Classes.vsm file into the Plug-ins folder of your User Folder Restart Vectorworks Put the new plug-in into your workspace Go to Tools - Workspaces - Edit Current Workspace Select the Menus tab In the box on the left, find and expand the category JNC In the box on the right, find a menu to place the new command in, such as Edit or Modify or Tools Click and drag the Reset Plug-in Obj Classes command from the box on the left to the target menu in the box on the right Click OK I tested this and it seemed to work correctly. As a quick side note, as part of the process it will reset the objects after changing their class, so if you have objects that take a while to reset or a lot of objects will be affected by this, the operation may take a while to complete. Just a heads up. In my testing it was pretty fast, however. Reset Plug-in Obj Classes.vsm Quote Link to comment
Jesse Cogswell Posted December 7, 2023 Share Posted December 7, 2023 36 minutes ago, michaelk said: I like your GOTO method! You would love my method filtering duplicates when building dynamic arrays. I use a FOR loop to go through the existing array with the code to add a new item to the array placed after the FOR loop and a LABEL pointer set at the very end. Inside the FOR loop, if a matching item is found, it uses a GOTO statement to bypass the code adding to the array. If it reaches the end of the loop without finding a match, it is allowed to get to the addition code. Here's the code in this plug-in that builds the array of object types using a ForEachObject(BuildTypeArray,(INSYMBOL & INVIEWPORT & (T=PLUGINOBJECT))) call: PROCEDURE BuildTypeArray(h:HANDLE); {ForEachObject callback that builds array of object types} LABEL 99; {Escape} VAR PIOName,locName:STRING; i:INTEGER; BSB:BOOLEAN; BEGIN PIOName:=GetName(GetRecord(h,NumRecords(h))); FOR i:=1 TO numPIOTypes DO BEGIN IF(PIOName = PIOTypes[i].name) THEN BEGIN PIOTypes[i].num:=PIOTypes[i].num + 1; GOTO 99; END; END; numPIOTypes:=numPIOTypes + 1; ALLOCATE PIOTypes[1..numPIOTypes]; PIOTypes[numPIOTypes].name:=PIOName; BSB:=GetLocalizedPluginName(PIOName,locName); IF(locName <> '') THEN PIOTypes[numPIOTypes].locName:=locName ELSE PIOTypes[numPIOTypes].locName:=PIOName; PIOTypes[numPIOTypes].num:=1; 99: {Escape} END; 1 Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 You can be certain that I was poking the columns with a stick. I saw something there and moved the columns to figure out what was going on. I just tried running Locate Class Objects with developer mode turned off. No error message! Quote Link to comment
michaelk Posted December 7, 2023 Share Posted December 7, 2023 That's hilarious. I remember being told in college that we could NOT use GOTO statements. Now I'm going to start GOTOing everything. 1 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.