joesfer / Voronoi-Shattering

Maya plugin implementing geometry fracturing based on Voronoi Diagrams (Voronoi Shattering). Visit http://www.joesfer.com/?p=60 for further information.
http://www.joesfer.com/?p=60
GNU Lesser General Public License v3.0
42 stars 9 forks source link

Preserving Normals and UVs #3

Open sabotage3d opened 9 years ago

sabotage3d commented 9 years ago

Hello is it currently possible to preserve the original normals and uvs of the mesh after the shattering. If it is not, is it hard to implement ?

joesfer commented 9 years ago

Normals should be relatively easy as all it takes is to preserve the original normals from the mesh surface, and consider the new interior faces as flat, since they're generated from plane cuts.

UVs are a harder problem: we can also preserve the original texture mapping on the surface (if present), but it is not immediately clear what the coordinates on the interior faces should be, as they define a volume now and not a surface. Normally one could use a procedural shader (e.g. noise 3D) for the interior, but that's just working around the fact of not having UVs in that area.

sabotage3d commented 9 years ago

Thanks a lot. How can we preserve the normals and uvs for the outside faces ? Do you have a simple example ?

joesfer commented 9 years ago

Normals should already be preserved as mentioned above (the resulting objects are not faceted but should have the same curvature than the original surface). UVs are not supported in the provided implementation.

sabotage3d commented 9 years ago

Isn't that recalculating the normals ?

//MVectorArray normals;
            for( size_t i = 0; i < triangleIsInterior.size(); i++ ) {
                if ( triangleIsInterior[ i ] ) {
                    MVector normal;
                    resMesh.getPolygonNormal( i, normal );

                    int triangleVertices[3];
                    resMesh.getPolygonTriangleVertices( i, 0, triangleVertices );

                    for( int j = 0; j < 3; j++ ) {
                        //resMesh.setFaceColor( MColor(  1, 0, 0 ), i );
                        resMesh.setFaceVertexNormal( normal, i, triangleVertices[ j ] );
                    }
                }
            }
joesfer commented 9 years ago

That's setting the normals on the interior triangles, which is the new faces created after the cuts (depending on the cut, the resulting piece can be completely flat, or have some of the original surface remaining. I think this is better shown in the images of the original blog post). Interior triangles will always be flat.

But you are right, however, the code is not explicitly copying the original normals around but creating the mesh from scratch and then flattening the interior faces. This seems to indicate (it's been a while since I coded this) that Maya is doing some normal averaging by default which explains the smoothness of the outer surface and the need for explicit flattening. To keep the exact original normals, the meshCut method would have to be extended to include the original array, so that these can be appended to the newly resulting array of vertices. Probably the easiest approach would be to simply copy the original normals and assume the normals on newly created vertices match those of the cutting plane.

sabotage3d commented 9 years ago

Yeah but we have lets say 8 vertices of a box and 8 vertex normals. We do the cut we end up with 9 or smaller number depending on the extra vertices from the triangulation. How do we match those to the original array ?

joesfer commented 9 years ago

Yes, you could end up with an arbitrary number of vertices, more, or less than the original. The procedure would be to copy the original array to your "working set" of vertices, and then have each edge splitting operation (which is always done one by one, so it's well-defined), keep the normal of the vertex which is not splitting, and then add a new normal to the newly created vertices. I seem to remember (though I suggest you double-check the code) that new vertices are simply appended at the end of the vertex array, so you wouldn't need to shuffle existing normals around but just append them as well. Basically, the whole operation is parallel to what we do with the position array, but with an additional normals array.

sabotage3d commented 9 years ago

Thanks I will try that .