How to find triangle index from vertices of a mesh?

Hi!

I am modifying mesh at runtime and to perform some operations, I need to find out which vertex belongs to a triangle?

This is the data I have

int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices;

Any guidance or direction would be great, thank you!

A triangle is, by its very nature, that already i.e. it’s 3 indices in the vertices array. A single vertex may be shared by multiple triangles. Or do you mean something else?

This is what I want to figure out… more specialized case is that I want to find out the first triangle which the vertex is a part of

As it was already mentioned, the index of a vertex is already the first hint. The triangles array contains vertex indices in groups of 3. So you have to find the index of the vertex in question in the triangles array and figure out which the other two vertices are. Since they come in groups of 3, you can simply divide the index position in the triangles array by 3 which gives you the triangle index (thanks to integer division). By multiplying the result again by 3 you get the first index of the triangle. Add 1 and 2 to that index and you get the other 2 indices. Of course out of those 3 one is the vertex you started with.

Note that a vertex may have multiple vertices that share the same (similar) position but have other vertex attributes different. For example a Unity default cube has 24 vertices but a cube logically only has 8. That’s because at each corner of the mesh you will have 3 duplicates of the same vertex but each with a different normal vector and uv coordinates. So when you start with a single vertex, you may need / want to find other vertices at the same position. Though this depends on your mesh.

How or where did you actually get your first vertex from?

As was already mentioned, but I will provide you with some code: (untested)

int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices;

List<int>[] vertexIndexToTrianglesLookup = new[vertices.Length];

for(int i=0;i<triangles.Length;i++){

    int vertInd = triangles[i];
    int triangleIndex = i/3;

    if(vertexIndexToTrianglesLookup[vertInd] == null){
          vertexIndexToTrianglesLookup[vertInd] = new List<int>(1);
    }

    vertexIndexToTrianglesLookup[vertInd].Add(triangleIndex);
}

Obviously this code do not merge vertices. If you got two vertex in the same position they are considered distinct.

I have a demo of finding a triangle by raycast in a scene called ClickTriangle in my MakeGeo project.

Here’s the code:

You can run it fully set up in a test scene in the project.

There’s a bunch more Unity procgen stuff in there too, just a hodgepodge of stuff.

MakeGeo is presently hosted at these locations:

https://bitbucket.org/kurtdekker/makegeo

Thank you! I will try this out

Basically what I am trying to achieve is:

  • I created a simple procedural mesh
  • When I click on the mesh, I want to sub-divide the clicked triangle and it’s neighboring triangle within a certain radius

So far I have written the code which finds out the closest vertex to the clicked point… and then also the code to sub divide the triangle. Currently just trying to figure out finding the neighboring triangles so I can sub-divide those

Thanks I’ll check this too

I have tried the simple raycast method… Any way to figure out neighboring triangles as well with raycast approach?

I suppose you could widen and do more raycasts, but you’d have to know how much wider and there’s always the chance you miss a small triangle.

When finding neighbors be aware that with a lot of geometry, vertices are not truly shared. There just happens to be two (or more) verts located at exactly the same spot in space, one involved in one face, one involved in another. Just assume this is the case, because normals and other data must be bound to a single vertex, so anything with a faceted look will absolutely have multiple vertices at each point. It’s up to you to collect all verts that are “close enough” to constitute what you think is the same spot in space.

If you want a code example of the concept of shared vs not shared verts, in that same MakeGeo project, check this:

https://github.com/kurtdekker/makegeo/blob/master/makegeo/Assets/SharedvsNonSharedVertices/SharedvsNonSharedVertices.cs

** @ktest112233 **
Recently in my project I had to merge the closest vertices, but the mesh was huge.
You have to create some spatial space partitioning because brute force method would take to long.

SpatialHashing helped me greatly.

This might be also used to find vertices in distance from some point in space.