[Python] Live Script

Can I make a script/command that does calculations all the time until stopped?
e.g. pops up a terminal and shows the results of calculations based on some selected object in Rhino in real-time?

@nathanletwory,

Will rhino-inside help me to implement this behavior?

I think you just need to implement a conduit.

The only thing this word reminds me of is Mass Effect. :smiley:

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Display_DisplayPipeline_DrawBitmap.htm

Here is an example how you can setup a conduit

Edit: also you could set up an event handler that listens to a selection event.

https://developer.rhino3d.com/api/RhinoCommon/html/E_Rhino_RhinoDoc_SelectObjects.htm

You don’t have to set up a selection event handler though, as you have access to the RhinoDoc in the conduit draw functions through the event args.

This example makes Rhino lock itself, changes the cursor to swallow-tail-looking-one then crashes Rhino.

Edit: Hi @ivelin.peychev,

Calculations should never be done in a conduit function. From your initial post, i do not really get what you’re trying to do but i would asume you can set up the terminal in a seperate modeless form which is called and does the calculation eg. when an event (select object, idle etc) occurs.
_
c.

It is from the rhino common api documentation.

It was a generic question. I have two ideas:

  • pop-up a terminal that shows some calculation in real-time. e.g. show coordinates of an object, or show the area of a surface while you move the control points
  • “pop” another process under rhino that triggers redraw and makes two points always coincide. You move one of them and the second one follows as if they were grouped

Hi @ivelin.peychev, i see now. The loops are in the __init__ function so they are only run once and not in the conduit drawing function. But i do not get the lockup, instead nothing is drawn in V6. The example draws the bitmap in V5.

_
c.

The lockup could be due to me clicking around a lot :wink:

Hi @ivelin.peychev, i can get it to draw in V6 if i change this line:

e.Display.DrawBitmap(self.display_bitmap, 50, 50, System.Drawing.Color.Red)

to this:

e.Display.DrawBitmap(self.display_bitmap, 50, 50)

It runs fast but i think it is a bug in V6, it should accept the 4th argument which is the mask color.

Back to your questions, if the calculations are not intense and you want to redraw eg. based on a point or mouse cursor position, you might look at this example which is using a dynamic conduit in a point picker.

_
c.

1 Like

For this particular case the easiest way would be to use the built in annotation text field function, which does not require any script. Eg. to show the area of a surface while editing its control points, try this:

1.Create your surface
2.Create a _Text object, click on the fx button
3.Highlight “Area” on the left then click Select Object and pick the surface
4.Close the text field dialog with OK

Is this what you’ve meant with calculations in a terminal ?
_
c.

No, I meant actual (Win)CommandPrompt terminal.
See, if you are working on a big object you can’t focus on that dynamic area text object while you’re editing.
I need it in another window separate from whatever is displayed on Rhino viewports and not affecting rhino command terminal.

The most close example is when you use Grasshopper and you use right-click Publish to Remote Panel.
Only that I don’t want to use Grasshopper for this only python. Also, grasshopper has a quite noticeable lag I want to avoid.

Ok, while a dynamic conduit runs, eg. using the GetPoint prompt you want to display eg. a point coordinate constantly and update whenever the point coordinate has changed. The display can either be shown in a regular conduit or a seperate form window which is modeless so it does not block Rhino.

For a point coordinate displayed in a conduit, you could set it up like in below example. Of course you’ll need a way to cancel the conduit (or form) and the idle event in some way. I’ve done this by just re-running the script. If you look in the code of the idle event, it is communicating with the conduit. The same could be done by using a form, which does not block Rhino.

IvelinExample.py (2.3 KB)

_
c.

1 Like

Hmm, I’m beginning to think a conduit is a GUI transparent thin film “glued” to the camera. Such that it doesn’t follow the object’s rotation but rather always displayed the same way for that specific camera. :thinking: Kinda like Unity’s UI Canvas.

Thanks for the exmple @clement.
I need to figure out how to pop it up in a separate window. I do not think using ETO is what I want, I want to pass the data to Python and the calculations to happen using python and displayed on that terminal.

Yes, like sunglasses :sunglasses: This page explains the concept very good. You can display things in 2D and 3D of course.

Just create an empty ETO or WinForm with a single text label. Note that when you Show the form, so it does not block Rhino, it is completely released from your code. So you need to put the form instance in a sticky value, in order to get hold of it inside the idle event. The concept is identical with using a conduit.

This is going to be tricky. Rhino related calculations happen in the scope of IronPython which is run by Rhino.

_
c.

I was thinking this could be done with rhino3dm and compute.rhino3dm modules. Although, I don’t know how to pass data directly. Either I have to cpickle or use sticky. But I don’t think sticky will be accessible to cPython.

rhino3dm and compute.rhino3dm modules are a nice thing. Now with rhinoinside it all got very confusing CPython+Ironpython+RhinoCommon :crazy_face:

Another way could probably be using subprocess running a subprocess of ironpython engine from the script :crossed_fingers: (hoping) it won’t lock Rhino this way.

It’s pythons all the way down!

http://mythologian.net/wp-content/uploads/2013/10/Ouroboros-dragon-serpent-snake-symbol.jpg)

1 Like