Disclaimer: I have very little experience with numpy and scipy so you are going to do better by searching google for support with these libraries. This blog is about getting these libraries to run in Rhino.
Yes it is possible now!!!
Okay, here’s what I did to get numpy/scipy running in Rhino
1 – Install Rhino 5 (32bit version)
numpy/scipy uses C++ DLLs which need to be compiled for a specific platform. Currently numpy/scipy for IronPython will only run in 32bit applications on Windows. I contacted the guys at Enthought and they do plan on releasing a 64bit version for Windows, but they want to make sure everything is working on 32bit first. They have some doubts about being able to release a mono version for you Mac guys out there.
2 – Install numpy/scipy for IronPython
Follow the instructions on this site http://www.enthought.com/repo/.iron/
3 – Modify settings in RhinoPython
Start Rhino 5 – 32bit version and run “EditPythonScript” to bring up the editor. Go to the options dialog by selecting Tools->Options from the menu
Check the “Frames Enabled” option since numpy/scipy requires this to be turned on.
I decided to make the “Frames Enabled” an optional engine feature since it does have a performance impact on scripts. Numpy/scipy requires this feature to be turned on.
4 – Run a test
# For now, we need to manually load mtrand before using numpy or scipy # I'm still trying to figure out why mtrand is not automatically getting # loaded when numpy/scipy imports it. If I can fix this, we won't need # the following two lines import clr clr.AddReference("mtrand") import numpy import rhinoscriptsyntax as rs x_coord = [ 0, 1, 2, 3, 4, 5, 6] y_coord = [0.0,0.1,0.5,2.5,2.5,2.5,4.0] xyz = zip(x_coord,y_coord,*len(x_coord)) rs.AddPoints(xyz) degree = 5 eq = numpy.polyfit(x_coord, y_coord, degree) fitfunc = numpy.poly1d(eq) fit_points =  for i in range(61): x = i/10.0 y = fitfunc(x) fit_points.append((x, y, 0)) rs.AddPolyline(fit_points)
If you get a polyline in rhino fit through a series of points then you are all all set; if not go back to step 1 and repeat.
This looks like a good place to start if you want to learn more about numpy/scipy
YES!!! This could lead to some incredible applications.
Now if they only had a version that clipped to your monitor and tracked your fingers…
I received a question on accessing the ShapeWays API from my last “Outside the Box” blog and figured I should dig in and figure out what is going on. Shapeways has a web service API that uses SOAP and a WSDL page (http://en.wikipedia.org/wiki/Web_Services_Description_Language) as described here
This API is a bit different than the REST API which I wrote a script to access in my previous blog post. In order to use this API, I ended up modifying a script originally put together by Michael Foord (author of “IronPython in Action”) that creates a .NET assembly on the fly for a given WSDL url.
The two scripts are in gists at the end of this post
Place both of these scripts in the same directory and open the “useshapeways.py” script. Here’s the script itself
"""Sample script that accesses the shapeways API [url]http://www.shapeways.com/api[/url] """ import wsdlprovider wsdl_url = "http://api.shapeways.com/v1/wsdl.php" username = "username" password = "password" application_id = "rhinotest" assembly = wsdlprovider.GetWebservice(wsdl_url) shapeways = assembly.SWwsdlService() session_id = shapeways.login(username, password, application_id) if session_id: #get list of printers available printers = shapeways.getPrinters(session_id, "", application_id) if printers: for printer in printers: print "printer:", printer.title for material in printer.materials: print " - material ", material.title
The script uses the wsdlprovider script to generate a .NET assembly from the shapeways wsdl url. This assembly has a class in it called SWwsdlService which we create an instance of and call functions on. It looks like a normal class to python, but all of the function calls are sent to ShapeWays over the internet and response are turned into classes that you can use. This sample simply logs into shapeways to get a “session id” and then asks Shapeways for a list of it’s available printers along with what materials each printer supports.
At the time of this blog post, the printed output from this script is
printer: Somatech FDM
- material Grey Robust
printer: Somatech Objet 720
- material Black Detail
- material White Detail
- material Transparent Detail
printer: SLS Printer
- material White Strong & Flexible
printer: Metal Printer matt
- material Gold Plated Glossy
- material Antique Bronze Glossy
- material Antique Bronze Matte
- material Stainless Steel
printer: SLS Color Printer
- material Black Strong & Flexible
printer: Silver Printer
- material Silver Glossy
- material Silver
printer: ZPrinter 650
- material Sandstone
- material Full Color Sandstone
printer: SLS Alumide
- material Alumide
printer: Glass Printer
- material High Gloss Black Glass
- material High Gloss White Glass
- material Milky White Matte Glass
printer: Metal printer Gold
- material Gold Plated Matte
printer: SLS Color Printer New
- material Dark Grey Strong and Flexible
- material Indigo Strong and Flexible
- material Winter Red Strong and Flexible
printer: HD printer
- material Frosted Detail
printer: UHD printer
- material Frosted Ultra Detail
printer: SLS Printer polished
- material White Strong & Flexible Polished
printer: Ceramics printer
- material Glazed Ceramics
One of the nice bits that we have access to in Rhino python is the Task Parallel Library that is built into .NET 4
This set of classes and functions makes it relatively easy to write things like parallel for loops in which every iteration of the loop may be processed on different threads. This nice thing about parallel for loops is that they make coding with multiple threads much simpler since the “multi-threading” only occurs inside the for loop and once the loop is finished you know that the all of the threads have completed and you are back on the main execution thread.
Here’s a sample python script which runs many Plane-Brep intersections either on a single thread or using multiple threads.
I’ve been trying to learn more about things like web services and APIs provided by internet companies (gotta figure out what all of these buzzwords are.) One thing I’ve noticed is that many companies now provide a REST API which return JSON objects. There are enough resources on the web that describe REST and JSON that I don’t need to repeat it here; I’m just going to get to my python experiments on this technology.
So what does it do?
The python script uses the Google Translate API to translate text from one language to another. Maybe not the most useful new tool for Rhino, but it shows how simple it is to format a request to a web service and get at the results.
Some important things to note:
- The scripts in both attachments are exactly the same. There is code in the script to figure out if it is running as a normal Rhino python script or inside of Grasshopper.
- The script does different things when it is running in Rhino versus when running in Grasshopper. In Rhino, the script converts text dot text which in Grasshopper the script uses input and output variables.
- I’m using the sticky variable to cache results. This way we don’t have to keep going out to Google if we are translating the same text over and over again
Search around on the internet for REST apis that return JSON data. Your python scripts that use these other services will end up looking pretty similar to the samples I posted (unless you don’t like my scripting style;)) Here are some interesting APIs to look at:
Giulio Piacentino and I have been working on an update to the grasshopper/python component and finally have something to show off!!!
http://www.food4rhino.com/project/ghpython – NOTE: Will only work in Rhino 5
This component is a scripting component similar to the VB.NET and C# components that ship with Grasshopper. You get a component where you can define as many input and output variables as you want and then reference these variables in the python script.
If you double click on the component, you get a light version of the python script editor which you are used to in the EditPythonScript command (keywords are colorized and functions autocomplete when possible)
But there is a cool twist… this component supports the rhinoscriptsyntax functions. The rhinoscriptsyntax functions can be set to generate geometry inside of Grasshopper that does not live in the Rhino document. We are using a concept called “duck typing” to swap the document that the rhinoscriptsyntax functions use from the rhino document to a grasshopper document. This means that the following script
import rhinoscriptsyntax as rs for x in range(10): rs.AddPoint((x,0,0)
will add 10 points to the Rhino document when run from Rhino’s “RunPythonScript” or “EditPythonScript” functions. The same script will add 10 points to a grasshopper document that can be passed on to other grasshopper components when run inside the syntax of grasshopper.
We are writing this as an open source project which is hosted at
Developers are welcome to download, compile, and tinker with the component source code. If you find bugs or want to add features, let us know and we’ll figure out how to get you more involved in the development process.
You can also log bugs and wishlist items at
Use your python scripting skills in Rhino 5 for Windows, Rhino 5 for Mac, and in Grasshopper for Rhino 5;)
This is only for Windows Rhino right now since you can’t customize toolbar buttons on Mac yet, but once that feature becomes available I’m pretty sure the technique will be the same.
In Rhino, create a new toolbar button and edit it. Consult the Rhino help for for adding and editing toolbar buttons. Now you have three options (that I can think of at the moment) for adding a python script to a toolbar button. All of these involve executing the RunPythonScript command
- Directly embed the script
Make sure the first line reads -_RunPythonScript (. Note that there needs to be a space between RunPythonScript and the parentheses.
Make sure the last line is just a closing parentheses. The lines in between are interpreted as your python script.
-_RunPythonScript ( import rhinoscriptsyntax as rs point0 = rs.GetPoint("start") point1 = rs.GetPoint("end") rs.AddLine(point0,point1) )
- Absolute path to the script
- Path to script on search path
If the script is on python’s search path, you can use the following form to let python find the script (use period separate subdirectories.)