Grasshopper has three scripted components. One for python (IronPython to be specific) programming language and another two for VB.NET and C#. These scripted components allows a user to create custom logic for a Grasshopper component. The component, therefore, can accept a configurable number of input and output connection points.
Since Rhino.Inside.Revit project brings Rhino and Grasshopper into the Autodesk Revit® environment, the scripted components also get access to the Revit API runtime. In this article we will discuss using the python component to create custom components for Revit.
Setting Up
When adding a new python component into the Grasshopper definition, you will get the default imports:
In order to access the various APIs we need to import them into the script scope first. To access Revit and Rhino.Inside.Revit we need to first import the CLR (Common-Language-Runtime) module in python and use that to add the necessary library references:
Now we can import the namespaces into the script scope:
Custom User Component
Since the imports mentioned above need to be done for every single python component, the process can get tedious. You can setup a template python component with a default script importing all the most frequently used APIs and save that as a User Component in Grasshopper:
After the user object has been created, you can easily create a new python component from the user object and it will have the template python script with all your default imports:
Here is a template script that covers most of the use cases:
You can download the User Object for this template from this button:
GhPython Script
Place under Grasshopper User Objects folder. Find in Revit > Custom panel
Example
This example component will create a sphere of an adjustable radius in Revit and Rhino. It will pass that sphere onto other Grasshopper components through the output and it will create the sphere in Revit and bake into Rhino if the button connected to the input is pressed.
As you see in the image above, we have renamed the input components and also the input and output parameters on the python components. This is a really good practice and it makes the definition a lot more clear to a new user.
Once this foundation is ready, then we can continue to create the script.
Creating Sphere Geometry
To show how a geometry that is created in Grasshopper, previews in both Rhino and Revit dynamically we will use the script below. This script will create a sphere based on the Radius input value:
The Sphere() method is from the Rhino.Geometry namespace and is part of the RhinoCommon API.
By setting the output to Sphere Grasshopper will preview the results in both Rhino and Revit (Grasshopper is smart to know that some geometry is set on the output parameter). It also allows the Preview option on the component to be toggled and the sphere geometry to be passed down to the next component.
Now we can change the slider value to adjust the radius. Make sure the slider values are set to a big-enough value to the resulting sphere is visible in your Revit and Rhino models.
Baking to Revit and Rhino
We can add a custom baking function in this script. This can serve as a template to almost an unlimited number of ways and elements that one might want to create Revit objects from Grasshopper.
Because baking objects to Revit can take a long time and many times only should be done once, this bake function will only execute if the Trigger input is set to True on the component. This way we can decide to bake the object once we are happy with the results.
First, let’s create a bake function:
Once we are done creating this function, we can modify the script to listen for the trigger and call this function.
All changes to the Revit model need to be completed inside a Transaction. To facilitate this, Rhino.Inside.Revit provides the Revit.EnqueueAction method that will wrap our function inside a transaction and calls when Revit is ready to accept changes to active document. The transaction mechanism is designed to ensure only one Revit Add-in can make changes to the document at any time. To create your own transactions, see Handling Transactions
And here is the complete sample code:
Handling Transactions
To effectively create new transactions and handle the changes to your model in Grasshopper python components, use the with pattern example below:
Inspecting Revit
To inspect which version of Revit you are using, use the REVIT_VERSION global variable provided in the template script above. See example below:
Node In Code
You can also use the Grasshopper components that you love, inside your code, as functions and therefore create much more complex and powerful scripted components without writing the necessary complicated codes. The Grasshopper components basically become like powerful library functions that help you get your job done and have a smaller script to maintain. Here is what you need to add to use the Grasshopper components in your code. First we need to import the Node-in-Code handle:
Now you can access the component, like a function. These function names are prefixed with the name of their Grasshopper plugin to avoid naming conflicts. The example below shows how we can access the
Add Material inside the code:
Now lets put this knowledge into use and create a custom scripted component that imports a Brep geometry into Revit and assigns a material to it. This scripted component effectively combines 3 different Grasshopper components into one. Note that there are obviously easier ways to do the same task, however this is a simple example of how components can be chained together in a script.