ETO Forms + DisplayConduit = Grasshopper-like Functionality in Python

I want to manipulate geometry in Rhino from ETO forms with sliders using python. I can kind of do it, but the geometry looks very choppy as it updates and updating is only truly possible in wireframe mode. I searched for “History” in the RhinoCommon site and found ReplayHistoryResult. And then I found a thread mentioning it.

I thnk ReplayHistoryResult is what I’m looking for. Is it? But, if it is, I can’t figure out how to use it, and I was hoping someone could point me to a tutorial or some sample code showing how to use it.

Here is a sample code I’ve made that has a slider that adjusts a radius of a circle, offsets it and lofts a surface between the two curves. I can scale the first circle (scaling and moving work fine for me). Currently, I delete the offset curve and the surface, then I recreate them. But I would love to see how ReplayHistoryResult would work for something like that. Even just the offset part (I assume it would be similar for the loft).

slider test.py (2.2 KB)

trying to have a look at your script , I ll get an error in line 68

dialog.DefaultButton cannot be null, you must specify a default OK button

Thanks for trying to look at it. I don’t know. I don’t get that on my computer (windows). I’ve never had to specify a default OK button.

I have remade it with an OK button and assigned it to “DefaultButton.” Hopefully that works for you.

slider test with ok button.py (2.5 KB)

ok - i am on a mac - now your script works.

there is a sample for a c# plug-in command with history:
check this topic

and

As soon as you add an Object to the document a user can edit your circle …

what s the exact usage-Scenario you re after ?
Maybe a Display Conduit will fit better for your needs - this will allow you to draw geometry to the screen to preview the result of your dialog - and as soon as the command / dialog is finished, add the final object to the document ?

3 Likes

Here’s a halo builder I’m working on in GH, which I would like to convert to ETO forms.

And here is my attempt at replicating it in an ETO form without GH. The ETO version is choppy and if I put the viewport in shaded mode (which I do at the end of the video), it keeps yanking the focus away from the form so I can only move the slider a small bit at a time.

And, yes, the Display Conduit looks promising…as long as it can be responsive to sliders. Whatever it is that GH is doing, that’s what I would like to do, but without GH (or GH can run in the background…as long as the user doesn’t have to interact with it)

Tom, it was indeed DisplayConduit that I needed. Specifically, I needed to override the DrawOverlay and CalculateBoundingBox functions. And it looks like it’s necessary to make objects with Rhino.Geometry instead of rhinoscriptsyntax (since rhinoscriptsyntax immediately adds objects to the document).

I’m so glad you saw my thread. I’ve been trying to figure this out for days…maybe weeks. But I didn’t know what to search for or even how to ask about it.

Here’s my sample script to test some sliders.

slider test with solver4.py (5.6 KB)

And here it is in action.

7 Likes

Hey, this is almost perfect for my needs. Only issue I’m having is I can only get it to work with python 2. Did you have a go at it with Python3? Here it throws ‘Object reference not set to an instance of an object.’ when you try to set the conduit.Enabled to True.

@Leonardo_Vassimon Make sure to call super().__init__() inside your conduit class initializer in python 3

2 Likes

(Edit: the script works for me as it was in Rhino8, which is surprising).

At the time I wrote this, I could never get my scripts to work in python3 AND python2, so I wrote only for python2. I still do this, but I have also figured out how to make my scripts work for both (or at least this has been my experience).

I’ve only ever been able to get Ehsan’s suggestion, which is what everyone says to do, to work for python3-only scripts. The solution for me - to have the same script work for both python2 and python3 - has been to insert a call to the super function in the def init but in a slightly different way.

By the way, Ehsan is, if I understand correctly, the developer of Rhino’s script editor.

class MyDialog(forms.Dialog):
    Radius = 1
    OffsetAmt = 0.5
    Angle = 0
    Conduit = None
    def __init__(self):
        # calling super so it works for both python2 and python3
        super(MyDialog, self).__init__()

@eirannejad , I’d love to hear your thoughts about the way I call super here. I couldn’t get the super().__init__() to work in Rhino7 AND Rhino8, and somewhere I stumbled on the super(MyDialog, self).__init__() format, and it seemed to work so I went with it.

And, oh, you’re putting it in the conduit class? I’ve put it in the dialog class (but even the original script was working for me with the python3 tag…so I don’t even really understand anymore)

OK. So, I’ve put my strange super call in both the dialog class and the conduit class, and it seems to work in both Rhino7 and Rhino8 (it was working before, but I mean nothing breaks). So, here’s the updated version of the script.

slider test with solver4b.py (5.7 KB)

But also, given the original script worked fine for me with both the python 2 and python 3 tags, in Rhino7 and Rhino8, I would consider making sure your Rhino is up-to-date (and, in case you don’t know, the update checker usually tells you your Rhino is up-to-date even if it isn’t…so you have to click on ‘check now’ to make sure)

1 Like

Thanks guys, that did it!

1 Like