2

I would like to remove duplicate faces from an array of faces - I have attempted some code below but I am not sure how to complete it.

Firstly I was suprised to find that:

new THREE.Vector3(0,0,0) == new THREE.Vector3(0,0,0)

yields false (I would expect it to yield True) and furthermore that the code below also yields false (again I would expect it to yield True).

    var triangleGeometry = new THREE.Geometry(); 
    triangleGeometry.vertices.push(new THREE.Vector3( 0.0,  1.0, 0.0)); 
    triangleGeometry.vertices.push(new THREE.Vector3(-1.0, -1.0, 0.0)); 
    triangleGeometry.vertices.push(new THREE.Vector3( 1.0, -1.0, 0.0)); 
    triangleGeometry.faces.push(new THREE.Face3(0, 1, 2)); 

    var triangleGeometry2 = new THREE.Geometry(); 
    triangleGeometry2.vertices.push(new THREE.Vector3( 0.0,  1.0, 0.0)); 
    triangleGeometry2.vertices.push(new THREE.Vector3(-1.0, -1.0, 0.0)); 
    triangleGeometry2.vertices.push(new THREE.Vector3( 1.0, -1.0, 0.0)); 
    triangleGeometry2.faces.push(new THREE.Face3(0, 1, 2));

    triangleGeometry2.faces[0] === triangleGeometry.faces[0] - yields false

As for my code to determine whether a face is already in an array of faces I have written the following:

            function faceInArray(arrayOfFaces,face)
            {   // https://stackoverflow.com/questions/29759480/how-to-customize-object-equality-for-javascript-set
                // Determine whether a face is in an array of faces
                // The ES6 Set object does not have any compare methods or custom compare extensibility.
                // For this reason this function will be called before adding an face to an array of faces 
                // to ensure that duplicate faces are not placed in an array

                for(let i = 0; i < arrayOfFaces.length; i++)
                {
                    vertexaFaceFromArray = buildingGeometry.vertices[arrayOfFaces[i].a]
                    vertexbFaceFromArray = buildingGeometry.vertices[arrayOfFaces[i].b]
                    vertexcFaceFromArray = buildingGeometry.vertices[arrayOfFaces[i].c]

                    vertexaFace = buildingGeometry.vertices[face.a]
                    vertexbFace = buildingGeometry.vertices[face.b]
                    vertexcFace = buildingGeometry.vertices[face.c]

                    // Compare the vertices in each face I'm not sure how to do this?


                }
            }

Now I'm unsure how to procede from here as simply checking vertex1 == vertex2 doesn't work as I demostrated in the first block of code. Do I really need to extract the x,y and z coordinate for each face when comparing them? Furthermore does the order of the vertices matter?

Anton James
  • 191
  • 2
  • 5
  • 15
  • Hi Anton, could you please update your question with an simple example of your current scenario and what have you tried so far? – rafaelcastrocouto Sep 17 '17 at 17:03
  • 1
    @rafaelcastrocouto thankyou for your comment I've added a lot more detail to my question - I realize that initially it was too simple. – Anton James Sep 18 '17 at 00:30

1 Answers1

3

The reason this does not work: new THREE.Vector3(0,0,0) == new THREE.Vector3(0,0,0) Is that == in this case checks if two values are references to the same object. But your vectors are different objects that happen to have the same values for x, y and z. You should instead use three.js equals function on Vector3:

new THREE.Vector3(0,0,0).equals(new THREE.Vector3(0,0,0))

So your function can work like this:

function faceInArray(arrayOfFaces, face) {
    for(let i = 0; i < arrayOfFaces.length; i++) {
        vertexaFaceFromArray = buildingGeometry.vertices[arrayOfFaces[i].a]
        vertexbFaceFromArray = buildingGeometry.vertices[arrayOfFaces[i].b]
        vertexcFaceFromArray = buildingGeometry.vertices[arrayOfFaces[i].c]

        vertexaFace = buildingGeometry.vertices[face.a]
        vertexbFace = buildingGeometry.vertices[face.b]
        vertexcFace = buildingGeometry.vertices[face.c]

        if (vertexaFaceFromArray.equals(vertexaFace) && 
            vertexbFaceFromArray.equals(vertexbFace) && 
            vertexcFaceFromArray.equals(vertexcFace)) {
            return true;
        }
    }
    return false;
}

BUT, of course, this only checks if each face has vertices in exact same order as the input face. It depends on what you are going to use this for, but in principle the face (1, 2, 3) is the same as the faces (2, 3, 1) and (3, 1, 2).

Furthermore, if your faces are two sided, then it is also the same as any order of the vertices. I.e. (3, 2, 1), (2, 1, 3) and (1, 3, 2). So you might want to extend the code to check for these cases in addition.

Holger L
  • 1,517
  • 1
  • 14
  • 20