title: draw 3d faces as 2d
body: <p>I have 3d mesh and I would like to draw each face a 2d shape.</p>
  
  <p>What I have in mind is this:
  for each face
  1. access the face normal
  2. get a rotation matrix from the normal vector
  3. multiply each vertex to the rotation matrix to get the vertices in a '2d like ' plane
  4. get 2 coordinates from the transformed vertices</p>
  
  <p>I don't know if this is the best way to do this, so any suggestion is welcome.</p>
  
  <p>At the moment I'm trying to get a rotation matrix from the normal vector,
  how would I do this ?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Here is a visual explanation of what I need:</p>
  
  <p><img src="https://i984.photobucket.com/albums/ae330/orgicus/cube.gif" alt="3d to 2d"></p>
  
  <p>At the moment I have quads, but there's no problem
  converting them into triangles.</p>
  
  <p>I want to rotate the vertices of a face, so that
  one of the dimensions gets flattened. </p>
  
  <p>I also need to store the original 3d rotation of the face. 
  I imagine that would be inverse rotation of the face
  normal.</p>
  
  <p>I think I'm a bit lost in space :)</p>
  
  <p>Here's a basic prototype I did using <a href="http://processing.org" rel="nofollow noreferrer">Processing</a>:</p>
  
  <pre><code>void setup(){
    size(400,400,P3D);
    background(255);
    stroke(0,0,120);
    smooth();
    fill(0,120,0);
  
    PVector x = new PVector(1,0,0);
    PVector y = new PVector(0,1,0);
    PVector z = new PVector(0,0,1);
  
    PVector n  = new PVector(0.378521084785,0.925412774086,0.0180059205741);//normal
    PVector p0 = new PVector(0.372828125954,-0.178844243288,1.35241031647);
    PVector p1 = new PVector(-1.25476706028,0.505195975304,0.412718296051);
    PVector p2 = new PVector(-0.372828245163,0.178844287992,-1.35241031647);
    PVector p3 = new PVector(1.2547672987,-0.505196034908,-0.412717700005);
  
    PVector[] face = {p0,p1,p2,p3};
    PVector[] face2d = new PVector[4];
    PVector   nr = PVector.add(n,new PVector());//clone normal
  
    float rx = degrees(acos(n.dot(x)));//angle between normal and x axis
    float ry = degrees(acos(n.dot(y)));//angle between normal and y axis
    float rz = degrees(acos(n.dot(z)));//angle between normal and z axis
  
    PMatrix3D r = new PMatrix3D();
    //is this ok, or should I drop the builtin function, and add 
    //the rotations manually
    r.rotateX(rx);
    r.rotateY(ry);
    r.rotateZ(rz);
  
    print("original: ");println(face);
    for(int i = 0 ; i &lt; 4; i++){
      PVector rv = new PVector();
      PVector rn = new PVector();
      r.mult(face[i],rv);
      r.mult(nr,rn);
      face2d[i] = PVector.add(face[i],rv);
    }
    print("rotated: ");println(face2d);
    //draw
    float scale = 100.0;
    translate(width * .5,height * .5);//move to centre, Processing has 0,0 = Top,Lef
    beginShape(QUADS);
    for(int i = 0 ; i &lt; 4; i++){
     vertex(face2d[i].x * scale,face2d[i].y * scale,face2d[i].z * scale);
    }
    endShape();
    line(0,0,0,nr.x*scale,nr.y*scale,nr.z*scale);
  
    //what do I do with this ?
    float c = cos(0), s = sin(0);
    float x2 = n.x*n.x,y2 = n.y*n.y,z2 = n.z*n.z; 
    PMatrix3D m = new PMatrix3D(x2+(1-x2)*c,  n.x*n.y*(1-c)-n.z*s,  n.x*n.z*(1-c)+n.y*s,  0,
                                n.x*n.y*(1-c)+n.z*s,y2+(1-y2)*c,n.y*n.z*(1-c)-n.x*s,0,
                                n.x*n.y*(1-c)-n.y*s,n.x*n.z*(1-c)+n.x*s,z2-(1-z2)*c,0,
                                0,0,0,1);
  }
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>Sorry if I'm getting annoying, but I don't seem to get it.</p>
  
  <p>Here's a bit of python using <a href="http://www.blender.org/documentation/249PythonDoc/Mathutils-module.html" rel="nofollow noreferrer">Blender</a>'s API:</p>
  
  <pre><code>import Blender
  from Blender import *
  import math
  from math import sin,cos,radians,degrees
  
  def getRotMatrix(n):
      c = cos(0)
      s = sin(0)
      x2 = n.x*n.x
      y2 = n.y*n.y
      z2 = n.z*n.z
      l1 = x2+(1-x2)*c, n.x*n.y*(1-c)+n.z*s, n.x*n.y*(1-c)-n.y*s
      l2 = n.x*n.y*(1-c)-n.z*s,y2+(1-y2)*c,n.x*n.z*(1-c)+n.x*s
      l3 = n.x*n.z*(1-c)+n.y*s,n.y*n.z*(1-c)-n.x*s,z2-(1-z2)*c
      m = Mathutils.Matrix(l1,l2,l3)
      return m
  
  scn = Scene.GetCurrent()
  ob = scn.objects.active.getData(mesh=True)#access mesh
  
  out = ob.name+'\n'
  #face0
  f = ob.faces[0]
  n = f.v[0].no
  out += 'face: ' + str(f)+'\n'
  out += 'normal: ' + str(n)+'\n'
  
  m = getRotMatrix(n)
  m.invert()
  
  rvs = []
  for v in range(0,len(f.v)):
      out += 'original vertex'+str(v)+': ' + str(f.v[v].co) + '\n'
      rvs.append(m*f.v[v].co)
  
  out += '\n'
  for v in range(0,len(rvs)):
      out += 'original vertex'+str(v)+': ' + str(rvs[v]) + '\n'
  
  f = open('out.txt','w')
  f.write(out)
  f.close
  </code></pre>
  
  <p>All I do is get the current object, access the first face, get the normal, get the vertices, calculate the rotation matrix, invert it, then multiply it by each vertex.
  Finally I write a simple output.</p>
  
  <p>Here's the output for a default plane for which I rotated all the vertices manually by 30 degrees:</p>
  
  <pre><code>Plane.008
  face: [MFace (0 3 2 1) 0]
  normal: [0.000000, -0.499985, 0.866024](vector)
  original vertex0: [1.000000, 0.866025, 0.500000](vector)
  original vertex1: [-1.000000, 0.866026, 0.500000](vector)
  original vertex2: [-1.000000, -0.866025, -0.500000](vector)
  original vertex3: [1.000000, -0.866025, -0.500000](vector)
  
  rotated vertex0: [1.000000, 0.866025, 1.000011](vector)
  rotated vertex1: [-1.000000, 0.866026, 1.000012](vector)
  rotated vertex2: [-1.000000, -0.866025, -1.000012](vector)
  rotated vertex3: [1.000000, -0.866025, -1.000012](vector)
  </code></pre>
  
  <p>Here's the first face of the famous Suzanne mesh:</p>
  
  <pre><code>Suzanne.001
  face: [MFace (46 0 2 44) 0]
  normal: [0.987976, -0.010102, 0.154088](vector)
  original vertex0: [0.468750, 0.242188, 0.757813](vector)
  original vertex1: [0.437500, 0.164063, 0.765625](vector)
  original vertex2: [0.500000, 0.093750, 0.687500](vector)
  original vertex3: [0.562500, 0.242188, 0.671875](vector)
  
  rotated vertex0: [0.468750, 0.242188, -0.795592](vector)
  rotated vertex1: [0.437500, 0.164063, -0.803794](vector)
  rotated vertex2: [0.500000, 0.093750, -0.721774](vector)
  rotated vertex3: [0.562500, 0.242188, -0.705370](vector)
  </code></pre>
  
  <p>The vertices from the Plane.008 mesh are altered, the ones from Suzanne.001's mesh
  aren't. Shouldn't they ? Should I expect to get zeroes on one axis ?
  Once I got the rotation matrix from the normal vector, what is the rotation on x,y,z ?</p>
  
  <p><em>Note:</em> 1. Blender's Matrix supports the * operator 2.In Blender's coordinate system Z point's up. It looks like a right handed system, rotated 90 degrees on X.</p>
  
  <p>Thanks</p>