Problem scripting a 'trim' operation
 1-17  18-37  38

Previous
Next
 From:  Michael Gibson
3541.18 In reply to 3541.17 
Hi Dave, so what kind of ghost objects are you seeing with the line, is it an extra point object?

Are you possibly calling update() at some time before you call calculate() ?

If so then you probably should leave out the call to update() because that's meant to be used for an interactive command, so things like UI objects are created during that call, in the case of Line there is a point object created to mark the beginning point.

If you do call update(), then you could call cancel() to erase the interactive stuff like the UI geometry though.

But if you call calculate() only and avoid calling update() the UI geometry should be suppressed.


But it sounds like you may be currently getting the regular "interactive mode" stuff created by a call to update() - if you just want to generate output objects directly and have them returned to your script then call calculate() _instead_ of calling update().


- 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:  Dave Morrill (DMORRILL)
3541.19 In reply to 3541.18 
> Hi Dave, so what kind of ghost objects are you seeing with the line, is it an extra point object?

I never use 'update' calls in my code. Previously, when I was still seeing the 'ghost' objects, the only factory call I was using was 'calculate'. Now, in addition to 'calculate', I also call 'cancel' after the call to 'calculate', which seems to eliminate the 'ghost' objects when creating things like lines.

What I mean by a 'ghost' object is a copy of a created object (like a line) that was never explicitly added to the geometry database (i.e. because only 'calculate' was used to create it), but which nevertheless shows up in the viewport.

The situation is usually as follows:

- Run a script that creates a line (using 'calculate'), but which never gets added to the geometry database.
- The viewport looks OK at this point (i.e. the created line is not visible, since it was not added to the geometry database).
- Now, using the UI (not a script), start an interactive operation, like creating another line. Click with the mouse to set the line's start point.
- At this point, the original line (created by the script in step 1), appears in all viewports.
- Complete the drawing of the interactive line by clicking to set the end point.
- At this point, the interactively created line is visible, and the 'ghost' line from step 1 disappears, never to be seen again.

Another attribute of 'ghost' geometry is that it can never be selected by clicking (no pre-selection highlight, no selection highlight), but can be selected by box dragging (normal pre-selection highlight and final selection highlight). However, once selected, the object cannot be moved, deleted, etc., although it does eventually go away, as described in the preceding series of steps. You would see this behavior immediately after running the script, when attempting to click or drag select on the empty space in the viewport where the created line should be.

So it looks like there are some circumstances where 'calculate' does put created geometry into a state where it may be displayed for a short while (usually during the extent of the next command). As I mentioned, placing a 'cancel' call after the call to 'calculate' does seem to clear up the problem (in most cases, although 'reset' seems to do a better job when using the 'trim' factory, as I mentioned before).

At this point, with the 'reset' (for 'trim') and 'cancel' (for everything else) calls in place, I have not seen any 'ghost' geometry at all. The only anomalous behavior I am seeing at this point is that when running a fairly complex script that creates lots of intermediate geometry, using a mixture of different factory operations, MoI sometimes ends up in a state that seems like it is waiting for a command to end. That is, the viewports all look fine, and may contain correctly selected objects (created by the script), but I cannot deselect existing objects or select new ones. Pressing 'enter' or 'esc' seems to exit whatever state is in in, and things are back to normal after that. I'm still investigating this, and it may be due to some other error in my script...

- Dave Morrill
  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:  Dave Morrill (DMORRILL)
3541.20 In reply to 3541.19 
Michael,

Let me know if you want me to send you some Javascript code that can reproduce the 'ghost' object behavior. But I think you can get the behavior I described by writing a simple script that:

- Creates a 'line' factory object and sets all its inputs.
- Run the 'calculate' method on the factory object.

At that point I think you should be able to see the 'ghost' line behavior I described...

- Dave Morrill
  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:  Dave Morrill (DMORRILL)
3541.21 In reply to 3541.20 
Just another update...

With the recent addition of the 'reset'/'cancel' calls, I'm finding my procedural scripting API is much more robust and stable now. In fact, I'm no longer seeing the last problem I mentioned, about MoI ending up in the strange 'command-like' state after running a script. As a result, I have been able to iterate really quickly now while developing my current script (since like I mentioned on another thread, I dynamically load my scripts while MoI is running).

So this is mainly a "food for thought" post for Michael...

