⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mesh.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
    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;}/******************** Other Edge Operations **********************//* All these routines can be implemented with the basic edge * operations above.  They are provided for convenience and efficiency. *//* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. * eOrg and eNew will have the same left face. */GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg ){  GLUhalfEdge *eNewSym;  GLUhalfEdge *eNew = MakeEdge( eOrg );  if (eNew == NULL) return NULL;  eNewSym = eNew->Sym;  /* Connect the new edge appropriately */  Splice( eNew, eOrg->Lnext );  /* Set the vertex and face information */  eNew->Org = eOrg->Dst;  {    GLUvertex *newVertex= allocVertex();    if (newVertex == NULL) return NULL;    MakeVertex( newVertex, eNewSym, eNew->Org );  }  eNew->Lface = eNewSym->Lface = eOrg->Lface;  return eNew;}/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, * such that eNew == eOrg->Lnext.  The new vertex is eOrg->Dst == eNew->Org. * eOrg and eNew will have the same left face. */GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg ){  GLUhalfEdge *eNew;  GLUhalfEdge *tempHalfEdge= __gl_meshAddEdgeVertex( eOrg );  if (tempHalfEdge == NULL) return NULL;  eNew = tempHalfEdge->Sym;  /* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */  Splice( eOrg->Sym, eOrg->Sym->Oprev );  Splice( eOrg->Sym, eNew );  /* Set the vertex and face information */  eOrg->Dst = eNew->Org;  eNew->Dst->anEdge = eNew->Sym;	/* may have pointed to eOrg->Sym */  eNew->Rface = eOrg->Rface;  eNew->winding = eOrg->winding;	/* copy old winding information */  eNew->Sym->winding = eOrg->Sym->winding;  return eNew;}/* __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;}/******************** Other Operations **********************//* __gl_meshZapFace( fZap ) destroys a face and removes it from the * global face list.  All edges of fZap will have a NULL pointer as their * left face.  Any edges which also have a NULL pointer as their right face * are deleted entirely (along with any isolated vertices this produces). * An entire mesh can be deleted by zapping its faces, one at a time, * in any order.  Zapped faces cannot be used in further mesh operations! */void __gl_meshZapFace( GLUface *fZap ){  GLUhalfEdge *eStart = fZap->anEdge;  GLUhalfEdge *e, *eNext, *eSym;  GLUface *fPrev, *fNext;  /* walk around face, deleting edges whose right face is also NULL */  eNext = eStart->Lnext;  do {    e = eNext;    eNext = e->Lnext;    e->Lface = NULL;    if( e->Rface == NULL ) {      /* delete the edge -- see __gl_MeshDelete above */      if( e->Onext == e ) {	KillVertex( e->Org, NULL );      } else {	/* Make sure that e->Org points to a valid half-edge */	e->Org->anEdge = e->Onext;	Splice( e, e->Oprev );      }      eSym = e->Sym;      if( eSym->Onext == eSym ) {	KillVertex( eSym->Org, NULL );      } else {	/* Make sure that eSym->Org points to a valid half-edge */	eSym->Org->anEdge = eSym->Onext;	Splice( eSym, eSym->Oprev );      }      KillEdge( e );    }  } while( e != eStart );  /* delete from circular doubly-linked list */  fPrev = fZap->prev;  fNext = fZap->next;  fNext->prev = fPrev;  fPrev->next = fNext;  memFree( fZap );}/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices, * and no loops (what we usually call a "face"). */GLUmesh *__gl_meshNewMesh( void ){  GLUvertex *v;  GLUface *f;  GLUhalfEdge *e;  GLUhalfEdge *eSym;  GLUmesh *mesh = (GLUmesh *)memAlloc( sizeof( GLUmesh ));  if (mesh == NULL) {     return NULL;  }    v = &mesh->vHead;  f = &mesh->fHead;  e = &mesh->eHead;  eSym = &mesh->eHeadSym;  v->next = v->prev = v;  v->anEdge = NULL;  v->data = NULL;  f->next = f->prev = f;  f->anEdge = NULL;  f->data = NULL;  f->trail = NULL;  f->marked = FALSE;  f->inside = FALSE;  e->next = e;  e->Sym = eSym;  e->Onext = NULL;  e->Lnext = NULL;  e->Org = NULL;  e->Lface = NULL;  e->winding = 0;  e->activeRegion = NULL;  eSym->next = eSym;  eSym->Sym = e;  eSym->Onext = NULL;  eSym->Lnext = NULL;  eSym->Org = NULL;  eSym->Lface = NULL;  eSym->winding = 0;  eSym->activeRegion = NULL;  return mesh;}/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in * both meshes, and returns the new mesh (the old meshes are destroyed). */GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 ){  GLUface *f1 = &mesh1->fHead;  GLUvertex *v1 = &mesh1->vHead;  GLUhalfEdge *e1 = &mesh1->eHead;  GLUface *f2 = &mesh2->fHead;  GLUvertex *v2 = &mesh2->vHead;  GLUhalfEdge *e2 = &mesh2->eHead;  /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */  if( f2->next != f2 ) {    f1->prev->next = f2->next;    f2->next->prev = f1->prev;    f2->prev->next = f1;    f1->prev = f2->prev;  }  if( v2->next != v2 ) {    v1->prev->next = v2->next;    v2->next->prev = v1->prev;    v2->prev->next = v1;    v1->prev = v2->prev;  }  if( e2->next != e2 ) {    e1->Sym->next->Sym->next = e2->next;    e2->next->Sym->next = e1->Sym->next;    e2->Sym->next->Sym->next = e1;    e1->Sym->next = e2->Sym->next;  }  memFree( mesh2 );  return mesh1;}#ifdef DELETE_BY_ZAPPING/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. */void __gl_meshDeleteMesh( GLUmesh *mesh ){  GLUface *fHead = &mesh->fHead;  while( fHead->next != fHead ) {    __gl_meshZapFace( fHead->next );  }  assert( mesh->vHead.next == &mesh->vHead );  memFree( mesh );}#else/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. */void __gl_meshDeleteMesh( GLUmesh *mesh ){  GLUface *f, *fNext;  GLUvertex *v, *vNext;  GLUhalfEdge *e, *eNext;  for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) {    fNext = f->next;    memFree( f );  }  for( v = mesh->vHead.next; v != &mesh->vHead; v = vNext ) {    vNext = v->next;    memFree( v );  }  for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {    /* One call frees both e and e->Sym (see EdgePair above) */    eNext = e->next;    memFree( e );  }  memFree( mesh );}#endif#ifndef NDEBUG/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. */void __gl_meshCheckMesh( GLUmesh *mesh ){  GLUface *fHead = &mesh->fHead;  GLUvertex *vHead = &mesh->vHead;  GLUhalfEdge *eHead = &mesh->eHead;  GLUface *f, *fPrev;  GLUvertex *v, *vPrev;  GLUhalfEdge *e, *ePrev;  fPrev = fHead;  for( fPrev = fHead ; (f = fPrev->next) != fHead; fPrev = f) {    assert( f->prev == fPrev );    e = f->anEdge;    do {      assert( e->Sym != e );      assert( e->Sym->Sym == e );      assert( e->Lnext->Onext->Sym == e );      assert( e->Onext->Sym->Lnext == e );      assert( e->Lface == f );      e = e->Lnext;    } while( e != f->anEdge );  }  assert( f->prev == fPrev && f->anEdge == NULL && f->data == NULL );  vPrev = vHead;  for( vPrev = vHead ; (v = vPrev->next) != vHead; vPrev = v) {    assert( v->prev == vPrev );    e = v->anEdge;    do {      assert( e->Sym != e );      assert( e->Sym->Sym == e );      assert( e->Lnext->Onext->Sym == e );      assert( e->Onext->Sym->Lnext == e );      assert( e->Org == v );      e = e->Onext;    } while( e != v->anEdge );  }  assert( v->prev == vPrev && v->anEdge == NULL && v->data == NULL );  ePrev = eHead;  for( ePrev = eHead ; (e = ePrev->next) != eHead; ePrev = e) {    assert( e->Sym->next == ePrev->Sym );    assert( e->Sym != e );    assert( e->Sym->Sym == e );    assert( e->Org != NULL );    assert( e->Dst != NULL );    assert( e->Lnext->Onext->Sym == e );    assert( e->Onext->Sym->Lnext == e );  }  assert( e->Sym->next == ePrev->Sym       && e->Sym == &mesh->eHeadSym       && e->Sym->Sym == e       && e->Org == NULL && e->Dst == NULL       && e->Lface == NULL && e->Rface == NULL );}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -