Jump to content

Jesse Cogswell

Member
  • Posts

    634
  • Joined

  • Last visited

Everything posted by Jesse Cogswell

  1. There are a couple of things getting in your way. The biggest thing has to do with your Availability Options. These determine when your command can be run, and the settings you have set up are fairly restrictive: The setting that is tripping you up is requiring Selection has 2D. This means that the command can only be run on Screen Plane objects, and you have Selection has 3D set to prohibit, so the command can never be run on objects on the Layer Plane. If you set these both to Ignore, the command will work correctly. That being said, I think there is something of a bug in Vectorworks that I never noticed before. Changing any of the Availability Options does not show any effect until Vectorworks has been restarted. This was tripping me up for a while, as I recognized immediately that this was an issue with Availability Options, but making changes didn't seem to have any affect. I set all to Ignore, then restarted Vectorworks on a whim. Suddenly the command worked perfectly. I reset Object Selected to Require and the command worked even with nothing selected. Restarted and then got the expected results. I think this is the only instance where changing the Plug-in Definition requires a restart aside from changing the name (and that only affects the Workspace, the command will continue working correctly until restarting Vectorworks, which will require resetting the Workspace to see the new plug-in name). I understand that the Selection has 2D / Selection has 3D nomenclature here is confusing. If you want the script to only work on planar objects, you will need to add in a check of some kind to your code. One such could be through the use of IsPlanarObj.
  2. For those curious, the Python code in the Marionette node is very simple: #Created 12/24/2023 Jesse Cogswell @Marionette.NodeDefinition class Params(metaclass = Marionette.OrderedClass): #APPEARANCE #Name this = Marionette.Node( "Str2NumF" ) this.SetDescription( 'Allows a user to convert a string value to a float value' ) #Input Ports x = Marionette.PortIn( 0,'s' ) x.SetDescription( "a string value" ) #OIP Controls #Output Ports y = Marionette.PortOut('n') y.SetDescription( "result float value" ) #BEHAVIOR def RunNode(self): #Libraries import math import vs #inputs x = self.Params.x.value #script b,y = vs.ValidNumStr(x) #outputs self.Params.y.value = y
  3. I didn't try the Float node while pulling from a Record Format, just having a manual string input a la: That seemed to work fine. The Str2Num node that I built does indeed work with pulling values from a record format, though. The attached example uses a Dimension Tape to set the width of the Marionette rectangle. Str2Num Marionette Example.vwx
  4. Or you can use this Marionette node that I just fabbed up. It works exactly like the ValidNumStr function that will properly convert a string value from a record format into a dimensional float value while also using the units specifier. I think it's a huge oversight to not have a node like this in the standard Marionette library. Str2NumF Marionette Node.vwx
  5. @Maury Jensen You will need to add a Float node between the Get Record Field and Add nodes. This should convert the string into a float value for the addition. However, keep in mind that this will only work if there aren't unit specifiers saved in the record field (', ", m, cm, mm, etc). If there are, you will need to remove them using a User Function node as specified in this thread:
  6. That's what I used to do. I would open up the User Folder and make a copy of the plug-in in a directory named "Unencrypted", then encrypt the plug-in and copy it into a directory named "Encrypted", then finally copy the backup back into the User Folder so that I could continue editing. Very tedious. My general recommendation when developing plug-ins is to work in the earliest version of Vectorworks that you have or that someone on your team might use. That way you hold on to some level of backwards compatibility. I do all of my development on VW2019, there have been very few advancements in Vectorscript that require me to use anything newer, and it lets me jump back and forth between versions depending on what version the project needs.
  7. @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.
  8. Quite right. Fixed below. Randomize Symbol Insertion.vsm
  9. @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: 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
  10. Done and done. Merry Christmas. 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
  11. 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.
  12. 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:
  13. 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.
  14. @michaelk Yeah...I'm not touching that. How did you get that information? Is it documented anywhere?
  15. 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
  16. 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 After running the script: After running Tools - Utilities - Reset All Plug-ins: No change. That test script looks like this: SetPenFore(FSActLayer,65535,0,65535); SetPenBack(FSActLayer,65535,0,65535); ResetObject(FSActLayer); ReDrawAll;
  17. 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: Running the command: After running the command, the only attribute that "stuck" is the fill pattern: Changing parameters, layer, and even the note contents has no effect: Selecting the note and using the Attribute Palette "Make All Attributes By Class" button: 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
  18. I was able to get it to work. I'll share my process. Draw top ellipse in Top/Plan view Off to the side, draw profile ellipse in Top/Plan view Draw angled cutting line Draw axis line Using the 2D Polygon tool in "Paint Bucket" mode, click on the quadrant to create our true profile Decompose the created polyline Select the resulting polylines along the outside edge and the cutting line and Compose Select the new polyline and the axis line and Convert to NURBS and Ungroup, you should have two NURBS curves Use Rotate 3D to get your NURBS curves into the proper plane Recenter your NURBS curves onto your rail ellipse Convert your rail ellipse into a NURBS curve. You should now have three NURBS curves Revolve with Rail, selecting the axis curve, the profile curve, and the rail curve. Then Ungroup and Add Solids to get your final shape I hope this answers your question. The key is getting to a point where you can get the profile curve and the cutting line to be able to be composed together before converting to a NURBS curve.
  19. 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;
  20. 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
  21. @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.
  22. 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.
  23. 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)))));
  24. 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.
  25. @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: 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.
×
×
  • Create New...