The secret of MOI welding

 From:  Michael Gibson
2453.3 In reply to 2453.1 
Hi Micha - the basic problem that you are seeing when importing into Rhino is that Rhino does not support "per face" attributes, it only supports a single vertex list of attributes. So in order to emulate the per-face attributes that are generated when you export a welded OBJ file from MoI, it is going to make duplicated points at import time rather than keeping the original unifed point structure, because the unified structure is not possible for it to hold with its system of defining meshes.


I'll try to explain the difference between "per face" and "per vertex" type systems here, but it will be a bit complex since it involves the actual structure of the data.


Basically the "per vertex" system means that there is a list of vertices each of which contains a 3d point, uv texture point, and a vertex normal for shading. Then faces have a list of numbers that index into those vertices, for example you may have a list of 4 vertices, and then 2 faces that index them. That would look something like this:

Vertex list, length 4

Vertex1 (point 2,5,6 uv 0.5,0.1 shading normal 0,0,1 )
Vertex2 (point 6,2,3 uv 0.2,0.2 shading normal 0,1,0 )
Vertex3 (.. similar data with a point, uv, normal ... )
Vertex4 (.. similar again .. )

Face list:

Face1: ( 1 , 2 , 3 )
Face2: ( 1, 3, 4 )


This is the system that Rhino uses for storing mesh data. So notice with this system that 2 faces can share the same vertex, but they can only do so if they want to share all the same information at once since a single vertex has all of the 3d, uv, and normal information combined into it.

With this system it is not possible to have 2 faces that share the vertex when they want to have the same 3d point only, but have differing UVs or normals, and this kind of situation is exactly what you want to have when you have a welded box model, the shading for each polygon of the box should be different so it needs different normals from the neighboring polygon, but at the same time it has the same point location so it would be good to share that but you can't do a "partial share" with this structure.


Now let us look at the "per face" type system instead, which is more flexible.

With this system instead of there being only one vertex list, there are instead 3 lists, one each for points, uvs and normals and they can all have a different number of items in the list. Then for each face instead of it having just one index for every entry of the face, it actually has 3 index values so a single entry of a face can reference points, uvs, and normals independently.

That system looks like this:

Point list:
Point1: (2.2,5.6,6.1)
Point2: (4.2,5.2,1.2)
Point3: (... xyz value)
Point4: (... xyz value)

UV list:
uv1: (0.5,0.5)
uv2: (1.0,1.0)
uv3: (.. uv value )
uv4: (.. uv value )
uv5: (.. uv value )
uv6: (.. uv value )

Normals list:
normal1: (0.0,0.0,1.0)
normal2: (1.0,0.0,0.0)
normal3: (.. xyz direction value)
normal4: (.. xyz direction value)
normal5: (.. xyz direction value)
normal6: (.. xyz direction value)

Faces list:
face1: ( (1,2,2) (2,1,1) (3,1,4) )
face2: ( (1,3,3) (3,4,2) (2,4,5) )



This is actually how a welded OBJ file is defined, if you open up the OBJ file in a text editor you will be able to see these various lists, you may want to export a box and take a look at that.

Notice how this system is structured differently than the previous system - a triangle face is now in this system not just a list of 3 index numbers, but instead a set of 9 numbers which are 3 sets of 3 index values. Each set of 3 specifies a different point, uv, and normal value.

So with this system it is possible to make cube that uses 8 points for the 3D points, and have those points shared between all the faces of the cube, while at the same time allowing a different vertex normal for each different face.



The way that Rhino defines mesh data follows the first method, while the welded OBJ files that you export from MoI and that you want to have use the second method.

When Rhino imports data where the data is structured using this second method, it sees that it has differing values per face and then makes a bunch of separate entries in its single vertex list so that it can assign different values, that essentially "unwelds" it since the faces will no longer share the same vertex anymore.

If you need to work on this kind of welded data, it is probably not really a good choice to use Rhino for doing the editing, since it does not fundamentally work on that kind of data.

You would probably get some better results with a more polygon-focused program like Silo for instance, polygon modelers can tend to work more directly on the second kind of "per face" data and so would preserve the structure you need rather than breaking that structure into a different system at import time.


Maybe you have assumed that all programs handle polygon meshes in the exact same way? That may be why this seems confusing to you before, because that assumption is not correct, there are different methods for storing polygon data and you seem to want to work with a different method than what Rhino uses...

- Michael