Hi, I have an example file of an object from which I cannot extract the render mesh.
I realise it’s not the most beautiful model in the world.
It’s part of a file I received from a client.
It’s not a bad object.
It works in rhino 7.
It is not the first time that I export files with my python script in which objects are missing.
This object also fails by extracting the mesh manually, so it’s not my code fault.
Anyway I’ll explain the problem in more detail: in my company we receive many rhino files every day, often very complex, so I created a code in python with a small client and server interface that automatically opens them, reorders them and exports them to obj, and imports them into 3dsmax.
The user (my colleagues), from their workstation open the client interface, select the file, and click start process.
The server is somewhere else, they have no idea what happens to the file.
So I need the export to have no missing objects.
As long as I have been using rhino 7 it has never happened to me to see the shaded view of an object on the screen and not be able to extract the render mesh, no matter how bad the 3d model may be.
Mesh has 2 degenerate faces.
Mesh has 909 extremely short edges.
Mesh has 2 non manifold edges.
Skipping face direction check because of positive non manifold edge count.
Mesh has 958 pairs of faces that intersect each other.
This can cause problems if you're doing mesh boolean operations with it.
Mesh has 5 naked edges. Naked edges can cause problems if the ultimate goal is STL output.
Mesh has 499 faces where the face normal differs substantially from the vertex normals.
These normals can cause problems if the ultimate goal is for rendering or boolean purposes
.
There is enough here to get a youtrack going. Thanks for reporting RH-86522.
Well, since you’re doing this via Python code, to debug I would create a small code snippet with the method you use to extract the render mesh, run it in the debugger and check the resulting mesh from that particular object. It might be invalid. Invalid RhinoCommon geometry often does not get added to the document. That might explain why it is missing from the exported document.
Edit:
Dunno, this code snippet seems to be able to extract the render mesh from your object posted above and add it to the document:
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
obj_id=rs.GetObject("Select a brep object",8+16,preselect=True)
if obj_id:
rhobj=rs.coercerhinoobject(obj_id)
r_meshes=rhobj.GetMeshes(Rhino.Geometry.MeshType.Render)
if r_meshes:
joined_mesh=Rhino.Geometry.Mesh()
joined_mesh.Append(r_meshes)
sc.doc.Objects.AddMesh(joined_mesh)
sc.doc.Views.Redraw()
My problem is not the mesh quality.
I need to have whatever I see in the rhino shaded viewport saved as obj.
My colleagues can take care of the wreck mesh later in max.
Can I expect to have rhino 8 to work as rhino 7 does? Or should I change my script meshing method?
Please follow along with the youtrack for updates. This looks to be a regression and expect it to be looked into asap and the developers will let us know what they find (hopefully a quick fix)
Thanks!
This is a valid workaround.
I just need to make sure the created mesh has the exact same attributes of the old one, (layer, color,material,etc)
Don’t think so, this just gets the mesh geometry. Not too hard to re-attribute the original object display color and layer, but the texture I have no idea how to do…
Here it is: It works, but “_ExtractRenderMesh” seems faster, I work with huge files and speed is important.
Hopefully the guys will sort the issue out soon…
#! python 2
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def extract_render_mesh():
# Get all objects from the document
obj_ids = rs.AllObjects()
if not obj_ids:
print "No objects found."
return
# Iterate over a copy of the list because we may delete some objects
for obj_id in obj_ids:
# Convert the ID to a RhinoObject
rhobj = rs.coercerhinoobject(obj_id)
if not rhobj:
continue
# Get the render meshes associated with the object
render_meshes = rhobj.GetMeshes(Rhino.Geometry.MeshType.Render)
if render_meshes:
# Create an empty mesh and merge all render meshes
joined_mesh = Rhino.Geometry.Mesh()
for mesh in render_meshes:
joined_mesh.Append(mesh)
# Copy the original object's attributes (layer, name, material, UV, etc.)
orig_obj = sc.doc.Objects.Find(obj_id)
if orig_obj:
attr = orig_obj.Attributes.Duplicate()
sc.doc.Objects.AddMesh(joined_mesh, attr)
# Delete the original object since it has a render mesh
rs.DeleteObject(obj_id)
else:
# If no render mesh exists, keep the original object
print "Object {} has no render mesh, keeping original.".format(obj_id)
sc.doc.Views.Redraw()
print "Operation completed: only objects with render meshes were replaced by their render mesh."
This should be much faster with thousand of objects.
#! python 2
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def extract_render_mesh():
# Get all objects from the document
obj_ids = rs.AllObjects()
if not obj_ids:
print "No objects found."
return
to_delete = [] # List of objects to delete after processing
# Disable redraw for better performance
rs.EnableRedraw(False)
for obj_id in obj_ids:
# Convert the ID to a RhinoObject
rhobj = rs.coercerhinoobject(obj_id)
if not rhobj:
continue
# Get the render meshes associated with the object
render_meshes = rhobj.GetMeshes(Rhino.Geometry.MeshType.Render)
if render_meshes:
# Create a single joined mesh
joined_mesh = Rhino.Geometry.Mesh()
joined_mesh.Append(render_meshes) # More efficient than looping
# Copy original object's attributes (layer, name, material, UV, etc.)
attr = rhobj.Attributes.Duplicate()
sc.doc.Objects.AddMesh(joined_mesh, attr)
# Store objects to delete after processing
to_delete.append(obj_id)
# Bulk delete of original objects for better performance
if to_delete:
rs.DeleteObjects(to_delete)
# Enable redraw after processing
rs.EnableRedraw(True)
sc.doc.Views.Redraw()
print "Operation completed: all objects with render meshes have been replaced by their render mesh."