PointPicker and history script/API questions

Next
 From:  Larry Fahnoe (FAHNOE)
10917.1 
First, is there a way to constrain the pointpicker to only allow picking an object's corner or end points?

Using pointpicker.restrictToObject( rect) at least constrains to the rectangle, but non-corner points can be picked by mistake.

Second, my script starts out making a rectangle and then “edits” it by first separating the edges and then rotating one of the edges (similar to opening the lid of a box). Oddly after the script exits, an undo will expose the rotated edge in its original position. I tried using updateWithHistory=false before the rotate or deleteHistoryData() after the rotate but neither changes this behavior. How do I avoid undo exposing this intermediate stage of the script? Seems like it is a history issue, but I’m not controlling it correctly.

Using the attached script, please click the Door checkbox to demonstrate these issues.

--Larry
Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10917.2 In reply to 10917.1 
Hi Larry,

re:
> First, is there a way to constrain the pointpicker to only allow picking an object's corner or end points?
>
> Using pointpicker.restrictToObject( rect) at least constrains to the rectangle, but non-corner points can be picked by mistake.

You would need to use a custom snap function on the pointpicker for that. But it might be difficult to get it working entirely from script right now.

The snap function itself is a script function that takes a pointpicker as a function argument, like:
  function SnapFunc( pointpicker )
  {
    ...
  }

You enable the snap function on the pointpicker by calling pointpicker.addSnapFunc( SnapFunc );

The pointpicker will then call the snap function at the beginning of the pointpick calculation and if the snap function has provided a snap point by calling pointpicker.setSnapFuncPoint( pt_xyz, 'label' ); then it will use that snap point.

You can also set pointpicker.onlyUseSnapFunc = true; so that it won't fall back to a regular point pick if there is no snap point provided.

The tricky part is it is up to the snap function to determine which snap point is targeted using the screen coordinates of the mouse.
The hit testing functions for helping with that are not currently exposed to script, nor is the screen coordinates. I'll see about adding those in.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
10917.3 In reply to 10917.2 
Hi Michael,

Thanks for the explanation. It sounds like it might be more trouble than its worth though and I can easily trap for the case where the user didn’t click on the corner points.

But I'm curious and I’m thinking that I don’t quite understand the SnapFunc, specifically how to pass the points into it? This should illustrate my confusion:

code:
function SnapFunc( pointpicker)
{
    // how do the corners get passed in?
    for ( i = 0; i < corners.length; i++)
    {
        pointpicker.setSnapFuncPoint( corners[ i], 'corner ' + i );
    }
}

[...]

    // code that would set up and call the pointpicker...

    // Find the longest line (width) and corners
    var width = 0;
    var corners = new Array;
    for ( var i = 0; i < lines.length; i++)
    {
        var line = lines.item( i);
        var length = round( line.getLength());
        if ( length >= width)
        {
            width = length;
            corners.push( line.getStartPt());
            corners.push( line.getEndPt());
        }
    }

    pointpicker.addSnapFunc( SnapFunc );
                                     ^^^^^^^^^^
                                     Do corners get passed in here?


--Larry
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10917.4 In reply to 10917.3 
Hi Larry, you'd need to put the corners in global variables so your snap function could access them.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
10917.5 In reply to 10917.4 
Got it, thanks Michael.

> The tricky part is it is up to the snap function to determine which snap point is targeted using the screen coordinates of the mouse.
> The hit testing functions for helping with that are not currently exposed to script, nor is the screen coordinates. I'll see about adding those in.

Yes, with only limited testing of the SnapFunc above, the corner points don't end up being "sensitive" enough: the clicks don't reliably trigger the intended corner.

No worries, I'll go back to using pointpicker.restrictToObject( rect).

--Larry

EDITED: 15 Dec 2022 by FAHNOE

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10917.6 In reply to 10917.1 
Hi Larry,

re:
> Oddly after the script exits, an undo will expose the rotated edge in its original position.

I'm not reproducing that over here.

When I run 2dopening and pick some points I get a result like this:


And when I then do an undo, I get this:


- Michael

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
10917.7 In reply to 10917.6 
Hi Michael,

Yes, that's the intended behavior. Please click on the Door checkbox to expose the unexpected undo behavior.

BTW, the purpose of the script is to add simple 2D window and door symbols to an architectural floorplan, so the typical use would be on a model like the attached.

--Larry

EDITED: 26 Dec 2022 by FAHNOE

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
10917.8 In reply to 10917.7 
With continued development of this script the unexpected undo behavior went away, though I'm still not clear on its cause nor just what cleared it up. A minor mystery, most likely due to a lack of understanding on my part.

--Larry
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10917.9 In reply to 10917.8 
Hi Larry,

re:
> A minor mystery, most likely due to a lack of understanding on my part.

I think there's a bug somewhere in the automatic undo generation system when some intermediate objects are both created and deleted within the same command.

If you run into it again you might try using factory.calculate() instead of factory.commit(), like:

var object_list_result = factory.calculate();

The difference is that factory.calculate() creates "loose objects", meaning the objects have not been added into the geometry database automatically. If you're then using that geometry for internal construction and it's not supposed to be shown by itself to the user you don't need to have it added into the geometry database.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
 From:  Larry Fahnoe (FAHNOE)
10917.10 In reply to 10917.9 
Thanks Michael, will keep that in mind.

--Larry
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All