Rhino inside Python

Hi Steve, this development sounds thrilling. Are there any updates?

We are still trying to figure out some issues with Grasshopper running in a headless CPython environment.

I haven’t really tried anything specific to running GH under CPython, but we do have GH running headless in other environments. Rhino compute is a case where GH is running headless in a C# based environment.

1 Like

This new capability is very exciting!

As a suggestion, I have seen another program use a COM object/server to expose their API to Python and many other programming languages. Python is able to connect to a running instance of this program by finding an object with a specific type in the system Running Object Table (using python module comtypes), or by creating a new instance with a specific registered COM type which is then used to load the API and then start a headed instance of the program (also using comtypes).

Not sure if that makes sense, as this is not my area of expertise, but maybe it is a workable technique for Rhino/GH as well.

Hi all,

Rhino inside Python is looking very cool!
We’ve been trying to automate some Rhino workflows but have run into some issues, hopefully this is the right place to post these.

The first issue is that our python code seems to randomly quit the process sometimes.
Using the debugger gives this result right before stopping the process:

Server[pid=13780] disconnected unexpectedly

And sometimes:

[WinError 10054] An existing connection was forcibly closed by the remote host

Other than this we do not have a real traceback for this error but it does happen quite often.

The second issue does have a traceback:

2021-02-24 09:18:39.218763: Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
2021-02-24 09:18:40.850448: at UnsafeNativeMethods.CRhinoDoc_Delete(UInt32 serialNumber)
2021-02-24 09:18:41.933765: at Rhino.RhinoDoc.Finalize()
2021-02-24 09:18:43.065226: Execution failed

Any ideas to fix either (or both :smiley: ) of these issues?

Thanks!

1 Like

Do you have any sample scripts that demonstrate these errors?

Update
I fixed it using the GetUserText method from RhinoScriptSyntax.
Which makes me wonder :thinking:, could this RhinoScript module just not be part of RhinoInside python package? It seems like a large collection of helper functions that would really benefit python developers.

Hi all :vulcan_salute:

I am trying to collect user data from objects by importing a .3dm file in a headless doc, but with no luck thus far. There don’t seem to be any items in the archivable dictionaries :face_with_raised_eyebrow: See sample code and file below.

In this post, it is recommended to use rhinoscriptsyntax.

  • Am I doing something wrong?
  • Can rhinoscriptsyntax be used in combination with Rhino inside Python?

Thanks :raised_hands:

import rhinoinside
rhinoinside.load()
import Rhino
import pathlib

path = pathlib.Path(__file__).parent.absolute()

input_file = f"{path}\Line-With-User-Data.3dm"

rhino_doc = Rhino.RhinoDoc.CreateHeadless(None) 
rhino_doc.Import(input_file)  
rhino_objs = rhino_doc.Objects

for rhino_obj in rhino_objs:
    # get data by user dictionary
    archivable_dictionary = rhino_obj.Attributes.UserDictionary 
    archivable_dictionary_count = archivable_dictionary.Count #returns 0

    # get data by user data
    user_data_list = rhino_obj.Attributes.UserData 
    user_data_list_count = user_data_list.Count #returns 2
    archivable_dictionary2 = user_data_list.get_Item(0).Dictionary #returns archivable dictionary
    archivable_dictionary2_count = archivable_dictionary2.Count #returns 0

rhino_doc.Dispose()

Line-With-User-Data.3dm (53.1 KB)

@stevebaer Thanks, that looks very interesting!
But just to be sure: This is not a way to run Rhino Inside Python on Linux, is it?

Unfortunately not. Rhino is still running on the machine, albeit in a “headless” mode. Also, Rhino.Inside only works with Rhino for Windows.

Compute is currently the best option for interacting with Rhino from Python on Linux.

1 Like

Hello together,

this is my first time asking some questions in the forum=) I have been reading a lot here and always enjoyed the discussions and most of the times found solutions for me. I really appreciate and like the spirit here :ok_hand:

I hope this is the correct discussion for a problem I ran into:

My goal is to gather some information from a Rhinofile within a pythonscript with rhinoinside.

Similiar to what @guus.gooskens describes in his post.

Apperantly I am running into an issue when either using the RhinoDoc Methods:

  • Open()

  • Import() or

  • OpenHeadless()

      import rhinoinside
      rhinoinside.load('C:\Program Files\Rhino 7\System')
      import Rhino
      import os
      
      # current path
      
      path = os.path.dirname(__file__)
      
      # input file path
      inputFile = path + '\Test_Lines.3dm'
      
      # get the template file path
      templateFile = Rhino.ApplicationSettings.FileSettings.TemplateFile
      
      # create a new rhino document from the template
      rhinoDoc = Rhino.RhinoDoc.CreateHeadless(templateFile)
      rhinoDoc.Import(inputFile)
    

I always get this message back:

Process is terminated due to StackOverflowException.

I tested this with different Version of Python 2.7 and 3.7.

Am I missing something fundamental here?
Does anyone have a solution to this?

My workaround sofar is to use the File3dm class. Which seems to work.

Thank you :slightly_smiling_face:

Your code looks like it should work. There must be something in Rhino core that is causing this. I logged this in our bugtracking system and will try to see if I can repeat it.
https://mcneel.myjetbrains.com/youtrack/issue/RH-64283

Thanks

Thank you for your response Steve Baer,

