Example #1
0
 //
 // Triangulate a single face
 //
 // After the edges of a triangle have been split,
 // we need to connect the new (odd) vertices so each
 // face is split into four faces. The figure below shows
 // one step of that process by adding an edge connecting
 // vertices v1 and v3. Once this is complete we will
 // update f->e = enew and lather, rinse, repeat.
 // We're done when e = e->next->next->next; this
 // condition also prevents us from triangulating a
 // face that has already been triangulated.
 //
 // Interestingly enough, this routine will triangulate
 // any polygon whether the edges have been split or not.
 //
 //    * : even vertex  (old vertices from before edge splitt
 //    o : odd vertex (created from edge split)
 //    f : original face
 //    e = f->e : edge emanating from even vertex
 //    enew, esym : newly added edge and its symmetric edge
 //    fnew : newly added face
 //
 //                     v2
 //                      *
 //                     / \                      . avoiding
 //                    /   \                     . backslash
 //                e2 /fnew \ e1 = e->next       . as
 //                  / esym  \                   . last
 //              v3 o.........o v1 = e1->v       . character
 //                /   enew    \                 . on
 //           e3  /             \ e = f->e       . line
 //              /       f       \               .
 //             /                 \              .
 //         v4 *---------o---------* v0 = e->v
 //                     v5
 public void triangulate(Face f) {
   Edge e = E.get(f.e);
   Edge e1 = E.get(e.next);
   // check to make sure this face isn't already triangular
   if (e.i != E.get(E.get(e.next).next).next) {
     // done when e == e->next->next->next
     do {
       Edge e2 = E.get(e1.next);
       Edge e3 = E.get(e2.next);
       // Edge = {i, sym, v, f, prev, next}
       Edge enew = new Edge();
       enew.i = E.size();
       Edge esym = new Edge();
       esym.i = enew.i + 1;
       // Face = {i, e}
       Face fnew = new Face();
       fnew.i = F.size();
       fnew.e = e1.i;
       // set up esym
       esym.sym = enew.i;
       esym.v = e3.v;
       esym.f = fnew.i;
       esym.prev = e2.i;
       esym.next = e1.i;
       // set up enew
       enew.sym = esym.i;
       enew.v = e1.v;
       enew.f = f.i;
       enew.prev = e1.prev;
       enew.next = e2.next;
       E.add(enew);
       E.add(esym);
       F.add(fnew);
       // clean up loose ends
       // e1.prev.next, e2.next.prev, e1.prev, e2.next, e1.f, e2.f
       E.get(e1.prev).next = enew.i;
       e3.prev = enew.i;
       e1.prev = esym.i;
       e2.next = esym.i;
       e1.f = fnew.i;
       e2.f = fnew.i;
       f.e = enew.i;
       // set e1 and e2 for next step
       e1 = e3;
       // e2 = E.get(e3.next);
     } while (e.i != E.get(E.get(e.next).next).next);
   }
 }
Example #2
0
 protected void splitEdge(int e, Vec3 newPos) {
   Edge edge = E.get(e);
   Edge sym = E.get(edge.sym);
   Edge e0 = new Edge();
   Edge e1 = new Edge();
   Vert v0 = new Vert();
   // set indices of new edges + vert
   e0.i = E.size();
   e1.i = e0.i + 1;
   // set up v0
   v0.coord = newPos;
   v0.i = V.size();
   v0.e = e0.i;
   V.add(v0);
   // set up e0
   e0.v = v0.i;
   e0.f = edge.f;
   e0.next = edge.next;
   e0.prev = edge.i;
   e0.sym = edge.sym;
   // set up e1
   e1.v = v0.i;
   e1.f = sym.f;
   e1.next = sym.next;
   e1.prev = edge.sym;
   e1.sym = edge.i;
   E.add(e0);
   E.add(e1);
   // clean up connections with e and e.sym
   E.get(edge.next).prev = e0.i;
   E.get(sym.next).prev = e1.i;
   edge.next = e0.i;
   sym.next = e1.i;
   sym.sym = e0.i;
   edge.sym = e1.i;
 }
Example #3
0
  public Mesh(Vec3 verts[], int faces[][]) {

    V = new Vector<Vert>(verts.length);
    for (int i = 0; i < verts.length; i++) V.addElement(null);
    F = new Vector<Face>(faces.length);
    for (int i = 0; i < faces.length; i++) F.addElement(null);
    int numEdges = 0;
    for (int f = 0; f < faces.length; f++) numEdges += faces[f].length;
    E = new Vector<Edge>(numEdges);
    for (int i = 0; i < numEdges; i++) E.addElement(null);
    originalFaceVerts = new Vector<Integer>(faces.length);
    originalFaceEdges = new Vector<Integer>(faces.length);

    Hashtable<IntPair, Edge> edgeTable = new Hashtable<IntPair, Edge>();

    int ei = 0; // base index for group of edges for next face

    for (int f = 0; f < faces.length; f++) {
      int[] face = faces[f]; // current face
      final int N = face.length; // number of edges in face
      for (int i = 0; i < N; i++) {
        Edge edge = new Edge();
        edge.i = ei + i;
        final int v = face[i];
        final int vnext = face[(i + 1) % N];
        IntPair key = new IntPair(vnext, v);
        Edge sym = edgeTable.get(key);
        if (sym == null) {
          key = new IntPair(v, vnext);
          edgeTable.put(key, edge);
        } else {
          edge.sym = sym.i;
          sym.sym = ei + i;
        }
        edge.v = v;
        if (V.get(v) == null) {
          Vert wvert = new Vert();
          wvert.i = v;
          wvert.e = edge.i;
          wvert.coord = new Vec3(verts[v]);
          V.set(v, wvert);
        }
        edge.f = f;
        edge.next = ei + (i + 1) % N;
        edge.prev = ei + (i + N - 1) % N;
        E.set(edge.i, edge);
      }

      Face wface = new Face();
      wface.i = f;
      wface.e = ei;
      F.set(f, wface);

      ei += N;
    }
    // ensure mesh is triangular
    triangulate();
    // get number of original faces
    originalFaceCount = F.size();
    // get one of each original face's vertices
    for (int i = 0; i < originalFaceCount; i++) originalFaceVerts.add(E.get(F.get(i).e).v);
    for (int i = 0; i < originalFaceCount; i++) originalFaceEdges.add(F.get(i).e);
    // set the normals for the mesh
    setNormals();
  }