Using my procedural API, I am finding that writing scripts many times is more like functional programming than standard procedural programming. That is, scripts tend not to have any explicit loops, but operate on lists of objects. So in many cases, ObjectList's are the "lingua franca" of the scripting world. Of course, at the lower levels of the procedural library, there are routines that must operate on the contents of the lists. In many cases, the operation that must be performed is to merge two lists into one. This can potentially create a performance bottleneck, since (as far as I know) the only way to do this is via the 'addObject' method on an ObjectList. Since Javascript (in IE) is not all that fast, I would propose adding an 'addObjects' method to ObjectList, which would add all of the objects in its ObjectList argument to the receiving ObjectList (similar to the 'addObjects' method on the GeometryDatabase object). Presumably this would be trivial to implement, but would better leverage the performance advantage of C++ over Javascript for this common scripting operation.

Again, this is just a suggestion, so feel free to take it or leave it :-)

- Dave Morrill
  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
3541.22 In reply to 3541.19 
Hi Dave,

> I never use 'update' calls in my code.

Do you call .commit() though? commit() implicitly calls update() if there has not been an update done once already.

The same thing goes for commit() as update() - avoid calling that interactive mode stuff if you intend to use calculate().

The 'ghost' effect that you're describing comes from the object having the "no hit test" flag set on it - that means that it does not go into the regular hit test map so it cannot be targeted for snaps or click selections. That's to avoid things like drawing a line and having the next point you pick getting snapped on to that same line that is in the geometry database from the previous mouse move.


- 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:  Michael Gibson
3541.23 In reply to 3541.21 
Hi Dave, the "addObjects" method sounds like a good idea, and it should be easy to add in once I am back in development mode when v3 starts up.

It definitely helps for speed to implement as much on the C++ side as possible so that the script is more directing and gluing things together rather than doing a lot of work itself.

- 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:  Dave Morrill (DMORRILL)
3541.24 In reply to 3541.22 
Michael,

> Do you call .commit() though? commit() implicitly calls update() if there has not been an update done once already.

No, the only calls I am making on a factory object are: setInput, calculate and cancel (for most operations), and setInput, generateFragments, calculate and reset (for 'trim' operations). I verified this by grepping my procedural library for 'commit' or 'update', and did not find any matches anywhere.

BTW, I spoke too soon in my last post :-(. I am still seeing the weird post-script state where I have to hit enter or esc to get back to normal. The behavior I am seeing makes it look like it is a 'trim' operation side effect...

Upon script completion, a number of points I created are (correctly) in the selected state (i.e. highlighted). If I mouse around, I can unselect/select any of these points (which are all trim fragment endpoints), but cannot select any other geometry in the scene. Once I press enter, then everything is fine again (i.e. I can select any geometry in the scene). So it looks like 'trim' has somehow left MoI in a trim related picking state. I'll play around with 'cancel' and other operations on the factory some more to see if I can 'cure' this)...

- Dave Morrill
  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:  Dave Morrill (DMORRILL)
3541.25 In reply to 3541.23 
> Hi Dave, the "addObjects" method sounds like a good idea, and it should be easy
> to add in once I am back in development mode when v3 starts up.

OK, great!

> It definitely helps for speed to implement as much on the C++ side as possible so
> that the script is more directing and gluing things together rather than doing a lot of work itself.

100% agreement on that. In fact, I was one of the pioneers in the use of 'glue' languages when I created the GLUE (General Language for Unifying Environments) language in 1987, back when I was with IBM Research :-)

- Dave Morrill
  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
3541.26 In reply to 3541.24 
Hi Dave, so it would probably help if you could make that line script example that leaves a ghost object, so I could run it over here and check it out.

For Trim, I guess it looks like the call to generate fragments will cause UI objects to be created, for things like the endpoints of curve fragments.

The automatic setting of the disable UI geometry flag happens inside of the call to calculate(), so that's why they are not being suppressed automatically, because the fragment generation thing happens before that.

Try calling factory.disableUIGeometry(); before the generate fragments call, that should manually set the flag that disables UI geometry so I think that would then prevent those extra things from being created.

- 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:  Michael Gibson
3541.27 In reply to 3541.25 
I never knew there was a glue language actually called GLUE ! :)

- 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:  Dave Morrill (DMORRILL)
3541.28 In reply to 3541.26 
Michael,

> Try calling factory.disableUIGeometry(); before the generate fragments call,
> that should manually set the flag that disables UI geometry so I think that
> would then prevent those extra things from being created.

I tried modifying the 'trim' function to be:
var trimmer = factory( 'trim', as_list( objects ), as_list( cutters ), 
                       object_list(), 'remove', arg( extend_lines, false ), 
                       arg( project_intersections, true ) );
