Jump to content

JBenghiat

Member
  • Posts

    2,024
  • Joined

  • Last visited

Everything posted by JBenghiat

  1. Assuming you have a list of old classes that map to new classes, and you have a means to traverse them (if you switch to python, you can use a dict). Classes have handles, so for each old name, see if GetObject returns a handle. If the handle exists but does not refer to a class, you need to either generate a warning or handle the name conflict in some way. Otherwise continue: Try to get a handle for the new class name. If it does not exist, simply rename the old class to the new class. If the new class name exists but does not refer to a class, handle the conflict by either alerting the user or modifying the new class name until it is valid Once you have a valid name for the new class, do a ForEachObject with deep traversal and change any objects that use the old class to use the new class.
  2. What exactly do you mean by clipbox? The clip cube, the cropped perspective frame, or something else?
  3. @michaelk has the answer. Note that there is a bug where not all text attributes get saved — I know alignment does not, and possibly line spacing, so you would have to manually code those (either set to a constant value or store to a parameter) @MullinRJ what you’re finding are the options to display the text style menu in the OIP. I believe that you also need object variable 800 on for style assignment to work automatically, otherwise you need to get the object’s text style and apply it to each text block.
  4. Unless this is part of a larger process, you can also export csv from the worksheet’s file menu
  5. CallTool isn't going to work for you. The tool will want to collect two points, then (I recommend) use vectors to calculate the length and rotation. Use the CreateCustomObject commands to place the pipe and/or create a Hanging Position. The universal name for the Hanging Position is "Light Position Obj". Use SetRField to set parameters. I know there's been posts on the forum about DebugListView, which can help you find universal names and hidden parameters. You can also construct a sample Hanging Position and examine the output of Export VectorScript. The pipe is path-based, so either call CreateCutomObjectPath, or set the path group after creating the object (the path should be a polyline). Any geometry in the Hanging Position needs to be inserted in its profile group. The trickiest thing is translating been the plug-in's internal coordinates and the coordinates of the overall world.
  6. @SamIWas You raise several questions here. Any object can be turned into a Hanging Position, and this can be accomplished with VectorScript. This would be the same as selecting the object, then choosing the Create Hanging Position command. In order to modify the geometry, you would have to edit the Hanging Position’s profile group. If you are asking if any object can be turned into a Rigging Object so that it directly interacts with Lighting Devices and loads, but still has options available in the OIP (without editing the profile group), then no. Rigging Objects need to be able to “answer” a certain set of questions that Vectorworks “asks” of them, and this is only possible via the SDK. In terms of snapping to the I-beam, this also wouldn’t be possible without the SDK. You can, however, place a Lighting Pipe at the bottom of the beam, and turn off the “draw pipe” option. This will give you a snappable line with the possibility of tick marks. You can definitely place a Lighting Pipe inside another PIO, but I’m not sure if it will still be detected as a rigging object. What you envision is definitely possible with the SDK. In VS, you can design a custom tool that draws a beam, places a Lighting Pipe for snapping, and wraps them in a Hanging Position.
  7. I think that menu and tool parameters haven’t worked for some time. Instead, use Get/SetSetting, a hidden record (GetObject(RecordName) gives you a handle to the record definition), or the string repository (RepStr commands)
  8. Plug-in objects have a record attached to them to hold plug-in parameters, but can also have data records attached to them, of which EntEquipUniversal is one. The plug-in record is not guaranteed to be the first record attached. Your best method depends on how you are filtering objects. If you are using ForEachObject, you can use the selected 'PON' (Plugin Object Name) to match a plug-in object by its universal name. You can also iterate through attached records, though I prefer using Eval and the PON criteria.
  9. In theory, all VectorScript constants are available in the vs namespace, so vs.SetupDialogC should work. This event runs for both the ok and cancel case, so in Raymond’s example above, you wouldn’t need to call SaveDialogPos() in two different cases. Vectorworks calls the dialog handler for every user interaction with the dialog, so it can run dozens of times with each dialog session. That means that you will be constantly repositioning the dialog, and if the user drags the dialog to a new position, it will snap back to the coded location.
  10. The parent of PIOHan. You have the test backwards: In preview, the PIO will not have a parent. When placed in the drawing, the parent will be non-nil, and the type will be layer, group, symbol, etc. (If somehow the preview is also non-NIL, check they type). Also be sure to test for duplications and copy/paste. IsNew may be true for both. I think you can get around it with the FirstRegen state (I don't have the constant in front of me) or by setting a hidden field to check if the object is new.
  11. The point object creates a preview for the tool. Check if the parent is NIL.
  12. I’m going to take the opportunity to plug BeamViz, which automatically creates the mask for elliptical beams. https://benghiatlighting.com/software/product/beamviz-6/
  13. GetLine() takes two clicks. Repeat until MouseDown() gathers a third click, which is exactly what you are observing.
  14. My guess is this is just an issue with the feedback string, and you can click ok. That said, I haven’t encrypted this way in years: I always use the batch encryption commands. The advantage is that the plug-in you’re encrypting doesn’t need to be in your plug-in folder, so you can encrypt a copy and not have to worry about locking your original script. I’m fairly sure you can search the forum for an earlier post on the subject
  15. There is not a method to do this, even with the SDK. You have a couple of clip surface commands that could work if your fill is a continuous polyline. An alternative solution would be to draw the insulation using a tile fill or line type that the plug-in scales appropriately. A tile fill would allow you to use separate objects, where you would have to calculate the end miters, while a line type combined with a path-based PIO (as others have mentioned) would make this a fairly easy script.
  16. The short answer is that VS does not have access to the same face selection capabilities that the SDK does. Pat's suggestion would probably work, though it would require a lot of careful duplicating and management of temporary objects.
  17. No, the UUID is core to project sharing, so Vectorworks is dependent on the objects maintaining the UUID generated at creation. You probably need to keep two sets of IDs: The database ID and the VW ID. I believe you can set the VW ID field to be unique but not required, so that new rows won’t duplicate the UUID. FileMaker should allow you to specify a unique index field. Alternatively, you can have a related table that just maps FileMaker record IDs to VW IDs
  18. https://developer.vectorworks.net/index.php/VS:Parametric_State_Notifications#kCreatedReset
  19. It's not quite so precarious — standard namespace rules still apply. When you have a script for objects with parameters, before running the script, Vectorworks will create a constant that uses the name of the parameter prepended with a "P." In python, these are all in the vs namespace, so you can access the parameter length with vs.Plength. Original Vectorscript has everything in the same namespaces, which is where Pat's example comes from. In python, you can have vs.PTS as distinct from PTS. And even in Vectorscript, you would only run into trouble if you also have a parameter named "TS." Note that all the vs.P… variables are constant. You can read a parameter value, but you can not write back to that variable and have it updated the object. For that you would have to use vs.SetRField() PrevObj is a method of vs (that returns a handle, which you can assign to a variable). As such, you would always call the method using parentheses: h = vs.PrevObj() vs.PrevObj refers to the method as an object, and something you would only do if, say, you had a function that took another function as a parameter. That's a fairly advanced coding concept. I suppose that you could get into trouble if you have an object parameter named "revObj," as Vectorworks would try to create a constant "PrevObj" in addition to the existing method. That would lead to either a compilation error or for PrevObj() to be re-defined.
  20. kObjOnInitXProperties runs once per session (Vectorworks open until quit), unless you are running scripts in developer mode, in which case objects are forced to re-initialize on every run. You can use object state events to catch new and duplicated objects. Alternatively, have your export script pull directly from the objects’ Uuid (see Pat’s post above), rather than depending on a record field.
  21. Sorry, one more point of clarification. LNewObj is short for Last New Object. The object creation call, vs.Rect() in the example above, creates the handle. vs.LNewObj() just asks VW to tell us what handle points to the object we just created, it doesn't actually create anything, and you only need to call it if you want to store that object's handle for later (the handle still exists, but if you create another new object, LNewObj() will point to the latest created object).
  22. One other thing, which I know can be confusing, is that some functions that create objects return handles, and some don’t. vs.Rect(), for example, does not return a handle, so you have to call vs.LNewObj() to retrieve the handle. That will always return the handle to the last object created. Other functions like MakePolygon() will return a handle. You just have to consult the function reference to know when you need to use LNewObj
  23. You might have to be more specific, as you have a working code snippet above. You seem to be asking about how to use handles for the duration of your script. In your example, h and j are handles, and you can use them as many times as you like for any function that asks for a handle. You seem to be creating a plug-in object. Every time a plug-in draws, it recreates the objects, so storing any identifier between runs doesn’t really make sense. Variables can’t have a space in the name, so let’s call it Client_1 vs.SetFillBack( Client_1, 255) Client_1 is the variable holding the handle to the rectangle you created. This is not a simple question to answer. Storing names or UUIDs is only necessary if you want to do things like link two plug-in objects together. You would have to describe exactly what your are trying to do. If you’re just trying to refer to objects within the same script none of this is necessary. If you did want to retrieve the UUID of the rectangle and store it to a database field, you would call: rectangleUUID = vs.GetObjectUuid(Client_1) Here’s a simple script using a handle #get the handle of the first selected drawing object and store it to a variable, h h = vs.FSActLayer() #Move the object 6 units to the right vs.HMove( h, 6, 0 ) #Change the object’s line color vs.SetPenFore( h, 42 ) For the duration of the script, h will point to that selected object until you either delete the object or assign h to another object via a function that returns a handle. If you are confused about the concept of variables and scope in general, you can try starting here: https://www.w3schools.com/python/python_scope.asp
  24. @FranAJA Again, I think you are over-thinking things. Handles are how Vectorworks tracks every element the drawing, and as such, every object already has a handle. The handle gets assigned to each object read from the saved file into memory and to every new object you create. You never have to "give" an object a handle -- you can only query Vectorworks to tell you the handle for the object you want. I think this is what is confusing you. The handle is the memory address where you can find the object. All the functions that return a handle aren't creating the handle, they are helping you find a handle that already exists. Functions that require a handle need to know where to find that object in memory. vs.LNewObj() is the equivalent of "What is the memory address of the handle I just created" Even though each object has a unique handle, because it is a memory address, you would never want to store the value of the handle anywhere, as it will change every time you load the file. ### Here's my analogy. Imagine that the Vectorworks drawing is a crowded bakery, and the handle is the number each customer takes as they enter. The numbers are all unique, but even if a group of regular customers returns to the bakery every day, their numbers will be different. We have a lot of ways we can find out which customer has each number. We can ask the first person or last person in line what number they have. Asking the last person is the equivalent to vs.LNewObj(). We can point at a customer and ask them what their ticket number is. This is similar to vs.FSActLayer(), which gives us the first selected object on the active layer. If we ask each customer to also put their name on a list as they enter, we can call out their name and ask their number. This is the equivalent of vs.GetObject(). Of course, if the customer doesn't add their name, we can't use the list of names to find their ticket number. Objects in Vectorworks can, but are not required to have names. We can also require each customer scan their government ID as they take a number, and use that list to ask the group what ticket number matches an ID. This is the equivalent of vs.GetObjectByUuid(). Another thing we can do is ask all the customers with red shirts what their ticket numbers are. This would be the equivalent of criteria functions that return handles. Finally, if a customer leaves the bakery without being served, and gives their number to a new customer walking in, that ticket number now refers to a new customer. This is equivalent to deleting an object and creating a new one, and an example of why storing handles as data is never a good idea. HTH
  25. You may be over thinking it. The handle is just an object identifier you pass to functions — it doesn’t get called. Your issue is that VW uses 16 bit color values: https://developer.vectorworks.net/index.php/VS:SetFillFore, so 256 will be a negligible tint.
×
×
  • Create New...