svgthree.js3dcollada

How to convert a shape of a face of a 3D model in three.js into a 2D SVG?


is it possible to generate an SVG with the shape for a particular face of a model in three.js? We are developing an interactive editor for 3D models where you can draw on each wall and we're stuck with this problem.

For example, for this face: enter image description here

We want to have an SVG like this: enter image description here


Solution

  • There are a few versions of this question out there between programming and math Exchanges. I was able to combine several answers and translate to Three.js' Vector3 and Quaternion classes.

    Let's say you want to render the first face of this tetrahedron OBJ:

    const points3D = [
      Vector3(0.0, 0.0, 1.732051),
      Vector3(1.632993, 0.0, -0.5773503),
      Vector3(-0.8164966, 1.414214, -0.5773503),
    ];
    
    function pointsInPlaneToPoints2D (points3D) {
      // The normal is a unit vector that sticks out from face.
      // We're using the first 3 points, assuming that there
      // are at least 3, and they are not co-linear.
      const [p0, p1, p2] = points3D;
      const planeNormal =
        (new Vector3()).crossVectors(
          (new Vector3()).subVectors(p0, p1),
          (new Vector3()).subVectors(p1, p2)
        ).normalize();
      
      // Unit vector on the Z axis, where we want to rotate our face
      const zUnit = new Vector3(0, 0, 1);
      
      // Quaternion representing the rotation of the face plane to Z
      const qRot = (new Quaternion()).setFromUnitVectors(planeNormal, zUnit);
      
      // Rotate each point, assuming that they are all co-planar
      // with the first 3.
      return points3D.map(function (p) {
        const pRot = p.clone().applyQuaternion(qRot);
        // Output format [x, y] (ignoring z)
        return [pRot.x, pRot.y];
      });
    }
    
    const points2D = points3DInPlaneToPoints2D(points3D);
    // Draw those with your 2D drawing context of choice
    
    

    Here are the faces of a truncated icosahedron, flattened with this function, and rendered with SVG:

    faces flattened from truncated icosahedron