Hacking the Grasshopper Hops Component
Hops is meant to let you re-use of Grasshopper script parts across multiple documents, and consume Rhino Compute services that are hosted online or on a local network. It provides a single component, that when given a path to a local file or network endpoint, turns itself into a component representing the function and handles communication with the source. That is, it shows a new icon, sets up the appropriate inputs and outputs, makes requests and returns responses either to a local file or remote service.
Besides making calls to other local Grasshopper documents, and remote
Rhino Compute servers, Hops also works with any Flask-based
Python1 server that uses the rhino3dm
python library, through a REST API.
An example is included in the Rhino Compute repository. This is great because it
provides a way to use "real" Python, independent of the Rhino application,
incorporating third-party libraries like NumPy, using your
preferred editor etc2.
But what else can it be used for? One potential opportunity here is you
could hypothetically build a single API accessible from either Grasshopper or a web app.
Even though this use case isn't documented, you don't actually need
Rhino Compute or rhino3dm
on the server to use Hops.
Given that the Hops code is open-source, you could go as far as adapting the
code to use a properly open format like well-known binary rather than openNURBS
for the geometry representation, making it easier to work with geospatial
libraries like shapely, but let's leave that for another time.
Using the Hops Grasshopper component as-is, can we adapt the server example to work without using any Rhino-specific code? Here's what I did:
- using a two-machine setup…
- a laptop running NixOS, to develop and run the server
- a windows desktop running Windows, Rhino and Grasshopper
- on the development machine:
- set up
shell.nix
and.envrc
for the developent environment - the python environment just needs
flask
for now - port
5000
should be open so the Flask service is reachable over network
- in
examples/app.py
- comment out
rhino3dm
import - also comment out endpoints that use
rhino3dm
calls (for now),srf4pt
andpointat
- finally add the arguments
host='0.0.0.0', port=5000
to theapp.run()
call
- comment out
- now in
ghhops_server/__init__.py
- comment out all calls to
params._init_...
- that is for both
rhino3dm
andrhinoinside
init functions
- comment out all calls to
- finally in
ghhops_server/params.py
RHINO_TOJSON = lambda v: json.dumps(v, cls=_HopsEncoder)
CONVERT_VALUE = lambda v: return v
- on line 210, (
for param_value_item in input_data["InnerTree"]["0"]:
) - change the outer key from
"0"
to"{0}"
- you should be able to start and test the development server:
- run
python app.py
fromexamples
- run
- now test it on the windows machine:
- in an empty grasshopper document, set up a new hops component as shown below
- (right click to get Path and Enabled inputs to appear)
- A, B inputs and S output will appear if Hops is able to reach the server
- S should have the result of the operation of A and B