Jump to content

AlHanson

Member
  • Posts

    70
  • Joined

  • Last visited

Everything posted by AlHanson

  1. Here's the PIO file. I think this is all you need? I haven't really gotten around to figuring out portability yet. 😆 PathExample.vso
  2. A fair point to explore- that was the only way I could figure out how to make the path a visible element in the drawing when I was getting started with my scripting and I've just continued to do it as it was working, but it does seem like there has to be a better way of approaching this that I'm missing- perhaps by some preference setting I haven't found yet? I never dug any deeper into that once the duplication solved the initial hurdle. That said, getting rid of the duplication doesn't help the situation and the initial path object is still grabbed by the symbol creation so it's just one less Handle variable is NIL error in the initial output until the symbol is created.
  3. Thanks Pat. Here's the simplified code for reference. This would be part of a 2D path PIO with Events enabled. import vs spacingBetween = 9 bUseSymbol = True markerSymbol = 'Direction Marker' (BOOL, pioName, pioHandle, pioRecordHandle, pioWall) = vs.GetCustomObjectInfo() # ---------------------------------------------------------------------------------------------------------------------- def positionMarkerSymbolResource(): if vs.GetObject(markerSymbol) == 0: # Check if symbol already exits, create symbol if not vs.BeginSym(markerSymbol) positionMarker((0, 0)) vs.EndSym() def positionMarker(pt, rotation=0): markerWidth = 3 markerGroup = vs.BeginGroupN(None) vs.ArcByCenter(pt[0], pt[1], markerWidth/2, 0, 360) # Draw Circle component vs.BeginPoly() # Draw Triangle component vs.MoveTo((pt[0] - markerWidth / 2, pt[1])) vs.LineTo((pt[0] + markerWidth / 2, pt[1])) vs.LineTo((pt[0], pt[1] + markerWidth / 2)) vs.EndPoly() vs.SetPolyClosed(vs.LNewObj(), True) # Close Triangle vs.SetFillBack(vs.LNewObj(), (0, 0, 65535)) # Set Triangle Color vs.EndGroup() vs.HRotate(markerGroup, pt, rotation) # Rotate Marker Group return markerGroup def main(): pathHandle = vs.HDuplicate(vs.GetCustomObjectPath(pioHandle), 0, 0) vs.SetFPat(pathHandle, 0) # No Fill pathLength = vs.HLength(pathHandle) # Length of Path ptCount = int(pathLength // spacingBetween) + 1 # Max Count by spacing for i in range(ptCount): distance = spacingBetween * i #Distance per step (b, pt, tangent) = vs.PointAlongPoly(pathHandle, distance) rotation = vs.Vec2Ang(tangent)+90 if bUseSymbol: positionMarkerSymbolResource() # Check Symbol Resource vs.Symbol(markerSymbol, pt, rotation) # Insert Symbol else: positionMarker(pt, rotation) # Draw non symbol Marker # ----------------------------------------EVENTS------------------------------------------------------------------------ kObjOnInitXProperties = 5 kObjOnWidgetPrep = 41 kParametricRecalculate = 3 kObjOnSpecialEditID = 7 kObjXPropSpecialEdit = 3 kReshapeSpecialEdit = 3 kObjXPropEditGroup = 1 kObjXPropEditGroupPath = 2 def execute(): (theEvent, theButton) = vs.vsoGetEventInfo() if theEvent == kObjOnInitXProperties: vs.SetObjPropVS(kObjXPropSpecialEdit, vs.Chr(kReshapeSpecialEdit)) # Double Click Edit Path vs.SetObjPropCharVS(kObjXPropEditGroup, vs.Chr(kObjXPropEditGroupPath)) # Double Click Edit Path if theEvent == kParametricRecalculate: main() if theEvent == kObjOnSpecialEditID: # Double Click Edit Path vs.EditObjectSpecial(pioHandle, 3) # Double Click Edit Path execute() (This basic script could also be a good starting reference for anybody looking for help creating a simple duplicate along path in the future)
  4. I'm building a simple tool that just does a distribute along path for an object, but it can end up drawing hundreds or thousands of each object along the path depending on the length and at these larger quantities it gets a little slow and cumbersome. This process works better way better just inserting a symbol since all these objects are the same anyway. Rather than having to import this symbol from some external resource file, I've just adapted the original draw script to create a symbol definition resource if its already in the resource library. The problem I'm running into is that if I try to run the create symbol script inside my object the custom object path gets swept up by the script and embedded into the symbol which will then break the rest of the script as the path is no longer part of the PIO. I'm not even sure how this is happening as the vs.BeginSym trigger comes well after the path creation and processing. I've tried moving the symbol creation trigger to a couple different points in the script/event flow and nothing I've attempted prevents this. Does anybody have any recommendations on how to avoid this, or a specific event to handle this creation, or just a better way to avoid creating a symbol?
  5. Anybody know of a way to access the handle of a sheet layer viewport's camera? Coming up dry on this one without manually entering the viewport camera to check its name.
  6. Thanks Pat- that's already the approach I'm using here to build the list. I'm presumably doing this stage correctly as it's getting all the correct data but perhaps this also part of my problem if I'm doing something odd at this stage. Here's a bit more info to clarify: I'm using vs.BuildResourceListN on the Lighting Stands library file and getting all the names added correctly with vs.GetNameFromResourceList and vs.vsoWidgetPopupAdd. In the event script I'm inserting the Widget and this works correctly. if theEvent == kObjOnInitXProperties: #Mostly lifted from _c_'s event example ok = vs.SetObjPropVS(kObjXPropHasUIOverride, True) ok = vs.SetObjPropCharVS(kWidgetGroupMode, vs.Chr(kWidgetGroupAutomatic)) #removed other unrelated inserts to keep this clean and clear ok = vs.vsoInsertWidget(cP___div2 - 1, kWidgetSeparator, cP___div2, O_GetLocParmName(vs.GetName(pioRecordHandle), '__div2'), 0) ok = vs.vsoInsertWidget(symbolContainer-1, kFieldPopUp, symbolContainer, O_GetLocParmName(vs.GetName(pioRecordHandle), '__SymbolList'), 0) Parameters are set in the Plug in Manager. Widgets are linked correctly in the OIP, but the Symbols popup is blank by default. Clicking the popup will show everything that was added to it, but selecting anything from the list will just return the popup to the blank state as seen above.
  7. Struggling with making an OIP Popup object functional- the goal is to just have a text based popup with the a list of symbols from an external resource. I've gotten the popup widget inserted into the OIP, and I've successfully populated it with the names of the symbols from the library file and I have it linked to an existing parameter. However after this I'm not having any luck. The popup is there, defaulting to blank data. If I click on it, it'll pop open and show me the list of symbols but from here clicking on anything doesn't actually set the field and the popup just returns to an empty field. I'm monitoring the events and there doesn't seem to be anything of note happening on selection with kObjOnInitXProperties kParametricRecalculate and kObjOnWidgetPrep cycling as usual after modifying a parameter. What am I missing here?
  8. SetEntityMatrix works like a charm @JBenghiat, even saved me a few lines of code. I'll have to use this one more often. Thanks! @Sam Jones Using SetEntityMatrix on the Lighting Device- the next value sets the X, Y, Z coordinates for the device, and the next three values represent the X, Y, Z rotation values. Example included. HTH # hObj = Handle of Lighting Device (BOOL, pioName, pioHandle, pioRecordHandle, pioWall) = vs.GetCustomObjectInfo() #Gets info from the current PIO zHeight = 48 ptLocation = vs.GetSymLoc(pioHandle) #2D Location of the Custom Plug-in Object xRot = 180 yRot = 0 zRot = 180 vs.SetEntityMatrix(hObj, ptLocation[0], ptLocation[1], zHeight, xRot, yRot, zRot)
  9. Of all the complicated things I spent the morning working through, I can't believe that this is the one that is tripping me up- I'm struggling with properly rotating a lighting device in 3D just to force a fixture into an upright yoked position (180 on y Rotation, or 180x/180z as the OIP will recalculate to). My first attempt at this is using vs.LDevice_SetParamReal however this is doing absolutely nothing and doesn't provide any feedback so it's difficult to understand why. The used values should all be fine based off a previous investigation into this command a few months back. I also tried using the OIP name 'X Rotation' which also does not work (didn't expect it to). I also ran a loop and tried changing the cell and accessory index parameters around just to see if anything work take, but nothing did. vs.LDevice_SetParamReal(hObj, -1, -2, 'xRot', 180) vs.LDevice_GetParamReal(hObj, -1, -2, 'xRot') The Get version of this command works perfectly using the same values and properly retrieves whatever values I manually set the device to. Also, the Get command will retrieve the new values set via the Set command when run after the Set commands in the script, but the end result will still be no change. Running just the get again following this will show to the initial/current values not the values that were supposedly set in the previous script run. I assumed that maybe a reset command must be triggered to update the light but I've thrown LDevice_Reset, LDevice_ResetVisual, vs.ResetObject or the hell of it vs.ResetBBox into the mix but none help this. Eventually I gave up on the LDevice commands and went straight into the record commands which are giving me the exact same issues. I can read it, I can't set it. It shows as changed if I immediately Get following Set but does not actually update the device. vs.SetRField(hObj, 'Lighting Device', 'xRot', 90) x = vs.GetRField(hObj, 'Lighting Device', 'xRot') I went a step lower into vs.Set3DRot and vs.SetRot3D which *KINDA* work. It takes some math to get the points and such all set correctly and I can get the desired rotations but only if I switch views to 3D which gets a little clunky especially when I'm dealing with symbol rotation as well. Without script forcing the views into a 3D view these commands fail in top/plan view since it's a hybrid object. I'm sure I can kludge around this approach a bit more and make this all work, but it really seems like this shouldn't require any sort of work around for something so simple. Is the an approach I'm overlooking, some error in the values or just some bugs here? Anybody have a solution or insight? I feel like I'm missing something obvious here since this process should be a no brainer at this point...
  10. Sorry for the long delay but I haven't been able to dig into this for a while. This is very helpful @MullinRJ, but I'm still struggling with some looping issues. I *think* I've finally narrowed down the problem to the plug in implementation I was using while playing around. I've been playing with as a Point Object Plug In, but with this option I can go through the process of displaying the pop up, selecting from the pulldown and ok'ing the selection and everything works as intended, however it will then retrigger event 12255 and start the process all over again, including when switching over to the modified code that you've provided. If I import the script into a simple menu command script, it all functions perfectly as intended and inserts the selected symbol without issue. So in part, the struggle here is likely my sequence of events if I am to build this as an insert point object... I'll have to dive into that more since this initial pass was really just experimentation to get used to the dialog building rather than creating something specific. Insights on the loop issue would be helpful if anybody has some better understanding of this or can suggest the better approach to using a dialog like this in a point insert object.
  11. I'm working with my first custom dialog display, and all the new stuff is clicking into place just fine, but I'm struggling to figure out the best ways of processing the interaction and not having any luck finding examples or details. Here's the example I've been playing with (might be a few oddities in the code lingering from some of the different approached I've been experimenting with). Right now this is attached to a point insert custom tool, and I'm just experimenting to get an understanding of the flow here- All I'm currently doing is building a simple popup that will show the symbols from another resource file and insert the selected symbol into the custom object. I've got Alerts tied to the dialog handler so I can see all the events that get passed around while I'm figuring this out. Where I'm struggling, is on the symbol insertion step. I'm logging the selection event just fine and getting the resource index from the Thumbnail Popup, and off this event setting a variable to the selected index, under the assumption that then when I click 'OK' it will register the 'OK' press, check that the iSymbol variable has been set and then insert it. However getting this variable passed around is proving problematic. I've tried declaring the variable both inside and outside Dialog_Handler, each have issues and I'm frequently being told iSymbol is getting referenced before assignment. The only way I'm able to make this 'work' is to build the symbol insertion in to the selection in the pulldown but that seems messy and can insert symbols without confirming anything. This also is causing me some looping issues that I'm not clear on the cause. After confirming the symbol, the SetupDialogC event is flagged again. Not sure what that's about... Also, I'm getting an item passed into the data handler as -12613. I dug around and checked the usual places, searches and the MiniCadCallBacks.h file and I can't find anything about what this flag represents. Any ideas? So clearly I'm still not quite getting the full process down, any easy fixes here or examples that can clear up some of the messiness I'm encountering? import vs debugMode = True btnOK = 1 btnCancel = 2 kThumbnailPopup = 101 SetupDialogC = 12255 iSymbol = -1 #bSymbol = False def Dialog_Handler(item, data): #global iSymbol if debugMode: text = 'Running Dialog Handler. Values Returned:\r\ritem: ' + str(item) + ' | data: ' + str(data) vs.AlertCritical('DIALOG HANDLER', text) resourceType = 16 fullPath = "../Libraries/Objects - Building Equip_Appliances/_Office Equipment.vwx" (symList, numItems) = vs.BuildResourceListN(resourceType, fullPath) # (symList, numItems) = vs.BuildResourceList2(resourceType, 0, '', False) if item == SetupDialogC: for i in range(numItems): name = vs.GetNameFromResourceList(symList, i) #if name[:7] == 'zNested': # continue vs.InsertImagePopupResource(dialog, kThumbnailPopup, symList, i) if item == kThumbnailPopup: # Interaction with Pulldown Menu #bSymbol = True iSymbol = data hSymbol = vs.ImportResourceToCurrentFile(symList, iSymbol) vs.Symbol(vs.GetName(hSymbol), (0, 0), 0) if debugMode: vs.AlertCritical('Clicked something in popup, setting iSymbol to: ', str(iSymbol)) #if item == btnOK and bSymbol: # OK Button Pressed and symbol has been selected #hSymbol = vs.ImportResourceToCurrentFile(symList, iSymbol) #vs.Symbol(vs.GetName(hSymbol), (0, 0), 0) #if debugMode: #vs.AlertCritical('OK BUTTON!', 'iSymbol: ' + str(iSymbol)) def CreateSampleDialog(): global dialog iSymbol = None dialog = vs.CreateLayout('Add Choice Sample', 1, 'OK', 'Cancel') vs.CreateThumbnailPopup(dialog, kThumbnailPopup) vs.SetFirstLayoutItem(dialog, kThumbnailPopup) vs.RunLayoutDialog(dialog, Dialog_Handler) vs.SetPref(412, True) CreateSampleDialog()
  12. Still slowly working through things and haven't gotten into the event based stuff yet, but DEFINITELY spending some time playing with this example. Great to see this, I was just thinking about starting to make similar simple example projects to help the community and this is a great reference. Here's a few things I have found so far: -Incorrectly placed control points just seems to be a refresh bug. I've found that creating the control point the in the definition and then later changing it as I'm updating what the defaults should be as my script evolves doesn't take internally. It'll show the new default value but it's still holding the initial default value and sending that into the script. The only way I've been able to deal with this so far is to delete the control point in the definition, exit the plug in manager, (let the script spaz out with errors), and then go back into the plug in manager and create new control points with the corrected values. It's obnoxious but it's simple enough for a couple points since it auto names everything anyway. -Hiding the control points definitely seems to be an event based function because I initially just built the hide portion into and ELSE statement, but when the conditions changed to true it wouldn't come back until I also built the make visible line into the the initial IF portion of the script. Interestingly though, there doesn't seem to be any need to check the Event Based execution in the definition options. Haven't dug into this any further since it's working just fine for my current needs, perhaps there's some distinction here that will become more obvious as I dig into the event based code more.
  13. Excellent, thanks for all the fantastic info @Jesse Cogswell! Lots to dig through here, will take me some time to explore and definitely keep me busy this weekend! The function reference has definitely been my friend lately and has it's own dedicated screen at this point, but knowing what to look for is 90% of the battle- especially when can't just search for a clear term and have to guess on some abbreviations like 'CntrlPt' because searching for 'Control' doesn't help. Also, was not aware of the Script Reference HTML and it looks to be another great resource. I had previously steered clear of the VSO and Event Based stuff as I thought I saw in some post that these were really only available to C++ but looks like I'll need to spend some time reading and exploring this more.
  14. Working on figuring out plug-in tools via Python scripting and have a few questions: -How can I add a separator line to the OIP? Also a slider? Interesting how these are present in Marionette but no direct easy access in the Plug In Manager. -I'm having trouble with the default values on my control points- The defaults are set to values such as (0,30"), however when I insert the object all control points default to (0,0). Nothing in my script is directly updating these values, and they respond to being moved just fine after inserted. -I have a text object that is inserted at a control point, and a Boolean that toggles whether or not the text is displayed- how can I make this also get rid of the control point? -How can I use the Text controls in the menu to adjust the text settings in my object?
  15. Found it while looking at other things: vs.SetSymbolOptionsN A little frustrating that all these options in one spot are adjusted so differently, but at least it's there. Hope this helps somebody else down the line!
  16. Thanks! Basically what I assumed, just hoping to force to process and not have to drag it out with a manual step but it is what it is.
  17. Looking for some insight on setting the 'Assign to Class' options of a symbol via Vectorscript so I can set this as my script imports some mesh objects. The Symbol options dialog seems to present a lot more info than the appendix covers for Symbol options. vs.SetObjectVariableBoolean is the only thing that appears to edit this setting at the value of 128, but its just a bool that is either <Active Class> on False or True when any other class is selected. I've hammered the variable types and ranges in script and can't seem to track this down, if it's actually accessible. This isn't that big of a deal if I can't make it happen on the import, but I figured it's worth looking into before I start importing everything.
  18. I'm working on an import script for a lot of mesh objects, and would like to simplify them as they come in as some are unnecessarily complex. Is there any way to automate this with vectorscript that I'm not seeing in the function reference? I'm even open to manual ways of accomplishing this is anybody has some insight. I attempted to just delete random mesh vertexes over x quantity and this proved to be a terrible idea since the mesh can't just patch back in the missing polys this caused. 😆
  19. If anybody winds up here down the line, I finally figured this out. The command is vs.GetTextureRef/vs.GetTextureRefN. This was one of the first things I was trying, however everything I was testing on was a Mesh object, in which case you cannot use Overall for the part number. As I'm finding now, meshes us Part ID 4 ('Top of Extrude or Sweep'). Once I stumbled on that everything started working just dandy. Hope that helps somebody down the line!
  20. Looking for some help getting remote debugging through PyCharm Pro to work if anybody has experience. As far as I can tell I'm doing everything as needed, but it's just not coming together. I've followed guides as well from PyCharm Remote Debugging and Vectorworks Python Debugging and got some great info from this old post from @MeTheMachine. When I get to the final steps and actually run a script in Vectorworks for the debugger I get an error on the PyCharm side: I'm not sure what the problem is here. All software is current and downloaded today from PyCharm to the pydevd-pycharm library. I've tried to copy the pycharm-debugger.egg file the error says to use into my project environment but I'm either not putting it in the right place or I'm missing something in importing or referencing it in the script. I also attempted to follow the pip command which installs the version it wants, but I still get this error. Anybody have any insights on this issue or recommendations on alternative methods for debugging python scripts with Vectorworks?
  21. @Yasen Aleksiev Thanks for the correction and clarification to make this work. Very helpful!
  22. Perfect! I didn't realize that information was just hanging out in such an easily accessible place... Was hoping they had made this a built in function already to do this more simply, but clearly not. Your information was perfect! I was able to whip this together in no time. Thank you much! My only tangential question then would be which is more practical? Running the file read code every time it needs to look up the data or simply including a dictionary put together from all this data. The files make more sense in terms of always getting the most current data (but how much are the gel libraries really changing these days?) but this is more code to run through on each run (which is still not very many lines). Ultimately I'm sure it makes no noticeable difference whichever route is used as it's all instantaneous and file sizes are miniscule. Just curiously pondering- I'm still fairly green at coding (I wrote the entire thing in python with the exception of the vs.FindFileInPluginFolder command you suggested).
  23. I notice there's some new vs commands to get Lighting Device information in 2021 and am trying to decipher the specific details for these: VS:LDevice_GetParamBool - https://developer.vectorworks.net/index.php/VS:LDevice_GetParamBool VS:LDevice_GetParamLong - https://developer.vectorworks.net/index.php/VS:LDevice_GetParamLong VS:LDevice_GetParamReal - https://developer.vectorworks.net/index.php/VS:LDevice_GetParamReal VS:LDevice_GetParamStr - https://developer.vectorworks.net/index.php/VS:LDevice_GetParamStr I've been able to get MOST of the data in the record working after some digging through the worksheet to get correct names on some of the more oddball parameters, but for some reason I'm not able to get a few of these fields to return anything on any of the commands, and they're mostly simple fields that I wouldn't have expected to have issues with: Device Type Instrument Type (Inst Type) Fixture Mode GDTF Fixture Mode GDTF Fixture Wattage Purpose DMX Footprint (Num Channels) Time Cost Frame Size Weight Symbol Name Anybody else have any luck with these or some other insight?
  24. AlHanson

    rotate list

    There's a "Reverse List" node that you can attach between your point list and the 3D poly node that should give you what you're looking for.
  25. Is there any way to get colors from the existing color libraries in Vectorworks via vectorscript- particularly for spotlight gel colors? Clearly it's there as the Color field on a lighting device can access the color libraries this way, but there doesn't seem to be a function that I can track down which gives a similar functionality. I've already previously built my own custom dictionary with gel names and RGB values that works great for what I'm doing, but it really seems like I shouldn't have to go this route of loading in hundreds of values manually when the information already exists in the program. Any thoughts?
×
×
  • Create New...