Importation mesh and process it

Hello,

I’m starting to use the Rhino sdk with python.

I want to import a mesh from a file with a specific extension (for instance obj) and then apply some process on it. In particular I want to perform the squish command.

I did not found in the documentation about these functions (import and squish), so I wanted to know if it’s just missing from it or not yet implemented? If it’s the last, will it be integrated later?

Have a good day,

Best regards,

Florian Berton

The RhinoCommon SDK has RhinoDoc.Import and Rhino.Geometry.Squisher interfaces.

I don’t see them RhinoScript, if you want to stick to the rhinoscriptsyntax package the easiest option is to script the command. Example for Open.

Hello,

thank you for the quick response.

When I was talking to the python sdk, I was talking about the compute-rhino3d.

To explain, I want to use rhino using the python api. So I created a python project and add the two libraries (rhino3dm & compute-rhino3d).

And what I want to do is to import a mesh and then squish it using python code. But I didn’t found the two functions on the documentation of these two libraries (Welcome to compute.rhino3d.py’s documentation! — compute_rhino3d 0.12.1 documentation and Welcome to rhino3dm’s documentation! — rhino3dm 7.6.0 documentation).

So is there another library that I have to import in python ? Because I don’t find the import in rhino3dm or compute-rhino3d.

Have a good day,

Florian Berton

@stevebaer will know more about the status of these in Compute; if they are not in the documentation they probably haven’t been made accessible through Compute yet.

rhino3dm is based on the public, free version of OpenNurbs that does not include things like format converters and advanced geometry functions, it will not have squish or import available.

If you can run Rhino locally on Windows, maybe try working with Rhino.Inside CPython instead? It basically like importing the RhinoCommon SDK in CPython, so there’s no need to wait for everything to be made available through Compute.

I try the Rhino.Inside.CPython

I had no trouble with the sample you give (rhinoinside · PyPI)

But I don’t really manage to make it work for the import of an obj.

I try to use the import function documented (RhinoDoc.Import Method) but I have an error.

Here my code:

import rhinoinside
rhinoinside.load()
import System
import Rhino
mesh = Rhino.RhinoDoc.Import('test.obj')

And the error:
No method matches given arguments for Import: ()

I also try to instantiate the class RhinoDoc and then use the method import like this:

doc = Rhino.RhinoDoc()
mesh = doc.Import('test.obj')

but I have this error :
No constructor matches given arguments: ()

I also saw that you have a class FileObj in Rhino.FileIO. This class has a read function method but it’s an abstract class so no luck.

You need to create a new document first, with Rhino.RhinoDoc.CreateHeadless if you are running Rhino with no GUI display (plain RhinoDoc.Create otherwise).

PS: block quotes (block of text enclosed in triple backquotes) are a nice way to display code on this forum.

I mange to create the new document and also the class to squish the mesh. But I don’t know how to select my mesh to give it to the class. And then how to save the squish_mesh as an obj.

Here my code for now:

% load mesh
doc = Rhino.RhinoDoc.CreateHeadless("")
loaded = doc.Import('test.obj') # it's equal to True
sn_end = Rhino.DocObjects.RhinoObject.NextRuntimeSerialNumber
print(doc.Objects.Count) # it's equal to 1
mesh = doc.Objects.Find(sn_end)

% init squish
squisher = Rhino.Geometry.Squisher()
squisher_params = Rhino.Geometry.SquishParameters()
squisher_params.Algorithm = 1
squisher_params.PreserveTopology = True

% process mesh
mesh_output = squisher.SquishMesh(squisher_params,mesh)

