Jump to content

Jesse Cogswell

Member
  • Posts

    628
  • Joined

  • Last visited

Posts posted by Jesse Cogswell

  1. @JBenghiat is referring to either the EncryptPlugin function or the EncryptAllPlugins function.  These are not included in the standard VW installation, you have to download the SDK and extract the BatchEncryption.vlb file and put it in your User Folder.  As a short note, the link in the online Function Reference is broken, so use this one instead to get the SDK file.  It looks like the SDK for 2024 isn't available yet.  The .vlb file will only work for the year that you downloaded (at least that's been my experience).

     

    I have a custom plug-in that I wrote to encrypt my plug-ins that basically takes in a folder and populates a List Browser with .vso, .vsm, and .vst files sorted by last modified date.  When you press OK, it encrypts all selected files.  This is nice because I can put all of my files in a remote location from my User Folder, so the plug-ins stay editable for me but easily accessible for sending out to folks.

     

    image.thumb.png.f1605fa88f1fb4fd23fa1a1935d695b8.png

    • Like 1
  2. @geo44rey I wrote a plug-in a couple of weeks ago to help consolidate classes.  It essentially remaps all objects of one class into another class with an option to delete the original class.  It's along the same lines as deleting a class and reassigning objects using that class to a different class, but the plug-in lets you do it for multiple classes at once.  The original post can be found here:

     

    image.thumb.png.b210760180268492dfb0cf2e432167bd.png

     

    As for Marionette, there might technically be a way to recreate my script in Marionette but I could see it being a huge pain.  Marionette is essentially a visual way of writing scripts but I find the implementation to be clunky and slow, and have several problems with the execution.  And I really don't think Marionette has a solution for the Callouts problem since it's typically much more limited than the Vectorscript / Python scripting.

    Consolidate Classes.vsm

    • Like 4
  3. On 12/11/2023 at 9:53 PM, Benson Shaw said:

    Rotation is around z axis.

    Enhancement? - 3d rotation to tumble the instances?

     

    Symbol selection and numeric values reset to defaults after each run.

    Enhancement? - Dialog "remembers" previous setting?

    Done and done.  Merry Christmas.

     

    image.thumb.png.f25933b03e98934f5e34d9070b8a1390.png

     

    The X Rotation and Y Rotation settings will be disabled if you select a 2D or a hybrid symbol.  It should remember all of your settings now (I didn't test every single box and button).  Let me know if you see anything strange.

    Randomize Symbol Insertion.vsm

    • Like 3
    • Laugh 1
  4. I wrote a plug-in a while back that can split up a worksheet into multiple parts.  On normal worksheets, all of the data in the created worksheets are referenced back to the original worksheet so they will all stay up to date (on recalculation anyway).  On database worksheets, the data will be made absolute and will break reference from the original master.  But it still might prove useful to you.

     

    I very much agree that worksheets and worksheet formatting is very handy to have in Vectorworks but feels very outdated.

  5. CreateImageControl will work but only if you have your logo image loaded in as a drawing resource.  In which case, you would use vs.GetObject to get a handle to the Image resource to pass into vs.CreateImageControl.  You would accomplish this by shipping your plug-in with a VW file containing an image resource of your file.  When your command is run, it would determine if your logo image exists in the drawing and if it doesn't, it would use vs.BuildResourceListN and vs.ImportResourceToCurrentFile to import the image into the active file.  If you don't want to have to import your logo every time someone runs your command, you could instead use vs.CreateImageControl2, which can take in a file path to a VWR file.

     

    The key in this case is to ship your plug-in with a VWR file.  VWR files are pretty easy to make once you know what it's looking for.  You basically setup a folder with all the resources you need and then zip it.  Then you change the file extension from .ZIP to .VWR.  More information can be found here:

     

    • Like 1
  6. Whoa!  I use this all the time to bounce back and forth between the 2D and 3D components of hybrid symbols and personally love that I can go back and forth without leaving the edit container.  I guess if you either only draft in 2D or 3D it could annoy you and it probably should be a Vectorworks Preference setting whether you see it or not, I would hate to lose it.  It was one of my favorite additions to VW2019.

    • Like 1
  7. I have attached a really simple file to show how this works.  In the file, there are two design layers, one with a rectangle and one with a cube, and a sheet layer.  There is a simple, one line script that sets one of the design layers as your active layer.  If you run this script from a sheet layer, Unified View is now disengaged but won't show up in the Legacy 2D tab of the Document Settings.  To re-enable Unified View, you have to Enable legacy 2D features and then disable them.  Poof, Unified View is back on.

     

    Or you can add SetPref(94,TRUE) to any script that activates a layer and hope that your user isn't deliberately disengaging Unified View.

    Unified View Bug.vwx

    • Like 1
  8. 2 hours ago, Pat Stanford said:

    Have you tried the Reset All Plug-in Object command from the Tools:Utilities menu?  That should make them reset. And if you are only doing it occasionally after running the Classing PIO, then the delay should be tolerable.

     

    Just tried it in both VW2019 and VW2024, no change on the Callout object.  I'm assuming that the menu command just runs on ResetObject on every object in the drawing (something along the lines of ForEachObject(ResetObject,(INSYMBOL & INVIEWPORT & (ALL)));), so it has the same effect as my script since it contains a ResetObject command as part of the execution.

     

    The test that I just did looked like this:

     

    Initial Setup

    image.thumb.png.4a0a4655dacd0ef0972e54300f0f5490.png

    After running the script:

    image.thumb.png.03492fb6203de32f902099142988ba68.png

     

    After running Tools - Utilities - Reset All Plug-ins:

    image.thumb.png.2f930b80dc2bf6a9965da78cadbffbdb.png

     

    No change.  That test script looks like this:

     

    SetPenFore(FSActLayer,65535,0,65535);
    SetPenBack(FSActLayer,65535,0,65535);
    
    ResetObject(FSActLayer);
    ReDrawAll;

     

  9. I've added this ability, but I did notice a fun bug when it comes to Callouts.  The script technically works but the new attributes won't show up on the callout until you use the Attribute Palette to change something.  None of the usual tricks to force a reset work, changing the Callout's layer, changing a parameter, or moving the object around.  If you change the Callout's class after the fact it will take on the attributes of the new class but I could not get it to work within a single run of the script.

     

    I know you probably want this to work on Callouts since they're probably one of your most mis-classed objects, but there doesn't seem to be a solution with a script at the moment.  Even running the command twice, once to set attributes by class and again to set the new class, didn't work.  This is true at least for VW2019, 2023, and 2024 on Windows.  It might work properly on Mac.

     

    Callout in the None class with no By Class attributes:

    image.thumb.png.d91a9093fcfee4301ac744542e494eaf.png

     

    Running the command:

    image.png.a401879029189ebd89afa5cccfb9d162.png

     

    After running the command, the only attribute that "stuck" is the fill pattern:

    image.thumb.png.cbd0b6ec9ed5ae70b8910fc6f6ebb902.png

     

    Changing parameters, layer, and even the note contents has no effect:

    image.thumb.png.e16993be6cf31d7ec5508d226e2c30c0.png

     

    Selecting the note and using the Attribute Palette "Make All Attributes By Class" button:

    image.thumb.png.826798829497a4704baa59e216bd5981.png

     

    This seems to be a bug with the Callout tool itself.  I tried a simple script that would set the pen color of any selected object to magenta and it works fine on everything except Callouts.  Neat.

     

    Anyhow, updated plug-in is attached.  Save it over the existing one in your User Folder and restart Vectorworks.

    Reset Plug-in Obj Classes.vsm

  10. 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;

     

    • Laugh 1
  11. All done.  Here you go, lightly tested in VW2023 and VW2024:

     

    image.png.7a962254336423b8b4e8075e7a55db62.png

     

    @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:

    1. Download the attached Reset Plug-in Obj Classes.vsm file
    2. Open your Vectorworks User File in a file explorer / Finder window
      1. 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
    3. Open the Plug-ins folder
    4. Place the downloaded Reset Plug-in Obj Classes.vsm file into the Plug-ins folder of your User Folder
    5. Restart Vectorworks
    6. Put the new plug-in into your workspace
      1. Go to Tools - Workspaces - Edit Current Workspace
      2. Select the Menus tab
      3. In the box on the left, find and expand the category JNC
      4. In the box on the right, find a menu to place the new command in, such as Edit or Modify or Tools
      5. 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
      6. 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

  12. @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.

    • Like 4
  13. 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.

    • Like 2
    • Love 2
  14. I think you are missing one set of parentheses in your SelectObj criteria.  It should be (INSYMBOL & ((C <> 'NonPlot') & ((T = LOCUS) | (T = LOCUS3D)))).

     

    Also, a more efficient way to achieve what you are doing would be through a ForEachObject call.  It would make the script one line since there's no need for variables.

     

    ForEachObject(DelObject,(INSYMBOL & ((C <> 'NonPlot') & ((T = LOCUS) | (T = LOCUS3D)))));

     

    • Like 1
    • Love 1
  15. It's the only reason I still use VW2019 at this point.  I do all of my development in 2019 so that the plug-ins will work in any version between 2019 and now.  The language hasn't changed much at all, mostly new object variables and a handful of more convenient functions, but it's pretty rare when I come across something that must be in a newer version.

    • Like 1
  16. @jonp001 You really have to keep expanding until you get to an actual Vectorworks file.  This is how deep I have to go until I get to a place I can import resources from:

     

    image.png.7b26bf9503a577e2e4bc41900679cfef.png

     

    If you expand the folders until you get to the end and there isn't a VW file, then you may have a larger problem.  I am just on Spotlight and don't have the Landmark package, so I can only check Plants based on the premium libraries, but this might be the issue you are having.

    • Like 1
  17. For menu commands, you can call another VS menu command by using DoMenuTextByName('Your Command Name',0);  I assume it would be the same with Python.

     

    In this instance, I think the way I would go about doing this is to make the PDF export the main script and call the label creation script with vs.DoMenuTextByName.  This should allow the label creation script to fully complete before exporting the PDF.  If you put the label creation script into the Category Don't Put In Workspace, it won't populate in the Workspace Editor, so you can make sure someone doesn't try to use that script by mistake.

    • Like 1
  18. @zoomer I am 100% with you.  I would love to have Vectorworks change the name of the Screen Plane when editing symbols to "2D Component" and allow its use in the OIP without having Legacy Features engaged.  Or even better, an OIP option for planar options that only appear inside the symbol edit container, similar to the detail checkboxes.  It seemed that my conversations with Steve would lead things in that direction, but it's been three years and nothing has changed in this regard.  Have a look at my surprised face.

    • Like 1
  19. @zoomer Deprecating the Screen Plane was actually a huge bummer in my workflow.  Doing lighting, I'm often near the end of the pipeline, so I get a "finished" model of the scenic or exhibit design.  Unfortunately, most of the designers I've worked with don't use hybrid symbols, so I'll get a file full of 3D Symbols and occasionally (shudder) just Groups of objects.  Converting the groups over to symbols is easy enough, just create the 2D geometry and Create Symbol, but editing 2D geometry into 3D Symbols can be a bit tricky.  I do not like the Generate 2D from 3D Component command because you lose class information and it hard sets the lineweights, so I rarely use it.  I developed a workflow of going into the 3D component edit and using Extract Face to quickly build geometry, then selecting all of it and sending it to the Screen Plane.  Ta-da!  Now you have a hybrid symbol.  Video example below:

     

     

    This process was made more difficult in 2022 when they deprecated the Screen Plane, as I would have to enable to Legacy Features, move the objects, then disable the Legacy Features anytime I wanted to use this process.  After I complained on the forum when 2022 first came out, Steve Johnson from VW emailed me asking for a demo of my workflow.  I recorded the video above, and we started talking about adding a plane option when inside the 3D edit component for something like "2D Symbol Component", but it never happened.  So now I have a script in my workspace that will set the plane of any selected object to the Screen Plane that I can run when creating hybrid components.

    • Like 3
  20. Importing resources from another drawing shouldn't re-engage the 2D Legacy Features, since it's going to assume that you will be putting things on the Layer Plane or a 3D working plane.  Even copying and pasting groups containing screen plane objects will result in all group objects being on the current working plane.  I just did a quick test trying to force the features on by importing and copying and pasting as wasn't able to do it.  You should be in the clear.

×
×
  • Create New...