Search Unity

Get vertices of each edge on mesh and separate by groups like vector3

Discussion in 'Scripting' started by Xaurun, Jul 30, 2014.

  1. Xaurun

    Xaurun

    Joined:
    Jul 29, 2014
    Posts:
    2
    Hi all

    For some time I'm trying to achieve to get all the vertices of a mesh edge and separate by groups, but I'm not good with scripting, my knowledge is out of working with classes and static members.

    I manage not to run this script, I need help to achieve this:
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class GetEdges1 : MonoBehaviour {
    6.    
    7.    
    8.     /// Builds an array of edges that connect to only one triangle.
    9.     /// In other words, the outline of the mesh    
    10.     public static Edge[] BuildManifoldEdges(Mesh mesh)
    11.     {
    12.         // Build a edge list for all unique edges in the mesh
    13.         Edge[] edges = BuildEdges(mesh.vertexCount, mesh.triangles);
    14.        
    15.         // We only want edges that connect to a single triangle
    16.         ArrayList culledEdges = new ArrayList();
    17.         foreach (Edge edge in edges)
    18.         {
    19.             if (edge.faceIndex[0] == edge.faceIndex[1])
    20.             {
    21.                 culledEdges.Add(edge);
    22.             }
    23.         }
    24.        
    25.         return culledEdges.ToArray(typeof(Edge)) as Edge[];
    26.     }
    27.    
    28.     /// Builds an array of unique edges
    29.     /// This requires that your mesh has all vertices welded. However on import, Unity has to split
    30.     /// vertices at uv seams and normal seams. Thus for a mesh with seams in your mesh you
    31.     /// will get two edges adjoining one triangle.
    32.     /// Often this is not a problem but you can fix it by welding vertices
    33.     /// and passing in the triangle array of the welded vertices.
    34.     public static Edge[] BuildEdges(int vertexCount, int[] triangleArray)
    35.     {
    36.         int maxEdgeCount = triangleArray.Length;
    37.         int[] firstEdge = new int[vertexCount + maxEdgeCount];
    38.         int nextEdge = vertexCount;
    39.         int triangleCount = triangleArray.Length / 3;
    40.        
    41.         for (int a = 0; a < vertexCount; a++)
    42.             firstEdge[a] = -1;
    43.        
    44.         // First pass over all triangles. This finds all the edges satisfying the
    45.         // condition that the first vertex index is less than the second vertex index
    46.         // when the direction from the first vertex to the second vertex represents
    47.         // a counterclockwise winding around the triangle to which the edge belongs.
    48.         // For each edge found, the edge index is stored in a linked list of edges
    49.         // belonging to the lower-numbered vertex index i. This allows us to quickly
    50.         // find an edge in the second pass whose higher-numbered vertex index is i.
    51.         Edge[] edgeArray = new Edge[maxEdgeCount];
    52.        
    53.         int edgeCount = 0;
    54.         for (int a = 0; a < triangleCount; a++)
    55.         {
    56.             int i1 = triangleArray[a * 3 + 2];
    57.             for (int b = 0; b < 3; b++)
    58.             {
    59.                 int i2 = triangleArray[a * 3 + b];
    60.                 if (i1 < i2)
    61.                 {
    62.                     Edge newEdge = new Edge();
    63.                     newEdge.vertexIndex[0] = i1;
    64.                     newEdge.vertexIndex[1] = i2;
    65.                     newEdge.faceIndex[0] = a;
    66.                     newEdge.faceIndex[1] = a;
    67.                     edgeArray[edgeCount] = newEdge;
    68.                    
    69.                     int edgeIndex = firstEdge[i1];
    70.                     if (edgeIndex == -1)
    71.                     {
    72.                         firstEdge[i1] = edgeCount;
    73.                     }
    74.                     else
    75.                     {
    76.                         while (true)
    77.                         {
    78.                             int index = firstEdge[nextEdge + edgeIndex];
    79.                             if (index == -1)
    80.                             {
    81.                                 firstEdge[nextEdge + edgeIndex] = edgeCount;
    82.                                 break;
    83.                             }
    84.                            
    85.                             edgeIndex = index;
    86.                         }
    87.                     }
    88.                    
    89.                     firstEdge[nextEdge + edgeCount] = -1;
    90.                     edgeCount++;
    91.                 }
    92.                
    93.                 i1 = i2;
    94.             }
    95.         }
    96.        
    97.         // Second pass over all triangles. This finds all the edges satisfying the
    98.         // condition that the first vertex index is greater than the second vertex index
    99.         // when the direction from the first vertex to the second vertex represents
    100.         // a counterclockwise winding around the triangle to which the edge belongs.
    101.         // For each of these edges, the same edge should have already been found in
    102.         // the first pass for a different triangle. Of course we might have edges with only one triangle
    103.         // in that case we just add the edge here
    104.         // So we search the list of edges
    105.         // for the higher-numbered vertex index for the matching edge and fill in the
    106.         // second triangle index. The maximum number of comparisons in this search for
    107.         // any vertex is the number of edges having that vertex as an endpoint.
    108.        
    109.         for (int a = 0; a < triangleCount; a++)
    110.         {
    111.             int i1 = triangleArray[a * 3 + 2];
    112.             for (int b = 0; b < 3; b++)
    113.             {
    114.                 int i2 = triangleArray[a * 3 + b];
    115.                 if (i1 > i2)
    116.                 {
    117.                     bool foundEdge = false;
    118.                     for (int edgeIndex = firstEdge[i2]; edgeIndex != -1; edgeIndex = firstEdge[nextEdge + edgeIndex])
    119.                     {
    120.                         Edge edge = edgeArray[edgeIndex];
    121.                         if ((edge.vertexIndex[1] == i1) && (edge.faceIndex[0] == edge.faceIndex[1]))
    122.                         {
    123.                             edgeArray[edgeIndex].faceIndex[1] = a;
    124.                             foundEdge = true;
    125.                             break;
    126.                         }
    127.                     }
    128.                    
    129.                     if (!foundEdge)
    130.                     {
    131.                         Edge newEdge = new Edge();
    132.                         newEdge.vertexIndex[0] = i1;
    133.                         newEdge.vertexIndex[1] = i2;
    134.                         newEdge.faceIndex[0] = a;
    135.                         newEdge.faceIndex[1] = a;
    136.                         edgeArray[edgeCount] = newEdge;
    137.                         edgeCount++;
    138.                     }
    139.                 }
    140.                
    141.                 i1 = i2;
    142.             }
    143.         }
    144.        
    145.         Edge[] compactedEdges = new Edge[edgeCount];
    146.         for (int e = 0; e < edgeCount; e++)
    147.             compactedEdges[e] = edgeArray[e];
    148.        
    149.         /*for (int i = 0; i < compactedEdges.Length; i++)
    150.         {
    151.             //print(i + ": " + edges[i].v1 + ", " + edges[i].v2);
    152.             Debug.DrawLine(compactedEdges[i].vertexIndex, compactedEdges[i].faceIndex[i], Color.yellow);
    153.         }*/
    154.        
    155.         return compactedEdges;
    156.     }
    157.    
    158.    
    159.     public class Edge
    160.     {
    161.         // The indiex to each vertex
    162.         public int[] vertexIndex = new int[2];
    163.         // The index into the face.
    164.         // (faceindex[0] == faceindex[1] means the edge connects to only one triangle)
    165.         public int[] faceIndex = new int[2];
    166.     }
    167.  
    168. }
    169.  
    Here a detail of the process I think it can be

    1 - get all the triangles that have near normal Vector3.Up, it may be something like this
    Code (CSharp):
    1. if (Vector3.Angle(Vector3.up, mesh.normals[i]) > 20){
    2.    // Not included in the list of triangles
    3. }
    2 - determine all edges of the mesh and separate groups without selecting the internal vertices, In the image selected triangles are blue.

    other case

    3 - save each group of vertices as vectors in an array, but ordered, no matter where Begin or in which direction. Maybe ArrayList of groups of vertices.
    30005-2.jpg
     
    Last edited: Aug 8, 2014
  2. Xaurun

    Xaurun

    Joined:
    Jul 29, 2014
    Posts:
    2
    People, I need help, i tried but I failed.

    I started getting the coordinates of the vertices forming the edge of the boundary, instantiating a cube at each vertex and this is what I get.

    Sin título.jpg

    Assumes that hubs should be created along the red line, but it is not.

    that's what I'm doing wrong?
    this is what I'm using

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PointsCreator : MonoBehaviour {
    5.  
    6.     //compactedEdges.vertexIndex[1] == i1) && (edge.faceIndex[0]
    7.     private Mesh mesh;
    8.     private GetEdges1.Edge[] edgesz;
    9.     public Transform prefab;
    10.     private Vector3[]groupA;
    11.  
    12.     void Start() {
    13.             Debug.Log("Start");
    14.             mesh = this.GetComponent<MeshFilter>().mesh;
    15.             edgesz = GetEdges1.BuildManifoldEdges(mesh);
    16.             groupA = new Vector3[edgesz.Length];
    17.    
    18.         print("edgesz: " + edgesz.Length);
    19.         for (int i = 0; i < edgesz.Length; i++) {
    20.                 Vector3 punto = mesh.vertices[mesh.triangles[edgesz[i].faceIndex[0]]];
    21.                 //Debug.Log(punto);
    22.                 groupA[i] = punto;
    23.             }
    24.  
    25.         int f = 0;
    26.         while (f < groupA.Length) {
    27.             Transform clone = Instantiate(prefab, groupA[f], Quaternion.identity) as Transform;
    28.             f++;
    29.         }
    30.         Debug.Log("Finish");
    31.     }
    32. }
    33.