Is there any way to get the vertices of a given mesh facet? (Or get neighbouring facets?)

I’ve been trying to find a solution for getting the neighbouring facets of facet i on a mesh. I couldn’t find any obvious solution for easily getting neighbours, but I figured each facet would have max three neighbours and a neighbour would be any facet sharing two vertices with facet i. However, while I seem to be able to get a range of information about facet i using facet data, the vertices that make up that facet do not seem readily available. So, I thought I’d ask if anyone else knows of a clever way to get this vertices information, or better yet, get the neighbouring facets. Thanks!

Hi @robska17 and welcome to the forum

This is not always true.

Imagine a set of fins. From one facet edge you could have multiple facets along that edge at various angles sticking out from that edge. Also if the mesh is not properly formed you could have a facet ABC with points DE along AB and facets ADF, DEG and EBH all neighbouring ABC.

You can uses the indices from mesh.getIndices() see Updating Vertices | Babylon.js Documentation.

Here is a rough and ready approach. You will need to check that the results are accurate.

https://www.babylonjs-playground.com/#24AF90

Thanks for the detailed response! I’ll play around with your code to confirm whether it gets the results I’m looking for and get back to you with an update!

So, unfortunately the code you wrote didn’t quite solve my problem as the facet identifiers didn’t match up with the facet IDs in mesh facet data. However, the good news is that it did give me some guidance to apply to my own code and I’ve now been able to produce the results I was looking for, so thanks!

I was able to get the indices, like in your example, then I was able to match those up with the vertex data from the mesh. From there, I was able to put together an array of vector3 containing the coordinates of each corner of each facet and compile a range of information on each facet into an array of JSON objects.

Here’s an example of my solution:

var indices = mesh.getIndices();

var vertices = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);

var groupedVertices = [];

for(var i = 0; i < vertices.length / 3; i++) {

    var pos = new BABYLON.Vector3(0, 0, 0);

    pos.x = vertices[3* i];

    pos.z = vertices[3 * i + 2];

    groupedVertices.push(pos);

}

var sortedVertices = [];

for(var i = 0; i < indices.length; i++) {

    sortedVertices.push(groupedVertices[indices[i]]);

}

for(var i = 0; i < sortedVertices.length / 3; i++) {

    var tri = [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 0, 0)];

    tri[0].x = sortedVertices[3 * i].x;

    tri[0].z = sortedVertices[3 * i].z;

    tri[1].x = sortedVertices[3 * i + 1].x;

    tri[1].z = sortedVertices[3 * i + 1].z;

    tri[2].x = sortedVertices[3 * i + 2].x;

    tri[2].z = sortedVertices[3 * i + 2].z;

    triObject = {id: i, a: tri[0], b: tri[1], c: tri[2], centre: new BABYLON.Vector3(0 , 0, 0), neighbours: []};

    tris.push(triObject);

}

for(var i = 0; i < mesh.facetNb; i++) {

    var tri = tris[i];

    tri.centre = mesh.getFacetPosition(i);

    var neighbours = [];

    for(var j = 0; j < tris.length; j++) {

        var matchingVerts = 0;

        if(tris[j] != tri) {

            if(tri.a.x == tris[j].a.x && tri.a.z == tris[j].a.z ||

            tri.a.x == tris[j].b.x && tri.a.z == tris[j].b.z ||

            tri.a.x == tris[j].c.x && tri.a.z == tris[j].c.z) {

                matchingVerts++;

            }

            if(tri.b.x == tris[j].a.x && tri.b.z == tris[j].a.z ||

            tri.b.x == tris[j].b.x && tri.b.z == tris[j].b.z ||

            tri.b.x == tris[j].c.x && tri.b.z == tris[j].c.z) {

                matchingVerts++;

            }

            if(tri.c.x == tris[j].a.x && tri.c.z == tris[j].a.z ||

            tri.c.x == tris[j].b.x && tri.c.z == tris[j].b.z ||

            tri.c.x == tris[j].c.x && tri.c.z == tris[j].c.z) {

                matchingVerts++;

            }

            if(matchingVerts == 2) {

                var neighbour = {id: j};

                neighbours.push(neighbour);

            }

        }

    }

    tri.neighbours = neighbours;

}