Jump to content

Jesse Cogswell

Member
  • Posts

    909
  • Joined

  • Last visited

Reputation

1,231 Spectacular

Personal Information

  • Location
    United States

Recent Profile Visitors

13,196 profile views
  1. I tried to $INCLUDE a Python file inside a Vectorscript file a while back and it wouldn't compile since it tried to compile the Python as if it were Vectorscipt. I just did some testing with ReadBin and it should work. The documentation for ReadBin straight sucks and doesn't tell you all of the things you need to know, if reading as a string, you need to include two additional arguments, the length of the string and the encoding. Here is the code I used to test it, and it faithfully reproduced a Python file. I haven't tried it with PythonExecute yet. PROCEDURE TestEncoding; CONST kPath = 'Enter file path here'; kUTF8 = 3; VAR contents:DYNARRAY[] OF CHAR; BEGIN Open(kPath); ReadBin(contents,65535,kUTF8); Close(kPath); CreateText(contents); END; Run(TestEncoding);
  2. I think @JBenghiat has the right solution using the string repository. Have the VS script call the Python script with CallToolByName (if it's a tool), or DoMenuTextByName (if it's a menu command). Then have the Python script store all of the needed variables into the string repository using the Rpstr_ set functions, and then have the VS script recall the variables using the Rpstr_ get functions. Then use the Rpstr_RemoveValue function to clear the string repository values if they are no longer needed. The only snag you might hit is that I'm not sure whether Vectorworks will allow a script to run and complete while executing another script. But it's certainly worth a shot. Otherwise, wrapping your Python script into a PythonExecute function and just having it live inside your Vectorscript is another way. You might even be able to get away with using Open to open the Python file, then use ReadBin with the proper encoding (probably UTF-8?) to get the full contents of the Python file and send it to PythonExecute to run it. Don't forget to add a PythonBeginContext and PythonEndContext around any Python code inside Vectorscript.
  3. I have something of a solution to this that I wrote two years ago. It's still very much in beta, but I've used it on several projects and it's worked pretty well, there's just a couple of bumps left to iron out with textures with Image Mask transparency shaders, particularly using alpha channel. There aren't Vectorscript commands to set the source for the image mask (grayscale, transparent color, alpha channel), so I have to cheat and have the script open the shader settings, which doesn't have an option to specify alpha channel. If that's something you think you'll need, I can describe the workarounds that I use, not awful but not as painless as it should be. More information can be found in the following thread: I'll add you to the DM thread containing the download.
  4. Absolutely! Just replace the GetSymLoc3D(h,loc.x,loc.y,loc.z); line with Get3DCntr(h,loc.x,loc.y,loc.z);
  5. I was in the middle of writing out to check that. Kind of ironic that the plug-in library featuring the new AddCredentials function is not verified... Also, the Script Batch Process being in Install Partner Products is a complete lie, at least at the time of this post.
  6. Since they mentioned the orientation flipping when importing into a previz software, most of the minutia in terms of yolk and hanging hardware is largely irrelevant. The MVR file itself will contain little if any of the geometry data, just enough to match the fixture with the relevant GDTF or Vision model and fixture orientation. In their case, the fixture orientation is coming in backward in their previz software. I've seen this even with Vision where Vision is expecting a fixture to be flat mounted vs hanging from a clamp and has to be reversed. Most of the time that I encounter it, I only have a couple of fixtures that are wrong so it's not that big of a deal to reverse it on the affected fixtures, but if it happened to every fixture, I would probably want to fix it before exporting, too. I originally messed around with Set3DRot for this, but ran into all kinds of issues where Vectorworks would try to "help" and change the wrong axes. Like adding 180 to the X Rotation would result in mathematically inverting the Z Rotation and also changing the Y Rotation. After a bit of time spent trying to correct this by either running multiple instances of Set3DRot or trying to do more than one axis at a time in a Set3DRot call, I gave up and went back to SetEntityMatrix. I've used it a lot before and found it to be generally very reliable for rotating planar objects, PIOs, and 3D Symbols, though the description in the function reference points to it being used for a very different purpose. The only trick being that you need to plug in the absolute rotation values, so you need a Get3DOrientation call to get the current values.
  7. Good morning. This is very achievable via script. The following should work for you, at least it does in the file you sent along. PROCEDURE SelectedInvert; {* Inverts selected objects Developed by: Jesse Cogswell VW Version: 30 (VW2025) Date: 11/30/2025 Revisions: *} VAR layerOption:INTEGER; currentLayer:STRING; PROCEDURE Invert(h:HANDLE); {Inverts given object} VAR loc,rot:POINT3D; mirrored:BOOLEAN; BEGIN GetSymLoc3D(h,loc.x,loc.y,loc.z); IF(Get3DOrientation(h,rot.x,rot.y,rot.z,mirrored)) THEN BEGIN IF(SetEntityMatrix(h,loc.x,loc.y,loc.z,rot.x + 180,rot.y,rot.z)) THEN ResetObject(h); END; END; BEGIN currentLayer:=GetLName(ActLayer); layerOption:=GetLayerOptions; CASE layerOption OF 5: {Show/Snap/Modify} BEGIN ForEachObject(Invert,(VSEL)); END; OTHERWISE BEGIN ForEachObject(Invert,((SEL) & (L = currentLayer))); END; END; END; Run(SelectedInvert); Image before running script: Image after running script: Let me know if this doesn't solve the issue. Just out of curiosity, which previz software are you importing into?
  8. Good catch, I guess I either forgot about that or didn't look for it. I'm not using 2026 regularly yet but usually build a shortcut to the function reference in a more convenient location. I don't super love that they've transitioned to online only, but I understand it. I'll also be saving a backup copy of the VW2025 function reference for use in the future.
  9. Also, VW still ships with the offline function reference (which is what Pat's screenshot is from). I don't know if you are on Windows or Mac, but on Windows it can be found in the Program File for Vectorworks in a folder called VWHelp. I imagine it's in the application folder on Mac, but don't have one to test. If you have Vectorworks on your machine, you also have an updated function reference.
  10. Any time you use SetRField, you need to have a ResetObject call for the changes to manifest, changing an object's record values will not trigger a reset.
  11. VW2022 was the year that they introduced the individual surface texturing system and removed the old Extrude "parts" (Top, Sides, Bottom) like they are showing in VW2017. Instead, you need to launch the Texture Tool, select a texture, and then select the face you want to texture. The original VW2022 guide for this can be found here: https://app-help.vectorworks.net/2022/eng/VW2022_Guide/Textures/Applying_textures_to_objects_and_faces_using_the_Texture_toolhtm.htm#h And Tom is correct, with this system they removed the Perimeter map (which used to be the default) and replaced it with Surface UV. There are many instances where perimeter mapping is more helpful, so it was great to see it make a return in 2026.
  12. A couple of things: If your plug-ins are written in Python, the Vectorworks encryption functions will prevent opening and editing the plug-ins in the Vectorworks IDE, but will not encrypt the source code. If the plug-ins are written in Vectorscript, the functions will encrypt the source code, with the only things left in plain text being plug-in strings (which makes perfect sense since they can be edited afterward after encryption). It's one of the reasons I still write all of my plug-ins in Vectorscript, even after getting more familiar with Python. If I absolutely need a Python function or library, I can use the PythonBeginContext, PythonEndContext, and PythonExecute VS functions to achieve that while being able to fully encrypt. The hardest thing is passing variables back and forth, since vs.GetVSVar and vs.SetVSVar won't work with encrypted plug-ins, you have to pass variables through the string repository instead (found this out the hard way). Installing the BatchEncryption file from the SDK won't get you a menu command, it will get you access to the EncryptPlugin and EncryptAllPlugins functions. You will need to write your own menu commands to use them. Also note that these commands offer the same encryption as the Shift-Ctrl-Alt-click method you tried before, just in a more convenient and scriptable sense. They still won't encrypt Python code. Any time you move or change a plug-in file outside of the Vectorworks IDE, you generally need to restart Vectorworks. Vectorworks scans the plug-in files when it starts, so if you're going from an encrypted plug-in to a non-encrypted plug-in, you will need to restart for the plug-in to properly get moved back to the Custom Plug-ins tab. If you copy and paste plug-ins in the User Folder while Vectorworks is open, if they are unencrypted you don't necessarily need to restart, you just need to open the script or the Plug-in Definition dialog and press OK before Vectorworks will register the changes. The problem you are having is that you can't really do that if the plug-in is still in the Third-Party Plug-ins tab, which they will be until you restart. I also cannot stress enough the importance of keeping back-ups of all of your plug-ins just to make damn sure you don't encrypt the wrong ones by accident. Once encrypted, there's really no way to get them unencrypted. I'm going to attach the menu command that I wrote to encrypt plug-ins from the post you mentioned earlier. It should help you see the implementation of EncryptPlugin (not that's difficult to use) and will save you the time of writing your own. It is written in Vectorscript, but it also uses Python to get the last modified date, so you can see using Python inside Vectorscript. It's old and could use a little love (it doesn't currently detect .vst files and has even older methods that I used commented out), but should get you well on your way. I use a different system now that integrates with my version tracking database. When I update the database with the new version and release notes, the plug-in automatically copies the source code for the plug-in from the User Folder to backup folder as well as to a local Git on my machine. The copy in the Git then gets encrypted with the EncryptPlugin function. It's then ready to push on to GitHub. It saves a ton of time and is pretty bulletproof (now I'm going to find some wood to knock on...) Encrypt Plug-ins.vsm
  13. Personally I wouldn't put the license check as a hidden parameter, it's way too easy for a user to build a worksheet and change the value. Here's how I would do it: I would have a global variable in the plug-in storing the current licenseCheck state. Like @JBenghiat has suggested, I would use the String Repository to hold two separate boolean values showing whether the license has been checked for the session (defaulting to FALSE), and storing the current license state (also defaulting to FALSE). If the repository contains no value for having been checked, then it would run license check function that you have and store the result in both the global variable and setting it in the string repository. I would have the check for the state in the plug-in's main driver before the event code. This way it's guaranteed to run in either a reset or widget prep situation. The license check code placed before the event code would look something like this: IF(NOT Rpstr_GetValueBool('SamIWasLicenseCheckedToday',FALSE)) THEN BEGIN licenseCheck:=CheckLicenseFunction; Rpstr_SetValueBool('SamIWasLicenseCheckedToday',TRUE); Rpstr_SetValueBool('SamIWasLicense',licenseCheck); END ELSE licenseCheck:=Rpstr_GetValueBool('SamIWasLicense',FALSE); Basically, it would run the license check only once for the session and otherwise would pull the result from the string repository, saving you the overhead of running it every time a PIO is reset or selected. You would technically not even need to use the global variable, you could just call the Rpstr_GetValueBool each time, but that is a lot of extra typing. The added benefit of this system is that you could use the same repository value for each of your plug-ins, so any one of them could verify the license for the rest of them (assuming they're offered as a set and not a la carte). The repository could potentially be bypassed by a savvy user but only if they knew the exact string you used for the repository entry, so you might consider "salting" the string with a random word or numbers if you're paranoid.
  14. My guess as both why some of the frames look different and why the loft is failing is that the some of the frames (the ones that are bright white) are still planar polylines. You should be able to select them and Convert to NURBS.
  15. I'm on Windows and can confirm that in VW2026, there is a hard minimum of 4 icons wide for tools that is not present on VW2025 or earlier. No idea why this was changed.
×
×
  • Create New...