[RhinoCommon & Python] : How to use it?


#1

Hi,
I now start with rhino. I would like to write a python script outside Rhino Script Editor.
If I understand correctly, to interface with Rhino, I have to use the dll RhinoCommon.

To this end, when I use the code below, but I get the following error in scriptcontext.py file

import sys
import clr
import System



def AddAnnotationText():
    pt = Rhino.Geometry.Point3d(10, 0, 0)
    text = "Hello RhinoCommon"
    height = 2.0
    font = "Arial"
    plane = scriptcontext.doc.Views.ActiveView.ActiveViewport.ConstructionPlane()
    plane.Origin = pt
    id = scriptcontext.doc.Objects.AddText(text, plane, height, font, False, False)
    if id!=System.Guid.Empty:
        scriptcontext.doc.Views.Redraw()
        return Rhino.Commands.Result.Success
    return Rhino.Commands.Result.Failure



def main():
    sys.path.append(r"C:\Program Files\Rhinoceros 5\System")
    clr.AddReference('RhinoCommon')


import Rhino
import scriptcontext
import System.Guid

AddAnnotationText()
pass

if __name__ == '__main__':
    main()

I use Python 2.7.

How should I do? Where can I find examples ?

Thanks,

Manu


(Giulio Piacentino) #2

Hi Manu

Python is generally intended to be used within Rhino, not to automate Rhino from the outside. This is more a technical limitation than anything having to do with a decision. Also, Rhino.Python is using IronPython, a .Net implementation of Python. This means that using RhinoCommon in CPython is even more complicated.

However, if your goal is to write .3dm files, there is a standalone library called Rhino3dmIo, which is encompassing a smaller range of functionality but allows reading and writing 3dm files from everywhere.

Does it make sense?
If it does not in your specific case, maybe we should try to discuss what you are trying to do first, and see if I or somebody else have some ideas.
Thanks,

Giulio

Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com


#3

Hi,

Thank for your reply.
In fact, I currently developping a small program in Python.
I wondered if it was possible to interface Rhino with my program in Python.
At first, I would just turn activate menu commands, and move, the camera…
That’s why, I tought to use the dll RhinoCommon.
I don’t understand why using RhinonCommon in Python is even more complicated?
In your opinion, Should I go through a layer of C++ to interface dll RhinoCommon ?

Thanks,

Manu


(Giulio Piacentino) #4

Hi Manu

can you just please elaborate a little on the work upon which you are about to embark?
This is the only way I think I will be able to assist.

Please, if you can, state what is the technical achievement you would like to get out of Rhino (e.g.: is it reading/writing .3dm files? Creating some complicated geometry automatically? Letting the use access Rhino’s UI/interface?)

Thank you,

Giulio

Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com


#5

Hi Giulio,

Sorry for my late response.

In fact, the idea would be to use a microcontroller, and plug in a joystick to control the functionality of Rhino.
Currently, I have a python application that interfaces with my microcontroller.

therefore, I would like to know if it is possible to attack your Python API.

Thanks,

Manu


#6

If your only goal is to be able to control rhino with a joystick, it might be easier to use one of the following options:

  1. Get a driver that will allow you to use the joystick (usb?) input as mouse/keyboard emulation. This shouldn’t be all that hard to find, unless the stick is a custom build.

  2. Refactor your python code in IronPython and run it in the RhinoPython editor. Most of the basic functionality of cpython (including stuff like interfacing with serial ports) is available in ironpython without too much hassle searching for libraries.


#7

Thanks to your Reply,

I was thinking of using second solution.
Is it possible from the Rhino python editor launch process(Thread).
Otherwise, I’m afraid to freeze the Rhino software.

Manu


(Giulio Piacentino) #8

Yes, I’m pretty sure it’s possible. You can also fire commands or move views/cameras from within Rhino. You can find the best way to make that work (remember, one non-transparent command at a time) but you will have to embed some logic about what to do while waiting, within your plug-in (for example, a queue of commands to execute).

Something that you can hook onto is the Idle event, happening when “nothing” is happening. Or, you could have one command that carries on with your operations while it is executing. These are just two ideas, there might be some other ones.

I hope this helps,

Giulio

Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com


#9

Hi,
I think unfortunately I did not understand everything.
Indeed,First I wish to validate this

  • A thread that displays a counter in the Rhino console without blocking it

For this I use the following code in Rhino Python Editor, but this blocks rhino

import time
import threading



 ##########################################################################
########################################################################## 
class Displaycpt(threading.Thread): 
    def __init__(self, nom = ''): 
        threading.Thread.__init__(self) 
        self.nom = nom 
        self._stopevent = threading.Event( ) 
    def run(self): 
        i = 0
        while not self._stopevent.isSet(): 
            print self.nom, i 
            i += 1 
            self._stopevent.wait(0.5) 
        print "end "+self.nom 
        
    def stop(self): 
        self._stopevent.set() 

##########################################################################
##########################################################################
class WaitEndSoft(threading.Thread): 
    def __init__(self, nom = ''): 
        threading.Thread.__init__(self) 
        self.nom = nom 
        self._stopevent = threading.Event( ) 
    def run(self): 
        startTime = time.time()
        endTime = startTime 
        while(endTime-startTime<10) :
            endTime=time.time()
            time.sleep(0.5)
        print "end "+self.nom
        
        
        
    def stop(self): 
        self._stopevent.set() 

##########################################################################
##########################################################################
def MyScript() :
    
    print 'Start Script'
    
    a = WaitEndSoft('Thread Wait') 
    b = Displaycpt('Thread A')
    a.start()
    b.start()
    a.join()
    
    b.stop()
    
    print 'End Script'
    
##########################################################################
########################################################################## 
if __name__ == '__main__':
    MyScript()

Have you any idea?

Thanks,

Manu