Obj -> Max post r5 is unusable... My findings

Hi there,

I receive rhino models for pretty much every project from my clients and we are forced to use r5 for exporting to obj because the exporter from version 6 onward behaves differently and gives unusable results.

I have been trying different combinations of export settings all day long and have come to the conclusion that I cannot recreate an exact copy of an obj in both r5 and r7.

What r5 seems to do that r7 seems to not do, is insert the group name before each object definition. Allow me to demonstrate.
I have exported several meshes on a layer named _WORK and the r5 export will insert “g __WORK” before the material definition for each mesh in the exported file. A snippet from the export:
f 34//34 36//36 25//25
f 30//30 33//33 34//34
f 34//34 31//31 30//30
f 29//29 30//30 31//31
g __WORK
usemtl Default
v 54866.33011621276 25125.31875220094 446.1393826848947
v 54899.18431753635 25149.29469307091 446.1393826848947
v 54882.26804695473 25188.61901136499 446.1393826848947
v 54851.11617113972 25192.6964048331 446.1393826848947

If I take the very same lines from an export of the very same objects from r7, it will appear thusly:
f 34//34 36//36 25//25
f 30//30 33//33 34//34
f 34//34 31//31 30//30
f 29//29 30//30 31//31
usemtl diffuse_0
v 54797.08701107337 25150.42174506201 446.1393826848947
v 54771.56930919119 25118.75013039109 446.1393826848947
v 54798.0993518269 25085.1537160373 446.1393826848947
v 54829.24354881148 25089.28935365121 446.1393826848947
v 54846.37885934678 25132.1411031307 446.1393826848947

As you can see the “g __WORK” line no longer exists and the results are catastrophic.
Below you can see the two results. They are completely different.

r7

Hello - what are your export settings here:

-Pascal

Hi Pascal,

Thanks for the reply.
The settings I use in r5 are as follows:

The settings for r7 match these as closely as possible but result in the same problem regardless of whether ‘Merge nested group/layer names’ is enabled or not. I have tried both, and neither work.

Hello - if you have not, please try this:

here, this gets me the ‘g’ like so

image

-Pascal

Hello,

the Wavefront .obj is a very simple file format.
Unless you don’t care about Materials you can potentially create your own obj export. See this Python example:

import Rhino
import Rhino.Geometry as rg
from time import gmtime, strftime

time = strftime("%Y-%m-%d---%H-%M-%S", gmtime())
path = "./shape-" + time +".obj"

useGroups = True

def SaveObj(path):
    print "Saving obj to " + path

    doc = Rhino.RhinoDoc.ActiveDoc
   
    with open(path,'w') as f:
        f.write("# Custom obj writer\n") 
        lastVertCnt = 0
        offset = 1
        for obj in doc.Objects:
            if type(obj.Geometry) != rg.Mesh:
                continue            
            mesh = obj.Geometry
            # write vertices
            for v in mesh.Vertices:
                f.write("v {0:f} {1:f} {2:f}\n".format(v.X,v.Y,v.Z))
                f.flush()
            # write group
            if useGroups:
                # get layername
                layerIndex = obj.Attributes.LayerIndex
                layer = doc.Layers.FindIndex(layerIndex)
                layerName = layer.Name       
                #replace problematic chars
                #=> parent::child::layer to parent_child_layer
                layerName = layerName.Replace(':','_')
                f.write("g {0}\n".format(layerName))            
            
            # write faces            
            offset += lastVertCnt
            for face in mesh.Faces:
                if face.IsQuad:
                    f.write("f {0} {1} {2} {3}\n".format(face.A+offset,face.B+offset,face.C+offset,face.D+offset))
                elif face.IsTriangle:
                    f.write("f {0} {1} {2}\n".format(face.A+offset,face.B+offset,face.C+offset))
                f.flush()
            lastVertCnt=mesh.Vertices.Count
SaveObj(path)

Some notes:

You should replace the path and, if on Mac, you also might need to replace the new line character ‘\n’ to ‘\r’. In this example the file will be stored in the directory the script lives in.

This is a minimal example, it scans the document for meshes and export all of them based on the layer. It does not automatically convert Nurbs to Meshes, nor does it anything else. It should work for RhinoMac as well (at least I hope so).

Hey Pascal,

Sorry for the late reply and thanks for getting back to me. For me, if I follow your settings as above, I do not get the ‘g’ like you have. And because ‘Do not export object names’ is selected, I don’t even get the line of code that the ‘g’ is usually part of. Is it possible for you to show me the other tabs of your export, and is it possible to also upload a simple file that you’re using so I can try exactly the same method?

I would upload a file that I’m using for you to test, but a simple mesh in a file is over 55mb and I cannot upload it here…

Hey TomTom

Thanks for this. It does indeed seem to work, but I would think the basic working functionality (and convenience) should be part of Rhino as it was previously. You solution is much appreciated and I will use it for now, but I’m keeping my hopes up that McNeel fixes this problem so I don’t have keep moving files between Rhino 5 and the current version for the years to come.

Cheers!
James

1 Like

Hello - can you reproduce your problem with a simple mesh or a subset of the mesh that you’re actually using, and send us that?

-Pascal

That would be excellent. Thank you.
I cannot upload it here, but it is on my drive here

Just to repeat: An r5 exported obj imported into max would give me a single mesh with 7 distinct mesh elements named __WORK as per the layer name from rhino.

Thanks again for continuing the investigation for me.

Hello - does the attached obj behave as you expect?
rocks.obj (24.1 KB)

-Pascal

Hi Pascal,

No I get all elements mushed together same as the second picture I posted in the first post.

If I inspect the obj file in notepad I can see that the ‘g’ code is not inserted before each mesh element. Yes it is there for the first element, but not every single element, which is what an r5 export does, and what leads to a ‘successful’ import.