michaelk Posted January 30, 2017 Share Posted January 30, 2017 (edited) Can someone walk me through the steps for creating a tool that creates a parametric object? I've been referencing the page on the developer site, but I feel like I'm missing a step. 1. Do I need to create the record format for the parameters? 2. At what point in the script do I call GetCustomObjectInfo(objectName, objectHand, recordHand, wallHand) ? 3. Am I correct that the parameter fields Pxxxxx are treated sort of like constants in the script? (so Pxxxxx := something is not cricket) I'd love to see an example of a script for a tool that draws a rectangle with the height and width as parameters. I've created the tool with what I thought would be a working script. I'm missing a step, running the tool just creates a rectangle, not a parametric object. 4. Do I also need to somehow create a .vso? Once again, a million thanks. mk Edited January 30, 2017 by michaelk typing mishaps Quote Link to comment
Pat Stanford Posted January 31, 2017 Share Posted January 31, 2017 OK, are you ready for this. It is quite complicated. I'm not sure that after the 10 years you have been scripting if you are ready for this yet. ;-) Go to the Plug-in Manager. Click the New button then choose the Rectangle Plug in. Name it and save it. Click the Edit script button and paste in the code below. Procedure MK_Rectangle; Begin Rect(0,0,PLineLength, PBoxWidth); End; Run(MK_Rectangle); Edit your workspace to add the new tool/object to a palette. It will probably be hiding in the Miscellaneous category. Select the new tool and do three clicks. One for the starting point, the second for the length of the first side, the third for the desired width of the box. You should now have your very own first PIO. To answer your other questions. 1. When you create a Rectangle object is automatically puts two parameters into the Definition, LineLength and BoxWidth. If you need more parameters you put them in though Edit Definition:Parameters. If you only need the two then you don't need to do anything with the parameter record. A point type object takes a single point. The Line type object takes 2 points. 2. Obviously you don't have to use it at all. You only need the GetCustomObjectInfo if you want a PIO that can react differently depending on where it is (inserted in a wall or not) or perhaps you are binding it to another object and need the handle of the instance so you can track it. You can put it in anywhere you need it, but usually fairly close to the top of the code and save the data into variables for future use. 3. Parameters are more like variables than constants. Variables that are also accessible through the OIP. They can be treated just like any other variable. The trick is that the only place you use the P is in the actual code. The parameter name is LineLength. If you don't set a custom name, that is the name that shows up in the OIP. When you want to reference the parameter in your script you must use PLineLength. The adding this line between the Begin and Rect lines in the script: PBoxWidth:=PBoxWidth*3; 4. If you use the standard Point, Line and Rect types, the VSO is created automatically. The Tool object is if you want to use a tool to do other things, including possibly inserting a VSO, in addition to inserting a VSO. Have fun playing. Ask again as you need help. Sample code always helps with understanding where you are at and where you are trying to go. Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 Don't you need to declare PLineLength and PboxWidth? Quote Link to comment
Pat Stanford Posted January 31, 2017 Share Posted January 31, 2017 Nope. As a Rectangle type PIO they are defined for you. Go to the Plug-in Manager, select the plug-in and click the Edit Definition button. Switch to the Parameters tab and you will see they are already there for you. When you run the PIO, the hidden behind the scenes code will populate those parameters with the lengths between the first and second and the second and third clicks and have that data all ready for you to use. Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 And just because I thought it would help me understand how things worked, I've been using RectangleN(FirstClick.x, FirstClick.y, V.x, V.y, Norm(V), PWidth_Test); and GetLine3D( p1X, p1Y, p1Z, p2X, p2Y, p2Z, TRUE); to isolate it down to only one parameter. My thinking was that I wanted to learn how to do a path object, so a linear seemed like a good place to start :-) Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 Thanks, Pat. Ever thought about annotating the developer pages? mk Quote Link to comment
Pat Stanford Posted January 31, 2017 Share Posted January 31, 2017 Yeah, I have thought about it. And every time I run screaming from the room ;-) Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 :-) Thanks, Pat. This is really helpful. My thrashing around got me close, but real examples are super helpful. I never would have figured out the part about not declaring the parameter variables. Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 OK!!! Your example works perfectly. My attempt causes VW to crash INSTANTLY :-) What am I doing wrong: I made a new tool > Linear. I have it an additional parameter (PWidth_Test) for the width. I give it a default of 12. When I run the tool I get the preference for the width value and then an instant crash. If I run it as a regular script giving PWidth_Test a value it runs great. Any ideas? mk DANGER: The script below when made into a tool causes an instant crash! Procedure JustARectangle; VAR PWidth_Test : REAL; p1X, p1Y, p2X, p2Y,p1Z, p2Z : REAL; V : VECTOR; FirstClick, SecondClick : POINT; Begin GetLine3D( p1X, p1Y, p1Z, p2X, p2Y, p2Z, TRUE); {Get Points} FirstClick.x := p1X; {Create Point Object from first click} FirstClick.y := p1Y; SecondClick.x := p2X; {Create Point Object from second click} SecondClick.y := p2Y; V.x := p2X - p1X; {Create Vector object from points} V.y := p2Y - p1Y; V.z := 0; RectangleN(FirstClick.x, FirstClick.y, V.x, V.y, Norm(V), PWidth_Test); End; Run(JustARectangle); Quote Link to comment
Pat Stanford Posted January 31, 2017 Share Posted January 31, 2017 When you make it into a PIO are you removing or commenting out the variables that are prefixed with P? Actually I just tested it. I commented out your PWidthTest and made it a parameter named just WidthTest. I ran the script and it bombed. I then hanged your p1X to X1, etc. I think you will have to change your standard nomenclature when working with PIOs. With everything renamed X1, Y2, etc., it does not crash. I don't think it does what you want, but it does not crash. If you want those to be Parameters you need to declare them as part of the PIO definition in the Parameters record, not in the VAR part of the script. Kind of sucks for debugging going back and forth, but that is what we got. Do you have a favorite programmers text editor? Something like BBEdit or TextWrangler? If so I will teach you another trick. Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 Of course! No more variables that start with P!!! Bummer, I use that line, GetLine3D( p1X, p1Y, p1Z, p2X, p2Y, p2Z, TRUE); , in about 25 scripts :-). I have BBEdit. Do you use $Include to run scripts? I've tested it, but, because so far I always just run plain scripts or make them into menu commands, it's easy enough to manage. Now that I'm hip to the ways of tools and parametric objects (thanks, Pat!) I may have to come up with a better code management system. Josh B showed me his amazing script management system a couple years ago. Made my head hurt. Can't wait for the trick! mk Quote Link to comment
Pat Stanford Posted January 31, 2017 Share Posted January 31, 2017 Yes. you definitely want to get comfortable with {$Include } if you are working on PIOs. Having to dig all the way into the Plug-in Manager for every change after every test would drive me batty. Make sure you have the Run Script in Developer Mode turned on in Vectorworks Preferences:Session tab. This used to be called compile scripts on each run or something like that. It will make sure that the modified Include is read in and used for each run so your changes are used not the cached code. The only thing I dislike about using an external editor is not having the very quick syntax check button that exists in the Script Editor. Quote Link to comment
michaelk Posted January 31, 2017 Author Share Posted January 31, 2017 5 minutes ago, Pat Stanford said: Yes. you definitely want to get comfortable with {$Include } if you are working on PIOs. Having to dig all the way into the Plug-in Manager for every change after every test would drive me batty. Yep. Check. Going batty. 5 minutes ago, Pat Stanford said: The only thing I dislike about using an external editor is not having the very quick syntax check button that exists in the Script Editor. Yes! I count on that button. It's why I still mostly use VS instead of Python. My scripts are still simple enough that the VS isn't much of a burden. Was $Include the trick? Or do you have another BBEdit trick? mk Quote Link to comment
Pat Stanford Posted January 31, 2017 Share Posted January 31, 2017 Include was the main trick, but I think C has (or had) a syntax highlighting module for BBEdit and VectorScript. That might help get the nesting right. I installed it a LOONG time ago and never really used it. If you ask C about it, see if you can share the current version. ;-) Quote Link to comment
michaelk Posted February 13, 2017 Author Share Posted February 13, 2017 OK Finally had a long flight to work on this again. Can you spot what I'm doing wrong? I made a plug in object (Linear). I gave parameters (starting with P!) for all the parameters of an OvalN OvalN( orginX,orginY :; directionX,directionY :; width :; height :); I've given all of them default values. I've tried both number type and dimension type. Doesn't matter. I get the same results. I've attached the script I'm using. It's better than the last attempt. I get the preferences box with all the default values. Then it fails. I've attached the error message I keep getting. It want's the variable to be a string instead of real. Is there a setting I have incorrect setting up the plug in? Thanks!! mk Oval.txt Quote Link to comment
Miguel Barrera Posted February 13, 2017 Share Posted February 13, 2017 A linear object does not have a width or a height and that is why you get the error that they are not defined. It only has an origin, a length and rotation. The origin and rotation you get from the symbol calls and the length is the parameter name "LineLength" or the constant PLINELENGTH. Quote Link to comment
michaelk Posted February 13, 2017 Author Share Posted February 13, 2017 Thanks Miguel. What I'm struggling to understand why can't I take the first click and direction from the linear object and use that in addition to unrelated parameters to make another object. In this case an oval. Can I only use parameters that the actual line derived from user clicks generates? mk Quote Link to comment
Pat Stanford Posted February 13, 2017 Share Posted February 13, 2017 Michael, Show us a screen shot of the parameters screen from the Plug-in Manager for your object. Pat Quote Link to comment
Miguel Barrera Posted February 13, 2017 Share Posted February 13, 2017 You have to keep in mind that plugins behave similar to symbols, that is, they have their own coordinate system. For example, if you want to create a line object at 30 degrees or any other angle, the code to generate this line will always be the following regardless of the angle. MoveTo(0.0); LineTo(PLINELENGTH,0); The line is drawn along the x-axis in the plugin coordinate and then transformed to the plugin origin and rotation. In the same way, if you wan to create an oval, you will need to calculate the width and height from the angle the plugin was drawn and then transform the geometry to the plugin coordinate system Quote Link to comment
JBenghiat Posted February 18, 2017 Share Posted February 18, 2017 Jumping in a little late here, but I think you actually have two functions of the plug-in happening at once, which is giving you the issues. We have our four types of Plug-In Objects: point, linear, box, and poly. All of these are bundled with an tool that collects each type's unique parameters. The tool doesn't need any extra coding, and indeed your code should not include any other user interaction. The exception would be if you have a button that collects user input, and that would only happen during the button event and never on insertion. Point objects collect an insertion point and rotation. Linear objects add collection of a line length. (You can see this when editing the parameters) Box objects add collection of a width and height. Poly objects collect a path, which gets stored in the plug-in's path group. If you need user interaction for the plug-in insertion that goes beyond this data collection, you need to write a separate Plug-In Tool that collects your points and then uses CreateCustomObjectN() to insert the object and SetRField() to set parameters. You can associate the tool with the plug-in, which mostly benefits actions like Create Similar Object. HTH, Josh Quote Link to comment
michaelk Posted February 18, 2017 Author Share Posted February 18, 2017 whoa. Can you give me an example? I'm trying to write a couple tools that use points on a path object. (It works now as a script when a line or polyline is selected.) So I've been using a line type tool as a test just to learn. So in the example above using RectangleN(); how would I make the width (last parameter) appear as a parameter in the OIP? mk Quote Link to comment
JBenghiat Posted February 19, 2017 Share Posted February 19, 2017 You need to create a Rectangular Object plug-in, and you will automatically have LineLength and BoxWidth as parameters. You can set a value for "Alternate Name" if you want them to appear differently in the OIP. For rectangular PIOs the insertion point is the center-left of the rectangle. Your oval script would be as follows: Procedure TestRectPIO; BEGIN Oval(0, -PBoxWidth/2, PLineLength, PBoxWidth/2); END; Run(TestRectPIO); Working with a path based PIO is slightly more complicated. Usually, you iterate over the poly vertices in the path stored in the path group. The origin of the PIO is the first click of the path. -Josh Quote Link to comment
michaelk Posted February 19, 2017 Author Share Posted February 19, 2017 Got it. But just for my understanding: What if I want user input (after a default value is used) for one of the parameters? Like the width of of the oval. mk Quote Link to comment
JBenghiat Posted February 19, 2017 Share Posted February 19, 2017 The rectangular PIO requires three clicks on creation: insertion / width start, width end, height. The insertion tool has two modes, the first mode drawing from the center of the box, which is the origin of the object. I'm actually having trouble with the second mode in my version of 2017, which looks like a bug. You can edit the width and height at any time in the OIP. -Josh Quote Link to comment
michaelk Posted February 19, 2017 Author Share Posted February 19, 2017 I can edit it. But can I set a default? In my original example I wanted to use a line type tool to define the length and a default value for the width. mk Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.