Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

outside egdes of a mesh

Discussion in 'Scripting' started by stickadtroja, Nov 28, 2015.

  1. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    i have this script that takes an mesh of any shape, and determines which edges, pair of vertices, that are on the "outside", the outlining edges. it does this by going through all the edges of all triangles and check for dublicates. if there are any dublicates, it means that another triangle are using the same vertices as an edge, and thus its not a outside edge.
    then i use these outside edges to place "doors", since i use the meshes to act as rooms in a level layout.

    the problem is that, though this works for flat meshes, as soon as i put a mesh with some height difference, it doesnt work anymore. see the picture below. the only difference between these meshes is that i pulled some vertices up and down. they have the same uvs, and the same smoothing groups. but still the upper one have doors place all over, and the lower one only on the outside edges.




    this is the code;
    Code (CSharp):
    1.         Edge[] roomMeshEdges = new Edge[meshTriangles.Length];
    2.  
    3.         for (int i = 0; i < meshTriangles.Length; i += 3)
    4.         {
    5.             int p1 = meshTriangles[i];
    6.             int p2 = meshTriangles[i + 1];
    7.             int p3 = meshTriangles[i + 2];
    8.  
    9.             roomMeshEdges[i] = new Edge(p1,p2);
    10.             roomMeshEdges[i + 1] = new Edge(p2,p3);
    11.             roomMeshEdges[i + 2] = new Edge(p3,p1);
    12.         }
    13.  
    14.  
    15.         Edge[] outsideMeshEdges = new Edge[roomMeshEdges.Length];
    16.         int edgeCount = 0;
    17.    
    18.         for(int j = 0; j < roomMeshEdges.Length; j ++)
    19.         {
    20.             bool hasDublicate = false;
    21.            
    22.             for(int k = 0; k < roomMeshEdges.Length; k++)
    23.             {
    24.                 if(k != j)
    25.                 {
    26.                     if(roomMeshEdges[j].AreSame(roomMeshEdges[k]))
    27.                         hasDublicate = true;
    28.                 }
    29.             }
    30.             if(!hasDublicate)
    31.             {
    32.  
    33.                 outsideMeshEdges[edgeCount] = roomMeshEdges[j];
    34.                 edgeCount++;
    35.                
    36.             }
    37.         }
    38.  
    39.         System.Array.Resize (ref outsideMeshEdges, edgeCount);
    grateful for any suggestions!
     
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    How does the AreSame method work? Is it possible that you are failing because of the order of the points in the triangle? Do all of your normals point the correct way?

    Its late here, just grasping at straws.
     
  3. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    this is my edge class. it doenst have the vertex position, only the index in the mesh.vertices list
    Code (CSharp):
    1. private class Edge
    2.     {
    3.         public int point1, point2;
    4.  
    5.         public Edge (int inPoint1, int inPoint2)
    6.         {
    7.             point1 = inPoint1;
    8.             point2 = inPoint2;
    9.         }
    10.  
    11.         public bool AreSame (Edge other)
    12.         {
    13.             int inPoint1 = other.point1;
    14.             int inPoint2 = other.point2;
    15.  
    16.             if (point1 == inPoint1)
    17.             {
    18.                 if (point2 == inPoint2)
    19.                     return true;
    20.             }
    21.             if (point1 == inPoint2)
    22.             {
    23.                 if (point2 == inPoint1)
    24.                     return true;
    25.             }
    26.             return false;  
    27.         }
    28.     }
    the code should make sure, it doesnt matter what order of vertices.

    what do you mean by normals? that is only a concern if they are split, like a hard edge right? both the meshes are smooth, ie 1 normal per vertex.
     
  4. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    i made some progress; if i put the import settings of the mesh to have normals and tangents to be calculated with a angle of 180 instead of imported, it works.
    to me this is weird, since the mesh has no hard edges, split normals when i export it from 3dsmax. and i think i have the right setting in the fbx exporter aswell.
    the mesh also show up as all smooth in the unity scene viewport. but somehow it thinks that some normals are split, so it makes double vertices in that point, and thus my AreSame method dont work. i think. some insight into this would be nice.
     
  5. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    I would think this has to do with how the mesh is created and what uv mapping is applied. A single connecting point can sometimes use 2 separate vertex points (in the exact same 3d position) because the uv texture coordinate needs to be different between triangles. This can result in a "middle" vert only being used by a single triangle.

    Less common but technically possible is the same doubling of verts for applying different normals. Not sure why you would want this since it would essentially create unrealistic seems, but maybe that's desired in some case.
     
    Kiwasi likes this.
  6. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    i dont belive the faulty uvs are the cause. if so, how can it work if i set normals to be calculated instead of imported? the uvs should be the same in both cases?

    dont know what you mean with last part. are you talking about hard edges? if so, the mesh shouldnt have any, since in 3ds max i only have one smoothing group.

    im grateful for the suggestions though. any more insights into this would be much appriciated.
     
  7. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    If you have duplicate verts for uv purposes, the calculated normals may simply be wrong. It isn't always very noticeable, especially if the texture change is significant (a slight shadow at the creases would blend in).

    Either way, without duplicate verts your logic seems to make sense.
     
    Kiwasi likes this.
  8. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    Any vertex can only ever have one unique set of vertex attributes in Unity, if the importer feels it can't comply with this rule without changing the appearance of the mesh it splits the vertices into unique ones. Finding out exactly why it happens can be a bit tricky. You can easily see if it happens by counting the triangles/vertices in your modeling application, and comparing the numbers to those on the imported mesh in Unity. The preview window gives short statistics for this.

    You could replace the index logic of the Edge object you got to use Vector3's instead and compare these instead. If two pairs of Vector3's are within some minimal threshold of eachother treat the edge as the same.
     
    Kiwasi likes this.