Rhino 8 Fails to Extract Render mesh

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.

Try it and let me know.
Test_object.3dm (948.3 KB)

The selected surface can be seen from two sides which I find a bit suspicious.

The pointy bit of your object should be cleaned up to avoid problems downstream…

How did you create the object? Do you happen to have planar curves used for an extrusion?

read my entire post before replying…

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.

Good idea, something I often ignore. Anyway. The pointy bit is problematic.

ok, I agree it is problematic.

But the question is why rhino 7 does not give a fuck and gives me a mesh every time and rhino 8 doesn’t? :smiley:

I need to know if this is a bug, and there will be a solution any soon or I need to change the way I mesh my objects.

And the render mesh from Rhino 7 is a good mesh or does it have self intersections?

The Rhino 7 render mesh is a wreck.

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.

1 Like

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()
1 Like

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?

See my post above…

It appears to be a valid mesh. What am I doing differently than you?

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)

1 Like

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… :slight_smile:

#! 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."