trimmer.disableUIGeometry();
var result = trimmer.generateFragments();
var result = trimmer.calculate();
trimmer.reset();

but it did not have any effect on the problem. Note that the geometry I see all seems correct and expected. The problem is simply that the UI seems to be 'stuck' in some kind of picking mode at the end of the script. Pressing esc seems to end the picking mode and return everything to normal.

EDITED: 18 May 2010 by DMORRILL

  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:  Dave Morrill (DMORRILL)
3541.29 In reply to 3541.26 
Michael,

> Hi Dave, so it would probably help if you could make that line script example
> that leaves a ghost object, so I could run it over here and check it out.

Here's a short script that shows the problem:
var p1 = moi.vectorMath.createPoint(  0.0, 0.0, 0.0 );
var p2 = moi.vectorMath.createPoint( 10.0, 0.0, 0.0 );
var f  = moi.command.createFactory( 'line' );
f.setInput( 0, p1 );
f.setInput( 1, p2 );
var result = f.calculate();

- Run the script (the viewport should still be empty afterwards).
- Start a new line using the normal MoI UI interface. Click to set the first point somewhere.
- After the click, the line created by the script should appear in the viewport.
- Click to set the second line point.
- The script 'ghost' line should now disappear and never appear again (unless you re-run the script).

Hope that helps...

- Dave Morrill
  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
3541.30 In reply to 3541.29 
Hi Dave, I see what you mean.

So there is actually an .update() being called by the system on your factory there.

Right now when a factory is created, it goes on the "active factory list", and in the pointpicker, if any binding was applied that set factory input value, update is then called on all factories in the active factory list.

That probably needs an overhaul so that it only calls update on factories that actually had an input modified. Also maybe there should be a flag that you could pass to createFactory to avoid it getting placed on the active factory list, or maybe just calling calculate() by itself should take it off the active list.

That active list is again something used for interactive commands, so that factories that are "running" are kept track of so that they can be canceled if a command is forced to exit.

The factory is removed from the active list is commit() or cancel() is called on it, so that's why calling cancel() fixes that up. You'll need to call cancel() for now to avoid unwanted updates on that factory later on.

- Michael

EDITED: 18 May 2010 by MICHAEL GIBSON

  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
3541.31 In reply to 3541.29 
And when a command ends, part of the cleanup process is that the active factory list is purged, with cancel() called on any that were still in it, that's why it stops happening after you have run some command.

That's one of the things that commit() does to make the effect of an interactive command stick around, it removes it from the active factory list so that it will not have cancel called on it when the running factories are cleared.

- 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:  Dave Morrill (DMORRILL)
3541.32 In reply to 3541.30 
Michael,

> Hi Dave, I see what you mean.

Great, at least you're aware of, and tracking, the issue now. For now, calling 'cancel' is not a problem, since it is hidden within my procedural framework. But obviously it would be good if at some future point you could fix the issue.

As I said before, there also appears to be a somewhat more annoying related issue, presumably with the trim factory, whereby the MoI UI ends up in some kind of picking mode at the end of a script.

In the script I'm working on now, I do many trim operations, all of which seem to execute correctly and produce correct results. But at the end of the script, the MoI UI is in this weird picking mode. The only geometry that can be selected or deselected are visible trim points. If I hit 'esc' then the UI resumes normal operation. No combination of adding calls to disableUpdate, disableUIGeometry, reset or cancel to the trim factory code seem to fix the problem.

I've modified (as a test) the script to not add any of the trim points it creates to the geometry database. So at the end of the script, all I see is the original geometry (since the trim points are the only things that the script is creating). I am still in the weird picking mode, but now there is nothing that can be selected or unselected, since none of the trim points I created were added to the geometry database. However, 'esc' still allows MoI to resume normal operation.

This obviously is a more serious problem, since as of now there is no work-around (other than telling the user to press 'esc' after the script finishes :-) ).

Also, I've noticed that some factories alter the selection setting of other, unrelated geometry. Can you confirm this? I noticed it when I originally wrote my script to set selection 'on' for various created objects as the script iterated its way along. At the end of the script, only the last set of selected objects were still selected; the rest had become deselected (presumably by some factories that had run after they were created and selected). When I modified the script to select all of the objects at the end, then it all worked OK. This is not necessarily a bug, but perhaps a script design consideration, so it would be good to know if that is the expected behavior...

- Dave Morrill
  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
3541.33 In reply to 3541.32 
Hi Dave,

