Пример #1
0
/* __gl_meshDelete( eDel ) removes the edge eDel.  There are several cases:
 * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
 * eDel->Lface is deleted.  Otherwise, we are splitting one loop into two;
 * the newly created loop will contain eDel->Dst.  If the deletion of eDel
 * would create isolated vertices, those are deleted as well.
 *
 * This function could be implemented as two calls to __gl_meshSplice
 * plus a few calls to memFree, but this would allocate and delete
 * unnecessary vertices and faces.
 */
int __gl_meshDelete(GLUhalfEdge* eDel)
{
   GLUhalfEdge* eDelSym=eDel->Sym;
   int joiningLoops=FALSE;

   /* First step: disconnect the origin vertex eDel->Org.  We make all
    * changes to get a consistent mesh in this "intermediate" state.
    */
   if (eDel->Lface!=eDel->Rface)
   {
      /* We are joining two loops into one -- remove the left face */
      joiningLoops=TRUE;
      KillFace(eDel->Lface, eDel->Rface);
   }

   if (eDel->Onext==eDel)
   {
      KillVertex(eDel->Org, NULL);
   }
   else
   {
      /* Make sure that eDel->Org and eDel->Rface point to valid half-edges */
      eDel->Rface->anEdge=eDel->Oprev;
      eDel->Org->anEdge=eDel->Onext;

      Splice(eDel, eDel->Oprev);
      if (!joiningLoops)
      {
         GLUface* newFace=allocFace();
         if (newFace==NULL)
         {
            return 0; 
         }

         /* We are splitting one loop into two -- create a new loop for eDel. */
         MakeFace(newFace, eDel, eDel->Lface);
      }
   }

   /* Claim: the mesh is now in a consistent state, except that eDel->Org
    * may have been deleted.  Now we disconnect eDel->Dst.
    */
   if (eDelSym->Onext==eDelSym)
   {
      KillVertex(eDelSym->Org, NULL);
      KillFace(eDelSym->Lface, NULL);
   }
   else
   {
      /* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */
      eDel->Lface->anEdge=eDelSym->Oprev;
      eDelSym->Org->anEdge=eDelSym->Onext;
      Splice(eDelSym, eDelSym->Oprev);
   }

   /* Any isolated vertices or faces have already been freed. */
   KillEdge(eDel);

   return 1;
}
Пример #2
0
/* glu_fastuidraw_gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
 * The loop consists of the two new half-edges.
 */
GLUhalfEdge *glu_fastuidraw_gl_meshMakeEdge( GLUmesh *mesh )
{
  GLUvertex *newVertex1= allocVertex();
  GLUvertex *newVertex2= allocVertex();
  GLUface *newFace= allocFace();
  GLUhalfEdge *e;

  /* if any one is null then all get freed */
  if (newVertex1 == nullptr || newVertex2 == nullptr || newFace == nullptr) {
     if (newVertex1 != nullptr) memFree(newVertex1);
     if (newVertex2 != nullptr) memFree(newVertex2);
     if (newFace != nullptr) memFree(newFace);
     return nullptr;
  }

  e = MakeEdge( &mesh->eHead );
  if (e == nullptr) {
     memFree(newVertex1);
     memFree(newVertex2);
     memFree(newFace);
     return nullptr;
  }

  MakeVertex( newVertex1, e, &mesh->vHead );
  MakeVertex( newVertex2, e->Sym, &mesh->vHead );
  MakeFace( newFace, e, &mesh->fHead );
  return e;
}
Пример #3
0
/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
 * mesh connectivity and topology.  It changes the mesh so that
 *      eOrg->Onext <- OLD(eDst->Onext)
 *      eDst->Onext <- OLD(eOrg->Onext)
 * where OLD(...) means the value before the meshSplice operation.
 *
 * This can have two effects on the vertex structure:
 *  - if eOrg->Org != eDst->Org, the two vertices are merged together
 *  - if eOrg->Org == eDst->Org, the origin is split into two vertices
 * In both cases, eDst->Org is changed and eOrg->Org is untouched.
 *
 * Similarly (and independently) for the face structure,
 *  - if eOrg->Lface == eDst->Lface, one loop is split into two
 *  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
 * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
 *
 * Some special cases:
 * If eDst == eOrg, the operation has no effect.
 * If eDst == eOrg->Lnext, the new face will have a single edge.
 * If eDst == eOrg->Lprev, the old face will have a single edge.
 * If eDst == eOrg->Onext, the new vertex will have a single edge.
 * If eDst == eOrg->Oprev, the old vertex will have a single edge.
 */
