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?
@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.
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.
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.
%% 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:
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.