Jump to content
Developer Wiki and Function Reference Links ×

Tool help


michaelk

Recommended Posts

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 by michaelk
typing mishaps
Link to comment

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.

Link to comment

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.

Link to comment

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 :-)

 

 

Link to comment

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);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Link to comment

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.

Link to comment

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

Link to comment

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.

Link to comment
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

 

Link to comment
  • 2 weeks later...

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

Screen Shot 2017-02-12 at 6.30.34 PM.png

Link to comment

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

Link to comment

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

Link to comment

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

Link to comment

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

Link to comment

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

Link to comment

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

Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...