3d file import on grasshopper

Hello Viktor Community,

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.

Thank you very much for your assistance!

Hi Solkyu,

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.

Let me know if that helps you out!

Hello @rvandijk

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

    newparams = {'largura': params.largura,
                  'espessura': params.espessura,
                  'altura': params.altura,
                  'distancia': params.distancia,
                  'path': path,
                  'shape': shape}

    #Create a JSON file form inputs
    input_json = json.dumps(newparams)

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.

Hi Felipe,

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.

Hope that helps!

Rick

1 Like

Thank you for your explanation @rvandijk!

I tried to implement your solution but I can’t import rhino3dm on app.py. I always get an error on uploading to the server.

ModuleNotFoundError: No module named ‘rhino3dm’

Naturally the module is installed on my system, it is being imported on the top of the file and there are no errors there.

Hi Felipe,

Add rhino3dm and compute_rhino3d to your requirements.txt in your app and run viktor-cli install to install the packages into your project.