After reading your comment in your issue system I tried it with a blank installed version on my desktop with the same files, which worked flawless.
After that I checked all my installed plugins on my Laptop and blocked them from loading and it worked :grinning:
After trying enabeling the plugins one by one and testing it seems that V-Ray makes problems here.

Made a small function which does this for me so I dont have to do it manually in the Rhino settings.

def LoadPlugIn(id,Load):
   ''' disables or enables the plugin loading
       from the PlugIn id as a string 
       Load True or False '''
   # string to guid
   guid = System.Guid(id)
   PluginName = Rhino.PlugIns.PlugIn.GetPlugInInfo(guid).Name
   # get load status of the plugin
   LoadStatus = Rhino.PlugIns.PlugIn.GetLoadProtection(guid,False)[1]
   if LoadStatus != Load and LoadStatus == True:
       Rhino.PlugIns.PlugIn.SetLoadProtection(guid,Load)   # disable loading
       Rhino.PlugIns.PlugIn.SavePluginSettings(guid)       # save plugin settings
       if Rhino.PlugIns.PlugIn.GetLoadProtection(guid,False)[1] == Load:
           return (False,'Plugin {} stopped from loading'.format(PluginName))
       else:
           print ('ERROR: Not able to disable loading for {}'.format(PluginName))
           return None
   elif Load == True:
       Rhino.PlugIns.PlugIn.SetLoadProtection(guid,Load)   # enable loading
       Rhino.PlugIns.PlugIn.SavePluginSettings(guid)       # save plugin settings
       if Rhino.PlugIns.PlugIn.GetLoadProtection(guid,False)[1] == Load:
           return (True,'Plugin {} is loading'.format(PluginName))
       else:
           print ('ERROR: Not able to enable loading for {}'.format(PluginName))
           return None
   else:
       return (False,'Plugin {} already was stopped from loading'.format(PluginName))

Thank you :slightly_smiling_face:

Hi there, I am trying to use rhinoinside.load() but getting the following error:

Traceback (most recent call last):
File “c:\test.py”, line 10, in
rhinoinside.load()
File “C:\Program Files\Python39\lib\site-packages\rhinoinside-0.5.0-py3.9.egg\rhinoinside_init_.py”, line 34, in load
clr.AddReference(resolver_dll)
AttributeError: module ‘clr’ has no attribute ‘AddReference’

Here is the code I am using:
import rhinoinside
import rhino3dm
rhinoinside.load()
import Rhino
import Rhino.Geometry as rg

I am using Python version 3.9.5. Rhinoinside had to be installed manually after downloading from github. Pythonnet also had to be installed manually. I have also installed clr without which there were additional errors.

Any advice would be appreciated. Thank you!

Do you have Rhino 7 installed on this computer? This is a requirement for running Rhino.Inside

HI @stevebaer thanks for getting back to me. Yes I have Rhino 7 installed. I just uninstalled Python 3.9.5 and tried everything with Python 3.8.10, and it is working. It would be great to make it work with Python 3.9.5.

We need to wait until a 3.9 version of pythonnet exists. Is there a reason you need 3.9?

Our in-class demonstrations at IAAC in VS Code have been using Python 3.9. But if the current pythonnet version is not going to work then Python 3.8.10 it is :slight_smile:

For some reason Python 3.9.5 also required rhinoinside to be installed manually using python setup.py install and I was unable to use pip3.9 to install it.

Dear @stevebaer,

i am trying to use rhinoinside within vscode to run QuadRemesh method. How do i read a mesh from an external file (ply in this case).

here is the code that i am trying to use:

import rhinoinside
rhinoinside.load()
import Rhino
mesh = Rhino.Geometry.Mesh()
# mesh.Append(plyFilePath)
print(mesh.IsValid, mesh.ObjectType, mesh.Vertices.Count)
para = Rhino.Geometry.QuadRemeshParameters()
para.TargetQuadCount=202
para.AdaptiveQuadCount=True
newMesh= mesh.QuadRemesh(para)
print(newMesh)

it prints
False 32 0
None

Thank you

Hi @stevebaer,
I only recently found out about rhinoinside CPython while working my way through the GH Hops tutorial. However currently I’m experiencing an issue while trying to load the modules with rhinoinside.load() with Python 3.8.10.
Could this be due to licensing issue? Currently I have Rhino 6 commercial license and Rhino 7 Evaluation (while waiting for my company to give RH7 :cry:)

Thank you for your time.

File ".\app-rhinside.py", line 3, in <module>
    rhinoinside.load()
File "C:\Users\Anaconda3\envs\grasshopper\lib\site-packages\rhinoinside\__init__.py", line 41, in load
    __rhino_core = Rhino.Runtime.InProcess.RhinoCore()
System.Runtime.InteropServices.COMException: Error HRESULT E_FAIL has been returned from a call to a COM component.
   at Rhino.Runtime.InProcess.RhinoCore.InternalStartup(Int32 argc, String[] argv, StartupInfo& info, IntPtr hostWnd)
   at Rhino.Runtime.InProcess.RhinoCore..ctor(String[] args, WindowStyle windowStyle, IntPtr hostWnd)

Have you started Rhino 7 on its own? Also, do you have 3rd party plug-ins installed?

Other than a reminder License Expires in 6 Days on startup, the Rhino 7 Evaluation works normally for me at I don’t have any 3rd party plug-ins installed.