Determining orientation of Boxes & Cylinders

Hi Giulio,

no, i’ve found that using events as described above cannot be used to reliably track changes in the transform of the object which holds a piece of geometry in it’s user dictionary.

Currently i treat all objects having stored geometry as untouchable, if the user wants to transform them, they have to unstore the stored geometry first or use a custom command i provide to perform a transform. Eg. if i write my own mirror command, i know the transform to mirror and then apply it to the object and it’s stored geometry. If this transform is undone, the stored geometry still lags behind and it’s transform is not updated unless i add custom undo events to my own transform command.

This is pretty limiting since i would have to rewrite all possible transform commands and then still cannot prevent users from transforming the object using rhino commands or just a single drag.

I am all ears if you have an idea to set it up so the stored geometry is updated “on the fly”. I have to make it work with V5 and V6 and on the Mac though.

_
c.

I looked into this briefly and it states that the geometry data is not cloned/duplicated. It means that, if the (exactly same) geometry is modified, then the instance in the dictionary is modified. Rhino always modifies by copying and modifying copies (so undo’s work, etc) plus there are caveats due to RhinoCommon being a .Net interface to C++ objects. But, in normal procedures, user modifications will not trigger instance changes to those geometries.

If you need to understand what modifications happen in transform commands, then you can hook into
http://developer.rhino3d.com/api/RhinoCommonWin/html/E_Rhino_RhinoDoc_BeforeTransformObjects.htm

@piac, thanks. As i wrote above, using events will not work as you cannot ensure that the event is running using python. I can set up the event no problem, and then listen to transforms, get the transform and apply it to the stored geometry. Using BeforeTransformObjects is not triggered on undoing the transform. So this requires another event, which again cannot be used as i never know if a user starts the event or not. Both events also need to get canceled once a new document is opened, so this requires another event to listen for that…

Imagine this scenario: I have a script, this does eg. a curve boolean to a curve and stores the original curve geometry into the curve which is the result of the curve boolean. So at any time, i can let the user start another script to restore the original curve which i had before the curve boolean. But, if someone transforms the resulting curve of the curve boolean, the stored curve is not transformed unless the events are running. If a user saves the file, restarts his system and justs opens the file again, the events (stored in sticky) are gone and where never started. In this moment the user either has to start the events to make transforms or first restore the stored geometry so he can transform and then do the curve boolean again.

Apart from above i’ve found some strange things happening with stored geometry in the user dictionary. As @stevebaer states above, the stored geometry seems to be referenced. If the curve gets duplicated, the stored geoemtry has the same adress in memory as the one stored in the original object. So transforming the stored geometry in the copied object also affects the stored geometry in the source object…

_
c.

You may want to elaborate more deeply to gain my agreement (of course you might well live without it), because I do not follow this… sorry.

You can register a Python function to an event and it will always be recalled even if the Python script has finished running. This is how events work… What you might be trying to say, though, is that this subject is quite big and a lot of things need to be taken into account. Of course Undo’s will make this more complicated, but there is also an Undo event, and it’s possible to register to that, too.

There is no Rhino user dictionary, or intermediate storage, or any similar facility, that will modify the geometry for you at this moment. It might get added at some point, but it’s not there. Right now the storage that modifies and transforms geometry for you is called Document and you already know how it works.

Of course, what seemed like a simple operation, “hiding” some geometry within other geometry, is now actually quite a bigger task, because adding it as “dead information” makes it lose some interesting possibility that you previously had. Arguably, this is the life of a programmer, always struggling and trying to make something complicated look simple.

Maybe you should restructure the original idea of hiding stuff altogether, if the Transform part is not working for you. These are my 2 cents, I doubt I can add much at this point.

@piac, thanks. i already use events extensively at the moment but i am a bit hesitant to add new ones to the current toolset. I guess you know how many different events are fired if you drag 10 objects from one position to another and then undo. Since all events are fired individually for each object (except the BeforeTransformObjects event) and i am working with groups, maybe even nested ones, it’s not easy to keep track of what happens.

The fact that Rhino does not print errors for delegates and that i have to put the events in scriptcontext entries to unregister them makes using events from python slightly painful. If a user wipes the sticky i loose the ability to unregister too.

I have not tried yet to store the links to the events elsewhere in the document maybe. Probably this all would be easier using a C# plugin which just registers the required events on startup. If the python script compiler would be able to support librarys and automatically load those librarys with the plugin on startup, this would be ideal, as i could then add my events there and do not have to keep track if they where started by the user or not. :slight_smile:

I am not really hiding the geometry, the user can at any time restore his curve as it was before a curve boolean and switch between the original and the booleaned state. There are other operations involved like collecting what to delete and transfering assigned user strings and object attributes to the stored geometry.

_
c.