Access "Contour" component via ghpythonlib.components

I am trying to access grasshopper’s Contour (“Create a set of Brep or Mesh Contours”) component,
but I cannot find it!

ghpythonlib.components.Contour refers to the curve contouring component (“Create a set of Curve contours”).

Does anyone know how to find out by which name you can access a specific component?

It’s arguably simpler to call the RhinoCommon methods directly:

https://developer.rhino3d.com/5/api/RhinoCommonWin/html/Overload_Rhino_Geometry_Mesh_CreateContourCurves.htm

https://developer.rhino3d.com/5/api/RhinoCommonWin/html/Overload_Rhino_Geometry_Brep_CreateContourCurves.htm

Thanks, but what I am actually trying to do is benefit from the parallel computing functionality from the gh-component.

Maybe there is also another way?

1 Like

Those are separate concerns. I assume the most performant (GHPython) solution is to call the RhinoCommon contour methods directly, and then implement these/the one you need using the inbuilt GHPython multithreading function, or implement this yourself.

1 Like

Thanks guys.

I reported RH-50604.

In the meantime, using RhinoCommon is probably the way to go. Please ask if you need assistance, @shwdehaan.

2 Likes

Thank you both! I’ll give it a try and let you know if it worked out.

The basis is pretty straightforward…

Fed with planes from grasshopper

import rhinoscriptsyntax as rs
import ghpythonlib.components as ghcomp
import ghpythonlib.parallel

brep = rs.coercebrep(x)

def slice(plane):
    contours = brep.CreateContourCurves(brep, plane)
    return contours
    
slices = ghpythonlib.parallel.run(slice, planes, True)

Slicing planes dynamically created (is there maybe a more efficient way?)

import rhinoscriptsyntax as rs
import ghpythonlib.components as ghcomp
import ghpythonlib.parallel
import Rhino.Geometry as rg
import math

brep = rs.coercebrep(x)

def slice(plane):
    contours = brep.CreateContourCurves(brep, plane)
    return contours
    
layer_height = 2

bbox = rs.BoundingBox(brep)

base_point = bbox[0]
end_point = bbox[4]

number_of_layers = int(1 + math.floor((end_point.Z - base_point.Z) / layer_height))

planes = []
        
for i in range(1, number_of_layers):
    
    z = base_point.Z + i * layer_height
    vector = rg.Vector3d(0,0,z)

    planes.append(
        rg.Plane(bbox[0]+vector, bbox[1]+vector, bbox[3]+vector)
    )

slices = ghpythonlib.parallel.run(slice, planes, True)

…but what I get returned then are (depending on the geometry) PolyCurves,
which gives type erros further down the line when for example using

rs.ReverseCurve(slice)

Runtime error (TypeErrorException): Parameter must be a Guid or string representing a Guid

If I first try to get a guid with

rs.coerceguid(slice)

I get returned a NoneType. I know I can achieve the same by doing

slice.Reverse()

but since most of my script uses rhinoscriptsyntax, I will run into problems somewhere.

I’m not sure what is the best way of dealing with shifting between rhinocommon and rhinoscriptsyntax anyway. Any tips on that?

I’d highly recommend sticking with RhinoCommon for geometry generation/manipulation in GHPython (there are many threads on this here and on the old GH forum). Both for simplicity and performance concerns.

Look up the source code of the rhinoscriptsyntax functions you need, two methods:

Thanks, that’s very helpful!

If I understand correctly, this is due to the fact that the curve doesn’t exist in the Rhino document, and hence has no Guid. Adding it to the document returns the guid…

id = scriptcontext.doc.Objects.AddCurve(slice)

…and makes it possible to use it in rhinoscriptsyntax again. But I’ll keep the following in mind!

1 Like

Thank you Giulio and Sven, any developments to solve the bug?

Hi @gch, the bug item I linked to above, RH-50604 , is assigned to David @DavidRutten. He set the target as Rhino 8. As long as the components have the same name, there’s little that can be done here in GhPython. Maybe David could schedule this for a little earlier release?