int __gl_meshSplice(GLUhalfEdge* eOrg, GLUhalfEdge* eDst)
{
   int joiningLoops=FALSE;
   int joiningVertices=FALSE;

   if (eOrg==eDst)
   {
      return 1;
   }

   if (eDst->Org!=eOrg->Org)
   {
      /* We are merging two disjoint vertices -- destroy eDst->Org */
      joiningVertices=TRUE;
      KillVertex(eDst->Org, eOrg->Org);
   }

   if (eDst->Lface!=eOrg->Lface)
   {
      /* We are connecting two disjoint loops -- destroy eDst->Lface */
      joiningLoops=TRUE;
      KillFace(eDst->Lface, eOrg->Lface);
   }

   /* Change the edge structure */
   Splice(eDst, eOrg);

   if (!joiningVertices)
   {
      GLUvertex* newVertex=allocVertex();
      if (newVertex==NULL)
      {
         return 0;
      }

      /* We split one vertex into two -- the new vertex is eDst->Org.
       * Make sure the old vertex points to a valid half-edge.
       */
      MakeVertex(newVertex, eDst, eOrg->Org);
      eOrg->Org->anEdge=eOrg;
   }

   if (!joiningLoops)
   {
      GLUface* newFace=allocFace();
      if (newFace==NULL)
      {
         return 0;
      }

      /* We split one loop into two -- the new loop is eDst->Lface.
       * Make sure the old face points to a valid half-edge.
       */
      MakeFace(newFace, eDst, eOrg->Lface);
      eOrg->Lface->anEdge=eOrg;
   }

   return 1;
}
Пример #4
0
Triangle& Subdivision::makeFace(Edge *e)
{
    Triangle *t = allocFace(e);

    first_face = t->linkTo(first_face);

    return *t;
}
Пример #5
0
/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
 * to eDst->Org, and returns the corresponding half-edge eNew.
 * If eOrg->Lface == eDst->Lface, this splits one loop into two,
 * and the newly created loop is eNew->Lface.  Otherwise, two disjoint
 * loops are merged into one, and the loop eDst->Lface is destroyed.
 *
 * If (eOrg == eDst), the new face will have only two edges.
 * If (eOrg->Lnext == eDst), the old face is reduced to a single edge.
 * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.
 */
GLUhalfEdge* __gl_meshConnect(GLUhalfEdge* eOrg, GLUhalfEdge* eDst)
{
   GLUhalfEdge* eNewSym;
   int joiningLoops=FALSE;
   GLUhalfEdge* eNew=MakeEdge(eOrg);

   if (eNew==NULL)
   {
      return NULL;
   }

   eNewSym=eNew->Sym;

   if (eDst->Lface!=eOrg->Lface)
   {
      /* We are connecting two disjoint loops -- destroy eDst->Lface */
      joiningLoops=TRUE;
      KillFace(eDst->Lface, eOrg->Lface);
   }

   /* Connect the new edge appropriately */
   Splice(eNew, eOrg->Lnext);
   Splice(eNewSym, eDst);

   /* Set the vertex and face information */
   eNew->Org=eOrg->Dst;
   eNewSym->Org=eDst->Org;
   eNew->Lface=eNewSym->Lface=eOrg->Lface;

   /* Make sure the old face points to a valid half-edge */
   eOrg->Lface->anEdge=eNewSym;

   if (!joiningLoops)
   {
      GLUface* newFace=allocFace();

      if (newFace==NULL)
      {
         return NULL;
      }

      /* We split one loop into two -- the new loop is eNew->Lface */
      MakeFace(newFace, eNew, eOrg->Lface);
   }

   return eNew;
}
Пример #6
0
/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
 * The loop consists of the two new half-edges.
 */
GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh )
{
  GLUvertex *newVertex1= allocVertex();
  GLUvertex *newVertex2= allocVertex();
  GLUface *newFace= allocFace();
  GLUhalfEdge *e;

  /* if any one is null then all get freed */
  if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) {
     if (newVertex1 != NULL) memFree(newVertex1);
     if (newVertex2 != NULL) memFree(newVertex2);
     if (newFace != NULL) memFree(newFace);     
     return NULL;
  } 

  e = MakeEdge( &mesh->eHead );
  if (e == NULL) return NULL;

  MakeVertex( newVertex1, e, &mesh->vHead );
  MakeVertex( newVertex2, e->Sym, &mesh->vHead );
  MakeFace( newFace, e, &mesh->fHead );
  return e;
}