How can I get a group of triangles that comprise a cube face?

I’m trying to get the triangles that create a cube mesh face.

This is what I tried:
The box geometry mesh turns to have a groups array of 6 items. I assumed that since a cube has 6 faces, each of this objects was storing data related to the faces than comprised the cube face.
image

However, in the following code I’m getting the indices stored in the first group and getting the vertices by using the mesh.getVertexPosition() to render lines from those points.

    const topFaceTrgl = groups[0];
    for (
      let i = topFaceTrgl.start;
      i < topFaceTrgl.start + topFaceTrgl.count;
      i += 3
    ) {
      const v1 = mesh.getVertexPosition(
        i,
        new THREE.Vector3()
      );
      const v2 = mesh.getVertexPosition(
        i + 1,
        new THREE.Vector3()
      );
      const v3 = mesh.getVertexPosition(
        i + 2,
        new THREE.Vector3()
      );

      const lineGeo = new THREE.BufferGeometry();
      const lineBufAtrb = new THREE.BufferAttribute(
        new Float32Array(4 * 3),
        3
      );
      lineBufAtrb.setXYZ(0, v1.x, v1.y, v1.z);
      lineBufAtrb.setXYZ(1, v2.x, v2.y, v2.z);
      lineBufAtrb.setXYZ(2, v3.x, v3.y, v3.z);
      lineBufAtrb.setXYZ(4, v1.x, v1.y, v1.z);
      lineGeo.setAttribute("position", lineBufAtrb);
      const lineMat = new THREE.LineBasicMaterial({
        color: "white",
        transparent: true,
      });
      const lineMesh = new THREE.Line(lineGeo, lineMat);
      scene.add(lineMesh);
}

As result, the following lines are rendered:
image

image

Instead, I was expecting the lines to draw one of the cube faces like this:
image

What it should be the process to get the grouped triangles that builds a cube face?

These are triangles, so except for simple cases like the cube, keep in mind finding “2 triangles that make up a square face in an arbitrary msh” would often not be an option at all (for cube it is though.)

To find 2 triangles that form a square face of a cube you can take advantage of the fact that the “outside” edges will have length of 1x and the inside edge has a length of 1x√2. So just:

  1. Pick a face (using raycasting for example.)
  2. Calculate distances between all 3 vertex pairs in the face (A-B, B-C, A-C.) Pick the pair with the longest result.
  3. Iterate through all other triangles in the cube and pick one that shares the two vertices from point 2 with the original face, and is not the original face.
  1. I’m not allowed to use raycast since it should be done as part of a pre processed step
  2. and 3. looks promising but I was expecting three.js to have that information organized or a simpler solution before going for the pure mathematics option.

Doesn’t it make sense to find 6 objects inside the geometry.groups property that should correspond to the vertices of each triangle for a single face?
image

That was just an example - feel free to pick the triangle in whichever way you desire :relieved:

Neither three, nor any other software / library, will knows of things you don’t deliver to it. If you put a triangulated cube into Blender - it will also not recognise adjacent triangles as planes, since in the model context they are just triangles (Blender / math can approximate triangles into planes, but that’s a separate topic.)

Three.js uses only triangles, both in the pre-calculated geometries and in all loaders, so all it knows of is triangles. If you need to turn these triangles into planes / squares - you do have to use some technique (the one above is just one of many, but I’d say it’s simple enough, since you virtually just calculate 3 numbers and filter an array.)

Hey mjurczyk,
My intuition was actually correct! It seems that geometry.groups keeps track of the triangles that conform a single cube face:

I got a wrong implementation of the code, now works fine:

2 triangles from a group item generating a cube face
image

Using 2 group items:
image

Using 3:

We prove it again that threejs is awesome!

1 Like