This python module helps you create python (specifically CPython) functions and use them inside your Grasshopper scripts using the new Hops components. This module can use its builtin default HTTP server to serve the functions as Grasshopper components, or act as a middleware to a Flask app. It can also work alongside `Rhino.Inside.Cpython to give full access to the RhinoCommon API
This is a python example defining a Hops python component that takes a curve and number as input and return coordinates of a point at given parameter on the curve. This example uses Flask as the http server:
from flask import Flask
import ghhops_server as hs
# register hops app as middleware
app = Flask(__name__)
hops = hs.Hops(app)
@hops.component(
"/pointat",
name="PointAt",
description="Get point along curve",
icon="examples/pointat.png",
inputs=[
hs.HopsCurve("Curve", "C", "Curve to evaluate"),
hs.HopsNumber("t", "t", "Parameter on Curve to evaluate"),
],
outputs=[
hs.HopsPoint("P", "P", "Point on curve at t")
]
)
def pointat(curve, t):
return curve.PointAt(t)
if __name__ == "__main__":
app.run()
Assuming you have python3 installed on your machine, follow the steps below to create your first Grasshopper Hops component:
-
Install
ghhops-server
(reads Grasshopper Hops Server) using your preferred python package manager. This will install the module and its dependancies. We will usepip
for simplicity here but the same commands can work by forpipenv
pip install ghhops-server
-
We are going to use Flask as the http server. So install flask as well:
pip install flask
-
Let's create a python script and name it
app.py
. We will renamedghhops_server
on import tohs
for simplicity:# import flask, ghhops_server, and rhino3dm # rhino3dm is automatically installed with ghhops_server from flask import Flask import ghhops_server as hs import rhino3dm
-
Now continue on the python script to instantiate a Flask app, and add Hops as a middleware:
# register hops app as middleware app = Flask(__name__) hops = hs.Hops(app)
-
Now let's create a Hops python component that takes a curve and number as input and return coordinates of a point at given parameter on the curve.
-
Note that we are using
@hops.component
decorator to decorate the functionpointat(curve, t)
as a Hops component. The first argument passed to the decorator ("/pointat"
) is the URL of this component on our server. The rest are the information that Grasshopper needs to visualize the component on its canvas, show the input and outputs, icon, description, and the rest. -
We are using Hops predefined parameter types (e.g.
HopsCurve
) to define the inputs and outputs. This is necessary so Hops knows which exact Grasshopper data type we want to use. -
We have also specified an icon for this component
examples/pointat.png
but this is not required. Create a 24x24 png icon as you like and provide the path to it instead.
@hops.component( "/pointat", name="PointAt", description="Get point along curve", icon="examples/pointat.png", inputs=[ hs.HopsCurve("Curve", "C", "Curve to evaluate"), hs.HopsNumber("t", "t", "Parameter on Curve to evaluate"), ], outputs=[ hs.HopsPoint("P", "P", "Point on curve at t") ] ) def pointat(curve, t): return curve.PointAt(t)
-
-
Now let's end the script by running out Hops server:
if __name__ == "__main__": app.run()
Save the python file and run it using python:
python app.py
You should see the report from the app initializing itself and waiting for calls to the flask server:
[DEBUG] Using Hops Flask middleware [DEBUG] Component registered: <HopsComponent /pointat [Curve,t -> PointAt -> P] > ... [INFO] * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
-
Open Rhino and Grasshopper, drop a Hops component on the Grasshopper canvas.
-
Right-Click on the hops component and input the component path as the url
http://127.0.0.1:5000/pointat
Hops component will update itself to show the input, output, and icon of the python component we just created. Note the small Hops badge on the lower right corner to show this is a Hops component under the hood:
-
If you add a curve and a slider and connect them to the Hops component input, you should get the calculated point on the curve as output:
# Running test HTTP server
pipenv run hops_http
# Running test Flask server
pipenv run hops_flask
# Running test HTTP server with rhinoinside
pipenv run hops_rhinside
# Publishing package on Pypi
pipenv run build
Hops module structure:
base.py
base class for the Hops middleware:- component registration
- input processing
- solving
- output processing
- schema [un]wrap
component.py
Hops componentparams.py
wrappers for supported paramsmiddleware/
supported server backends:- handle http GET and POST in each framework