> As I said before, there also appears to be a somewhat
> more annoying related issue, presumably with the trim
> factory, whereby the MoI UI ends up in some kind of picking
> mode at the end of a script.

That's probably another side effect from the Trim factory being currently designed to work with the interactive command.

When you call generateFragments(), it sets a property called "Selection lock" on all the other objects in the geometry database. Selection lock prevents objects from having their selection changed - that helps with the Trim command because it wants you to select some of the fragments that were generated and not other objects in the model.

Selection lock is automatically cleared from everything in the cleanup step that happens when a command ends. That step is not happening with your procedural calls since you are not using them within the "command" framework.

Try something like geometryDatabase.getObjects().unlockSelection(); although that will only remove it from top-level objects, you may need to do something like put all objects and all their sub-objects also into a object list and then call .unlockSelection() on that big object list.


> Also, I've noticed that some factories alter the selection
> setting of other, unrelated geometry. Can you confirm this?

Yeah, this is what is happening in Trim. It looks like the only other one that I can find with a quick look that would also do it is Fillet when you are filleting the corners of a single curve, there is a vertex selection step there and that works similar to the fragment selection in Trim.


These various things you're running into are basically side effects from things being primarily set up and tested for use with the regular interactive commands.


- 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:  Dave Morrill (DMORRILL)
3541.34 In reply to 3541.33 
Michael,

> Try something like geometryDatabase.getObjects().unlockSelection(); although
> that will only remove it from top-level objects, you may need to do something
> like put all objects and all their sub-objects also into a object list and then
> call .unlockSelection() on that big object list.

OK, that seemed to do the trick! What I've done for now is to put that code in my script execution framework so that it gets called after every script executes. I did this since it seemed like it might be potentially kind of expensive to do after every trim operation (within a script), especially if it needs to be done on the complete object graph closure. Right now I'm only doing it on the top-level objects at the end of the script. At least now, if I still see weird behavior in the future, I'll know where to look. So thanks for the explanation!

> These various things you're running into are basically side effects from things
> being primarily set up and tested for use with the regular interactive commands.

Sure, understandably so. Another question is though, do you think you might be willing to target the clean-up of some or all of these script-level behavioral issues as a V3 work item? It may not be necessary, since so far the problems I've run into mostly all have viable work-arounds, but it would obviously help simplify a script writers life to remove some of the bumps in the road. Just something to think about.

Thanks again for all your help...

- Dave Morrill
  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
3541.35 In reply to 3541.34 
Hi Dave, I'm glad that you've got things working now!

> Another question is though, do you think you might
> be willing to target the clean-up of some or all of these
> script-level behavioral issues as a V3 work item?

Certainly! I've actually already added several of the things mentioned here on my todo list.

Also maybe during v3 we can discuss setting up a more procedurally friendly geometry creation API directly within MoI, like a function call based one like you have set up, rather than having to rely on the factory system for simple things like creating lines, etc...

- 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:  Dave Morrill (DMORRILL)
3541.36 In reply to 3541.35 
Michael,

> Certainly! I've actually already added several of the things mentioned here on my todo list.

Great!

> Also maybe during v3 we can discuss setting up a more procedurally friendly geometry creation
> API directly within MoI, like a function call based one like you have set up, rather than having
> to rely on the factory system for simple things like creating lines, etc...

Awesome! I'll start making a shopping list ;-) Actually, based on all the scripting work I've done so far, I've been coming up with a number of follow-on projects which, once you have your V3 hat on, might be worth kicking around.

Finally, is the moi.idl file linked to from the scripting wiki page up to date? I've been trying to package up a beta version of some of the scripting extensions I've been working on, and would like to add my MoI API documentation to the package. Since V2 is code complete, I'd like to make sure I've got all the API included, even if it doesn't all have a write up yet (last time I checked, it was about 70% documented).

The funny thing is, I've been using my API documentation a lot while writing scripts, and I've been reading the documentation I wrote previously as if it were all the unvarnished truth. LOL! Well, at least I haven't run across anything I wrote so far that is completely wrong...

- Dave Morrill
  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
3541.37 In reply to 3541.36 
Hi Dave,

> Finally, is the moi.idl file linked to from the scripting
> wiki page up to date?

No, it wasn't, it was missing a few newer things like the orientation picker object, and some various new options.

I've uploaded the final v2 version and updated the link on scripting wiki page now.

- 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
 

Reply to All Reply to All

 

 
Show messages:  1-17  18-37  38