% export mesh
doc.Export("output_test.obj)

I know that the mesh is loaded as the variables is equal to True.

When I try to use the function Find of doc.Objects, I have this error:
No method matches given arguments for Find: (<class ‘int’>)

I also tyr the function:

doc.Objects.GetObjectList (Rhino.Geometry.Mesh)

But it didn’t really work.

That’s my best take on it:

import rhinoinside
rhinoinside.load()
import System
import Rhino

# load mesh
doc = Rhino.RhinoDoc.CreateHeadless("")
loaded = doc.Import('test.obj')

# NextRuntimeSerialNumber is not assigned to an object yet, it is the next one that is free
# Also doc.Object.Find needs a System.UInt32 as input, you need to call it as
# doc.Objects.Find(System.UInt32(sn_end))
# Instead, let's dump all objects in the ObjectTable into a Python list
objects = []
for object in doc.Objects.GetObjectList(None):
    objects.append(object)

# Get the mesh, it is stored in the Geometry of the MeshObject
mesh = objects[0].Geometry
print(mesh)

# init squish
squisher = Rhino.Geometry.Squisher()
squisher_params = Rhino.Geometry.SquishParameters()
squisher_params.Algorithm = 1
squisher_params.PreserveTopology = True

# process mesh
mesh_output = squisher.SquishMesh(squisher_params, mesh)
# There is a bug in our code that makes the squished mesh invalid: RH-66087
mesh_output.Vertices.UseDoublePrecisionVertices = False

# Add the newly created mesh to the doc's objects
doc.Objects.AddMesh(mesh_output)
print(doc.Objects.Count)  # Should be 2

# export mesh
doc.Export(r"C:\Users\Pierre\Desktop\output_test.obj")  # I don't know where this goes with just a filename

When RH-66087 is fixed the UseDoublePrecisionVertices = False line won’t be needed anymore.

Thank you,

I also manage to make it work like this:

%%load mesh
doc = Rhino.RhinoDoc.CreateHeadless("")
doc.Import(inputfile)
objs = doc.Objects.FindByObjectType(Rhino.DocObjects.ObjectType.Mesh)
mesh = objs[0].MeshGeometry

%% create squisher
squisher = Rhino.Geometry.Squisher()
squisher_params = Rhino.Geometry.SquishParameters()
squisher_params.Algorithm = 1
squisher_params.PreserveTopology = True

% %process mesh
mesh_output = squisher.SquishMesh(squisher_params, mesh)

%% save mesh
WriteOptions = Rhino.FileIO.FileObjWriteOptions(Rhino.FileIO.FileWriteOptions())
Rhino.FileIO.FileObj.Write(output_file,[mesh_output],WriteOptions)

And I didn’t have ay trouble without the

UseDoublePrecisionVertices = False

What was the trouble with this feature?

Furthermore, I needed this code to flatten a mesh wich have some portions at 90°. I played a lot with the parameters but it seems that the squish method is not well adapted for that.

I also tried the unroll method as my mesh is a 3d surfaces but I don’t really understand how to do the unroll. Here is a snipet of my code:

%%load mesh
doc = Rhino.RhinoDoc.CreateHeadless("")
doc.Import(inputfile)
objs = doc.Objects.FindByObjectType(Rhino.DocObjects.ObjectType.Mesh)
mesh = objs[0].MeshGeometry
brep_mesh = Rhino.Geometry.Brep.CreateFromMesh(mesh,True)
unroller = Rhino.Geometry.Unroller(brep)

The creation of the unroller works but I don’t know how to do the operation. In the doc there is only PerformUnroll. But it takes a list of brep and I already give my brep representation of my mesh in the constructor.

PerformUnroll takes as argument a list of Breps, that will be filled with the output Breps of the unroll. Example below:

import rhinoinside
rhinoinside.load()
import System
import Rhino

# load mesh
doc = Rhino.RhinoDoc.CreateHeadless("")
loaded = doc.Import('test.obj')

# NextRuntimeSerialNumber is not assigned to an object yet, it is the next one that is free
# Also doc.Object.Find needs a System.UInt32 as input, you need to call it as
# doc.Objects.Find(System.UInt32(sn_end))
# Instead, let's dump all objects in the ObjectTable into a Python list
objects = []
for object in doc.Objects.GetObjectList(None):
    objects.append(object)

# Get the mesh, it is stored in the Geometry of the MeshObject
mesh = objects[0].Geometry
print(mesh)

# init squish
squisher = Rhino.Geometry.Squisher()
squisher_params = Rhino.Geometry.SquishParameters()
squisher_params.Algorithm = 1
squisher_params.PreserveTopology = True

# process mesh
brep_mesh = Rhino.Geometry.Brep.CreateFromMesh(mesh,True)
unroller = Rhino.Geometry.Unroller(brep_mesh)
breps_output = System.Collections.Generic.List[Rhino.Geometry.Brep]()
unroller.PerformUnroll(breps_output)

# Add the newly created mesh to the doc's objects
for object in breps_output:
    doc.Objects.AddBrep(object)
print(doc.Objects.Count)  # Should be mesh.Faces + 1

# export mesh
doc.Export(r"C:\Users\Pierre\Desktop\output_test.obj")  # I don't know where this goes with just a filename

Rhino can store vertices position in two lists: one using single precision floats (each is 32 bits of memory), and another one with double precision doubles (64 bits each). If a mesh declares itself to be using double precision values for its vertices, then these two lists need to be synchronized (same lengths, compatible locations), or Rhino won’t know which one to give preference to. The squish operation would create meshes with desynchonised lists, making the output mesh invalid and Rhino would refuse to add it to the document.

If you had no trouble with this, it might be because you wrote the mesh to an .obj file directly instead of adding it to the doc like I did. In any case the bug is now fixed and the fix should be incorporated in the service release 7.13.

RH-66087 is fixed in Rhino 7 Service Release 13 Release Candidate