I am working on a project where I need to import 3D files (OBJ and 3DM formats) into Grasshopper, in a similar manner to EnergyViz. However, I’m uncertain about the specific steps and components required for this integration.
How can I use Hops in Grasshopper to import OBJ/3DM files? What are the specific steps for this integration with Viktor’s API?
Any advice, examples, or resources you can share would be incredibly helpful.
Great to hear you are building VIKTOR apps through Grasshopper!
There are two ways to import geometry into Grasshopper:
The most straight-forward is to make use of our Generic Worker, and send your 3dm to the worker (just like you send parameters with a .json). The 3dm file will then be downloaded into the worker directory, where you can access it in your Grasshopper script using a Import3dm gh-node (with the file path).
The other way is primarily useful if you aren’t using the Generic Worker. You can read and encode your geometry in your app, and then use the Get Geometry [HOPS] component to load in the geometry to get a direct reference to any geometry.
Thank you for explaining the possible workflows for sending geometry to Grasshopper. I’m not sure I understood it correctly but this is how I’m trying to reproduce your second solution.
I’m trying to use the GeoPolylineField to collect the geometry and send it to the Grasshopper file. Yet, since the JSON parser does not like the GeoPolyline object I tried to build a custom json object for the polyline along these lines:
path = {'type':'polyline'}
if params.path:
pointlist = []
for i in params.path.points:
point = [i.rd[0], i.rd[1], 0]
pointlist.append(point)
path['data'] = {'points': pointlist}
I then construct a new params with the path object and pass it to the json.dumps
My assumption here is that viktor is using a key to know which Hops get components receives which input. But I’m getting an error on the Rhino Compute server.
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: {. Path ‘data’, line 1, position 30.
Nice to see you working on this workflow! Your assumption is right to create a custom json object from the points. However Hops expects encoded Rhino geometry, instead of a custom json object.
See this snippet:
def geopolyline_to_rhino(line : GeoPolyline):
"""Returns a Rhino polyline from a VIKTOR GeoPolyline"""
rhino_points = [rhino3dm.Point3d(p[0], p[1], 0) for p in line.points]
rhino_points += [rhino_points[0]]
return rhino3dm.Curve.CreateControlPointCurve(rhino_points, 1)
...
newparams = { ... }
newparams['path'] = json.dumps(
geopolyline_to_rhino(params.path).Encode()
)
...
This assumption is also right, but we have to translate the newparams-json to a Grasshopper Datatree. Like this:
import compute_rhino3d.Grasshopper as gh
...
input_trees = []
for key, value in newparams.items():
tree = gh.DataTree(key)
tree.Append([{0}], [value])
input_trees.append(tree)
output = gh.EvaluateDefinition("your_script.gh", input_trees)
In this step; make sure that your Hops inputs have names that correspond with your keys of your newparams dict.