Search Unity

Part of the mesh facing upward

Discussion in 'General Discussion' started by Nakel, Mar 14, 2021.

  1. Nakel

    Nakel

    Joined:
    Sep 28, 2017
    Posts:
    106
    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.
    Code (CSharp):
    1.  
    2.             List<Vector3> verticesToExport = new List<Vector3>();//vertices of the triangles facing upwards.
    3.             List<int> trianglesToExport = new List<int>();//new triangle facing upwards.
    4.             //meshToCut is the original mesh, then I just try to replace it with the new data.
    5.             int[] triangles = meshToCut.triangles;
    6.             Vector3[] vertices = meshToCut.vertices;
    7.  
    8.             for (int i = 0; i < triangles.Length; i += 3)
    9.             {
    10.                 Vector3 corner = vertices[triangles[i]];
    11.                 Vector3 a = vertices[triangles[i + 1]] - corner;
    12.                 Vector3 b = vertices[triangles[i + 2]] - corner;
    13.  
    14.                 float projection = Vector3.Dot(Vector3.Cross(b, a), Vector3.down);
    15.                 if (projection > 0f)
    16.                 {
    17.                     verticesToExport.Add(vertices[triangles[i]]);
    18.                     verticesToExport.Add(vertices[triangles[i + 1]]);
    19.                     verticesToExport.Add(vertices[triangles[i + 2]]);
    20.                     trianglesToExport.Add(triangles[i]);
    21.                     trianglesToExport.Add(triangles[i + 1]);
    22.                     trianglesToExport.Add(triangles[i + 2]);
    23.                 }
    24.             }
    25.             meshToCut.SetVertices(verticesToExport);
    26.             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:
    Screen Shot 2021-03-14 at 13.18.27.png Screen Shot 2021-03-14 at 13.15.07.png Screen Shot 2021-03-14 at 13.19.05.png
     
    Last edited: Mar 14, 2021
  2. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    This:
    Code (csharp):
    1.  
    2. verticesToExport.Add(vertices[triangles[i]]);
    3.  
    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:
    Code (csharp):
    1.  
    2. if (projection > 0f){
    3.    var baseIndex = vertices.Count;
    4.    verticesToExport.Add(vertices[triangles[i]]);
    5.    verticesToExport.Add(vertices[triangles[i + 1]]);
    6.    verticesToExport.Add(vertices[triangles[i + 2]]);
    7.    trianglesToExport.Add(baseIndex + 0);
    8.    trianglesToExport.Add(baseIndex + 1);
    9.    trianglesToExport.Add(baseIndex + 2);
    10. }
    11.  
    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.
     
    Nakel likes this.
  3. Nakel

    Nakel

    Joined:
    Sep 28, 2017
    Posts:
    106
    It did the trick :D

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

    Code (CSharp):
    1. int GetNewIndex( Dictionary<int, int> oldIndexToNew, int oldIndex,
    2.                  Vector3[] oldVertices,
    3.                  List<Vector3> verticesToExport) {
    4.  
    5.     if (!oldIndexToNew.TryGetValue(oldIndex, out int newIndex)) {
    6.         newIndex = vecticesToExport.Count;
    7.         verticesToExport.Add(oldVertices[oldIndex]);
    8.         oldIndexToNew.Add(oldIndex, newIndex);
    9.     }
    10.     return newIndex;
    11. }
    Code (CSharp):
    1. if (projection > 0f)
    2. {    
    3.     trianglesToExport.Add(GetNewIndex(oldIndexToNew, triangles[i],     vertices, verticesToExport));
    4.     trianglesToExport.Add(GetNewIndex(oldIndexToNew, triangles[i + 1], vertices, verticesToExport));
    5.     trianglesToExport.Add(GetNewIndex(oldIndexToNew, triangles[i + 2], vertices, verticesToExport));
    6. }
     
    neginfinity likes this.
  4. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    Yep, that's the right way to do it. Good job.
     
  5. Nakel

    Nakel

    Joined:
    Sep 28, 2017
    Posts:
    106
    thanks to you ;)