Using Shrinkwrap in Python

How would it be possible to use Shrinkwrap in Python?

This is the code that I am using now:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
import random

# Step 1: Select the mesh
mesh_id = rs.GetObject("Select STL mesh", rs.filter.mesh)

if not mesh_id:
    raise Exception("No mesh selected")

mesh_obj = rs.coercegeometry(mesh_id)

if not isinstance(mesh_obj, Rhino.Geometry.Mesh):
    raise Exception("Selected object is not a mesh")

params = Rhino.Geometry.ShrinkWrapParameters()

params.FillHolesInInputObjects = True  # Example, enable hole filling
params.InflateVerticesAndPoints = False  # Example, do not inflate vertices/points
params.Offset = 0.1  # Example, offset the mesh by 0.1 units
params.PolygonOptimization = 50  # Example, 50% optimization for polygons
params.SmoothingIterations = 5  # Example, apply 5 smoothing iterations
params.TargetEdgeLength = 0.2  # Example, target edge length is 0.2 units

# Step 3: Shrink wrap the mesh using the parameters
# Step 3: Get mesh vertices
vertices = mesh_obj.Vertices

all_points = [Rhino.Geometry.Point3d(v.X, v.Y, v.Z) for v in vertices]

# Step 4: Reduce points (take 10%)
sample_ratio = 0.1
sampled_points = random.sample(all_points, int(len(all_points) * sample_ratio))

# Optional: Visualize the points
for pt in sampled_points:
    rs.AddPoint(pt)

shrink_wrap_mesh = Rhino.Geometry.Mesh.ShrinkWrap(mesh_obj, params)

I keep getting the following error:
Traceback (most recent call last):
File “file:///C:/Users/Martijn/.rhinocode/stage/cclfz0qb.4mc”, line 40, in
TypeError: Invoked a non-static method with an invalid instance

What would be a possible solution?

Hi Martijn, try formatting the Python code, like so:

Also, I changed the category. Also also, welcome to the forum :slight_smile:

Thank you very much for the tip! Looks much better now. Thanks for the welcome!

No worries. Looks like it might be an issue with running the code in CPython. What happens if you run it in IronPython with the new script editor? Or better yet, using the old/pre-Rhino 8 EditPythonScript editor?

Edit: You might need to be more explicit with the overload you’re using (e.g. wrap the mesh in a list and use this one).

It works in IronPython. What could the issue be with CPython?

A whole bunch, but it’s likely because of how CPython interfaces with RhinoCommon (i.e. using Python.Net), where IronPython is written in C# and can implement it directly. So there’s some considerable hoop jumping/performance issues involved on the CPython side of things.

I got it working now in Python3.

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
import random

# Step 1: Select the mesh
mesh_id = rs.GetObject("Select STL mesh", rs.filter.mesh)

if not mesh_id:
    raise Exception("No mesh selected")

mesh_obj = rs.coercegeometry(mesh_id)

if not isinstance(mesh_obj, Rhino.Geometry.Mesh):
    raise Exception("Selected object is not a mesh")

# Create shrink wrap parameters
params = Rhino.Geometry.ShrinkWrapParameters()

params.FillHolesInInputObjects = True  # Example: Enable hole filling
params.InflateVerticesAndPoints = False  # Example: Do not inflate vertices/points
params.Offset = 0.1  # Example: Offset the mesh by 0.1 units
params.PolygonOptimization = 50  # Example: 50% optimization for polygons
params.SmoothingIterations = 5  # Example: Apply 5 smoothing iterations
params.TargetEdgeLength = 0.2  # Example: Target edge length is 0.2 units

# Step 2: Shrink wrap the mesh using the parameters (mesh_obj needs to be wrapped)
shrink_wrap_mesh = mesh_obj.ShrinkWrap(params)

Thanks for your help!

2 Likes

@Martijn_Fouchier

Mesh type defines overloads of ShrinkWrap that are some marked as static and some are instance methods. This confuses CPython and I do have a ticket to improve this:

RH-85062 Pynet gets confused about methods with same name but one is static

As you figured it out already, the instance ShrinkWrap overload is the way to go.