Part of the mesh facing upward

Hey guys,
I have this code that gives me back the vertices of the triangles facing upwards, works but the moment I set the triangles too I believe is on disorder so I get a total weird mesh.

How could I solve this, in the way that I will only have the vertices and triangles in a new mesh.

            List<Vector3> verticesToExport = new List<Vector3>();//vertices of the triangles facing upwards.
            List<int> trianglesToExport = new List<int>();//new triangle facing upwards.
            //meshToCut is the original mesh, then I just try to replace it with the new data.
            int[] triangles = meshToCut.triangles;
            Vector3[] vertices = meshToCut.vertices;

            for (int i = 0; i < triangles.Length; i += 3)
            {
                Vector3 corner = vertices[triangles[i]];
                Vector3 a = vertices[triangles[i + 1]] - corner;
                Vector3 b = vertices[triangles[i + 2]] - corner;

                float projection = Vector3.Dot(Vector3.Cross(b, a), Vector3.down);
                if (projection > 0f)
                {
                    verticesToExport.Add(vertices[triangles[i]]);
                    verticesToExport.Add(vertices[triangles[i + 1]]);
                    verticesToExport.Add(vertices[triangles[i + 2]]);
                    trianglesToExport.Add(triangles[i]);
                    trianglesToExport.Add(triangles[i + 1]);
                    trianglesToExport.Add(triangles[i + 2]);
                }
            }
            meshToCut.SetVertices(verticesToExport);
            meshToCut.SetTriangles(trianglesToExport, 0);//probably I'm doing wrong here!

EDIT:

  1. The model I’m trying to separate:
  2. This is what happens if I just take the vertices and triangulate them again:
  3. The result I get from the code above:
    6933594--814359--Screen Shot 2021-03-14 at 13.18.27.png 6933594--814356--Screen Shot 2021-03-14 at 13.15.07.png 6933594--814362--Screen Shot 2021-03-14 at 13.19.05.png

This:

verticesToExport.Add(vertices[triangles[i]]);

is wrong and ain’t going to fly.

The mesh is indexed, meaning each triangle vertex is an INDEX referring to a vertex within a vertex array.

When you are building a new mesh, you’re building a new vertex array, and therefore you can’t use old indexes, unless the array is completely identical.

Therefore you’ll to record which vertices of the original mesh you’re going to use, save only THOSE into the new mesh, record which new index corresponds to which old index, and then remap indices.

You can also do this:

if (projection > 0f){
   var baseIndex = vertices.Count;
   verticesToExport.Add(vertices[triangles[i]]);
   verticesToExport.Add(vertices[triangles[i + 1]]);
   verticesToExport.Add(vertices[triangles[i + 2]]);
   trianglesToExport.Add(baseIndex + 0);
   trianglesToExport.Add(baseIndex + 1);
   trianglesToExport.Add(baseIndex + 2);
}

In this case the mesh will display correctly, but it will be rendered inefficiently, as no vertices will be shared between triangles. So if you want to do it properly, you should remap.

1 Like

It did the trick :smile:

In my case I really don’t need to fix the vertices but if someone needs you can do it this way:

int GetNewIndex( Dictionary<int, int> oldIndexToNew, int oldIndex,
                 Vector3[] oldVertices,
                 List<Vector3> verticesToExport) {

    if (!oldIndexToNew.TryGetValue(oldIndex, out int newIndex)) {
        newIndex = vecticesToExport.Count;
        verticesToExport.Add(oldVertices[oldIndex]);
        oldIndexToNew.Add(oldIndex, newIndex);
    }
    return newIndex;
}
if (projection > 0f)
{    
    trianglesToExport.Add(GetNewIndex(oldIndexToNew, triangles[i],     vertices, verticesToExport));
    trianglesToExport.Add(GetNewIndex(oldIndexToNew, triangles[i + 1], vertices, verticesToExport));
    trianglesToExport.Add(GetNewIndex(oldIndexToNew, triangles[i + 2], vertices, verticesToExport));
}
1 Like

Yep, that’s the right way to do it. Good job.

thanks to you :wink: