Checking if a selected vertex point is on an edge

Hey! So I’ve been fiddling with this one for a bit, and I think I have a solution - but it’s not quite working.

The goal is to only let the user select points on a vertex that are at the shape’s edge - any time the user double clicks on the shape, it should snap the selection to the nearest vertex on an edge. You can see the full example here (relevant code @ line 57):

https://jsfiddle.net/Shuvy/n2y08xof/83/

To support this, I have a function that receives the selected vertex (defined by two vertices) and compares the normals of all facets sharing that vertex. If any two facets share a normal I want the function to return “true” (which will be used by another function to reject the selection).

I can’t for the life of me figure out why it never seems to trigger… I’m mostly curious if anyone else has made this approach work or if I’m missing something vital about the approach. I’m convinced it’s something to do with the comparison at the last step, because it looks like it is successfully pulling the list of relevant facets and their normals whenever called.

var CheckNeighbourFacetsOnSurface = function(edgeVerticeA, edgeVerticeB, pickedFacet, pickMesh, pickMeshVertices, highlightMaterial){
  
    var indices = pickMesh.getIndices();
    var totalFacets = indices.length/3;

    var i = 0;
    var sortedFacetVertexes = [];
    for (i = 0; i < totalFacets; i = i+1) {
        var indiceOne = indices[(i*3)];
        var indiceTwo = indices[(i*3)+1];
        var indiceThree = indices[(i*3)+2];
        sortedFacetVertexes.push(
            [
                new BABYLON.Vector3(
                    pickMeshVertices[indices[(i*3)]*3],
                    pickMeshVertices[(indices[(i*3)]*3)+1],
                    pickMeshVertices[(indices[(i*3)]*3)+2])
                    ,
                new BABYLON.Vector3(
                    pickMeshVertices[indices[(i*3)+1]*3],
                    pickMeshVertices[(indices[(i*3)+1]*3)+1],
                    pickMeshVertices[(indices[(i*3)+1]*3)+2])
                    ,
                new BABYLON.Vector3(
                    pickMeshVertices[indices[(i*3)+2]*3],
                    pickMeshVertices[(indices[(i*3)+2]*3)+1],
                    pickMeshVertices[(indices[(i*3)+2]*3)+2])
                ]);
    
    };

    // get list of all facets that share vertices A & B.
    // It might be worth making the comparisons approximate (e.g. minimum distance based)
    var neighbouringFacetToEdgeID = [];
    var neighbouringFacetNormals = [];
    var neighbouringFacetToEdgePositions = [];
    var pickedFacetNormal;
    var x;
    var y;
    for (i = 0; i < sortedFacetVertexes.length; i = i+1) {
        var isNeighbour = false;
        var shareA = false;
        var shareB = false;
        var isDuplicate = false;
        for (y = 0; y < 3; y = y +1) {
            if(
                sortedFacetVertexes[i][y].x == edgeVerticeA.x &&
                sortedFacetVertexes[i][y].y == edgeVerticeA.y &&
                sortedFacetVertexes[i][y].z == edgeVerticeA.z
                )
                {
                    shareA = true;
                }
        }
        for (y = 0; y < 3; y = y +1) {
        if(
            sortedFacetVertexes[i][y].x == edgeVerticeB.x &&
            sortedFacetVertexes[i][y].y == edgeVerticeB.y &&
            sortedFacetVertexes[i][y].z == edgeVerticeB.z
            )
            {
                shareB = true;
            }
        }
        
        // in addition to making sure we don't count the facet that was picked as a neighbour, we are also grabbing it's normal to compare to other facets.
        if(
            (sortedFacetVertexes[i][0].x == pickedFacet[0].x &&
            sortedFacetVertexes[i][0].y == pickedFacet[0].y &&
            sortedFacetVertexes[i][0].z == pickedFacet[0].z)
            &&
            (sortedFacetVertexes[i][1].x == pickedFacet[1].x &&
            sortedFacetVertexes[i][1].y == pickedFacet[1].y &&
            sortedFacetVertexes[i][1].z == pickedFacet[1].z)
            &&
            (sortedFacetVertexes[i][2].x == pickedFacet[2].x &&
            sortedFacetVertexes[i][2].y == pickedFacet[2].y &&
            sortedFacetVertexes[i][2].z == pickedFacet[2].z)
            )
            {
                isDuplicate = true;
                pickedFacetNormal = pickMesh.getFacetNormal(i);
            }

        if(shareB == true && shareA == true && isDuplicate == false)
            
            {
            isNeighbour = true;
            neighbouringFacetToEdgeID.push(
                i
            );
            neighbouringFacetNormals.push(
                pickMesh.getFacetNormal(i)
            );
            
            neighbouringFacetToEdgePositions.push(
                [
                sortedFacetVertexes[i][0],
                sortedFacetVertexes[i][1],
                sortedFacetVertexes[i][2]
                ]
            );

        
        };
    };

    // Now check if any normals are shared between neighbouring facets and the selected facet
    var normalsShared = false
    var sharedSurfaceNeighbour = [];
    var normalThreshold = 0.1;
    for (i = 0; i < neighbouringFacetNormals.length; i = i+1) {
            if (
                Difference(neighbouringFacetNormals[i].x,pickedFacetNormal.x) < normalThreshold  &&
                Difference(neighbouringFacetNormals[i].y,pickedFacetNormal.y) < normalThreshold &&
                Difference(neighbouringFacetNormals[i].z,pickedFacetNormal.z) < normalThreshold
                )
                {
                    console.log("part" + neighbouringFacetNormals[i] + " | " + pickedFacetNormal);
                    normalsShared = true;
                    sharedSurfaceNeighbour.push(
                    neighbouringFacetNormals[i]
                    );
                }
        
    }
    return normalsShared;
        
};

Sorry that you have no replies yet. Lets see if this bump helps.

I guess it would really help to have a repro in the playground. This is really hard to tell just looking at the code.

Sorry for the lack of reply yesterday.