예제 #1
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void SetupVertexSelection(void) {
	face_t	*f;
	brush_t *b;

	g_qeglobals.d_numpoints = 0;
	g_qeglobals.d_numedges = 0;

#ifdef NEWEDGESEL
	for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
		for (f = b->brush_faces; f; f = f->next) {
			MakeFace(b, f);
		}
	}

#else
	if (!QE_SingleBrush()) {
		return;
	}

	b = selected_brushes.next;
	for (f = b->brush_faces; f; f = f->next) {
		MakeFace(b, f);
	}
#endif
}
예제 #2
0
파일: chull.c 프로젝트: sleitner/cart
/*---------------------------------------------------------------------
 DoubleTriangle builds the initial double triangle.  It first finds 3 
 noncollinear points and makes two faces out of them, in opposite order.
 It then finds a fourth point that is not coplanar with that face.  The  
 vertices are stored in the face structure in counterclockwise order so 
 that the volume between the face and the point is negative. Lastly, the
 3 newfaces to the fourth point are constructed and the data structures
 are cleaned up. 
---------------------------------------------------------------------*/
void    DoubleTriangle( void )
{
   tVertex  v0, v1, v2, v3;
   tFace    f0, f1 = NULL;
   int      vol;
	
   /* Find 3 noncollinear points. */
   v0 = vertices;
   while ( Collinear( v0, v0->next, v0->next->next ) )
      if ( ( v0 = v0->next ) == vertices )
         printf("DoubleTriangle:  All points are Collinear!\n"), exit(0);
   v1 = v0->next;
   v2 = v1->next;
	
   /* Mark the vertices as processed. */
   v0->mark = PROCESSED;
   v1->mark = PROCESSED;
   v2->mark = PROCESSED;
   
   /* Create the two "twin" faces. */
   f0 = MakeFace( v0, v1, v2, f1 );
   f1 = MakeFace( v2, v1, v0, f0 );

   /* Link adjacent face fields. */
   f0->edge[0]->adjface[1] = f1;
   f0->edge[1]->adjface[1] = f1;
   f0->edge[2]->adjface[1] = f1;
   f1->edge[0]->adjface[1] = f0;
   f1->edge[1]->adjface[1] = f0;
   f1->edge[2]->adjface[1] = f0;
	
   /* Find a fourth, noncoplanar point to form tetrahedron. */
   v3 = v2->next;
   vol = VolumeSign( f0, v3 );
   while ( !vol )   {
      if ( ( v3 = v3->next ) == v0 ) 
         printf("DoubleTriangle:  All points are coplanar!\n"), exit(0);
      vol = VolumeSign( f0, v3 );
   }
	
   /* Insure that v3 will be the first added. */
   vertices = v3;
   if ( debug ) {
      fprintf(stderr, "DoubleTriangle: finished. Head repositioned at v3.\n");
      PrintOut( vertices );
   }

	
}
예제 #3
0
파일: mesh.c 프로젝트: AnadoluPanteri/glues
/* __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;
}
예제 #4
0
파일: mesh.cpp 프로젝트: 01org/fastuidraw
/* 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;
}
예제 #5
0
파일: mesh.c 프로젝트: AnadoluPanteri/glues
/* __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;
}
예제 #6
0
파일: mesh.c 프로젝트: TomCN7/libtess2
/* tessMeshDelete (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 tessMeshSplice
* plus a few calls to memFree, but this would allocate and delete
* unnecessary vertices and faces.
*/
int tessMeshDelete (TMesh *mesh, THalfEdge *eDel) 
{
	THalfEdge *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 (mesh, eDel->Lface, eDel->Rface) ;
	}

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

		Splice (eDel, eDel->Oprev) ;
		if (! joiningLoops)  
        {
			TFace *newFace= (TFace*)BucketAlloc (mesh->pFaceBucket) ;
			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 (mesh, eDelSym->pOrigin, NULL) ;
		KillFace (mesh, eDelSym->Lface, NULL) ;
	} 
    else 
    {
		/* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */
		eDel->Lface->pHalfEdge = eDelSym->Oprev;
		eDelSym->pOrigin->pHalfEdge = eDelSym->Onext;
		Splice (eDelSym, eDelSym->Oprev) ;
	}

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

	return 1;
}
예제 #7
0
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
{
	// allocate the new face
	WFace *face = instanciateFace();

	WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face);
	if (!result)
		delete face;
	return result;
}
예제 #8
0
void SetupVertexSelection (void)
{
	face_t	*f;
	brush_t *b;

	g_qeglobals.d_numpoints = 0;
	g_qeglobals.d_numedges = 0;

	for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  {
	  for (f=b->brush_faces ; f ; f=f->next)
		  MakeFace (b,f);
  }
}
예제 #9
0
파일: mesh.c 프로젝트: TomCN7/libtess2
/* tessMeshSplice (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 tessMeshSplice(TMesh* pMesh, THalfEdge *pEdgeOrg, THalfEdge *pEdgeDst) 
{
	int bJoiningLoops = false;
	int bJoiningVertices = false;

	if (pEdgeOrg == pEdgeDst) return 1;

	if (pEdgeDst->pOrigin != pEdgeOrg->pOrigin)  
    {
		/* We are merging two disjoint vertices -- destroy eDst->Org */
		bJoiningVertices = true;
		KillVertex(pMesh, pEdgeDst->pOrigin, pEdgeOrg->pOrigin);
	}
	if (pEdgeDst->Lface != pEdgeOrg->Lface)  
    {
		/* We are connecting two disjoint loops -- destroy eDst->Lface */
		bJoiningLoops = true;
		KillFace(pMesh, pEdgeDst->Lface, pEdgeOrg->Lface);
	}

	/* Change the edge structure */
	Splice(pEdgeDst, pEdgeOrg);

	if (!bJoiningVertices)
    {
		TVertex *pNewVertex = (TVertex*)BucketAlloc(pMesh->pVertexBucket);
		if (pNewVertex == 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(pNewVertex, pEdgeDst, pEdgeOrg->pOrigin);
		pEdgeOrg->pOrigin->pHalfEdge = pEdgeOrg;
	}
	if (!bJoiningLoops)  
    {
		TFace *pNewFace = (TFace*)BucketAlloc(pMesh->pFaceBucket);
		if (pNewFace == 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(pNewFace, pEdgeDst, pEdgeOrg->Lface);
		pEdgeOrg->Lface->pHalfEdge = pEdgeOrg;
	}

	return 1;
}
예제 #10
0
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
                        vector<bool>& iFaceEdgeMarksList, unsigned iMaterial)
{
	// allocate the new face
	WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial);

	if (!face)
		return NULL;

	// set the list of per-vertex normals
	face->setNormalList(iNormalsList);
	// set the list of per-vertex tex coords
	face->setTexCoordsList(iTexCoordsList);

	return face;
}
예제 #11
0
파일: mesh.c 프로젝트: AnadoluPanteri/glues
/* __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;
}
예제 #12
0
/* tessMeshSplice( 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 tessMeshSplice( TESSmesh* mesh, TESShalfEdge *eOrg, TESShalfEdge *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( mesh, eDst->Org, eOrg->Org );
    }
    if( eDst->Lface != eOrg->Lface ) {
        /* We are connecting two disjoint loops -- destroy eDst->Lface */
        joiningLoops = TRUE;
        KillFace( mesh, eDst->Lface, eOrg->Lface );
    }

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

    if( ! joiningVertices ) {
        TESSvertex *newVertex = (TESSvertex*)bucketAlloc( mesh->vertexBucket );
        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 ) {
        TESSface *newFace = (TESSface*)bucketAlloc( mesh->faceBucket );
        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;
}
예제 #13
0
파일: mesh.c 프로젝트: TomCN7/libtess2
/* tessMeshConnect (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.
*/
THalfEdge *tessMeshConnect (TMesh *mesh, THalfEdge *eOrg, THalfEdge *eDst) 
{
	THalfEdge *eNewSym;
	int joiningLoops = false;  
	THalfEdge *eNew = MakeEdge (mesh, 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 (mesh, eDst->Lface, eOrg->Lface) ;
	}

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

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

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

	if (! joiningLoops)  
    {
		TFace *newFace= (TFace*)BucketAlloc (mesh->pFaceBucket) ;
		if (newFace == NULL) return NULL;

		/* We split one loop into two -- the new loop is eNew->Lface */
		MakeFace (newFace, eNew, eOrg->Lface) ;
	}
	return eNew;
}
예제 #14
0
파일: mesh.c 프로젝트: astrofimov/vgallium
/* __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;
}
예제 #15
0
/* tessMeshMakeEdge creates one edge, two vertices, and a loop (face).
* The loop consists of the two new half-edges.
*/
TESShalfEdge *tessMeshMakeEdge( TESSmesh *mesh )
{
    TESSvertex *newVertex1 = (TESSvertex*)bucketAlloc(mesh->vertexBucket);
    TESSvertex *newVertex2 = (TESSvertex*)bucketAlloc(mesh->vertexBucket);
    TESSface *newFace = (TESSface*)bucketAlloc(mesh->faceBucket);
    TESShalfEdge *e;

    /* if any one is null then all get freed */
    if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) {
        if (newVertex1 != NULL) bucketFree( mesh->vertexBucket, newVertex1 );
        if (newVertex2 != NULL) bucketFree( mesh->vertexBucket, newVertex2 );
        if (newFace != NULL) bucketFree( mesh->faceBucket, newFace );
        return NULL;
    }

    e = MakeEdge( mesh, &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;
}
예제 #16
0
파일: mesh.c 프로젝트: TomCN7/libtess2
/* tessMeshMakeEdge creates one edge, two vertices, and a loop (face).
* The loop consists of the two new half-edges.
*/
THalfEdge *tessMeshMakeEdge(TMesh *pMesh) 
{
	TVertex *newVertex1 = (TVertex*)BucketAlloc(pMesh->pVertexBucket);
	TVertex *newVertex2 = (TVertex*)BucketAlloc(pMesh->pVertexBucket);
	TFace *newFace = (TFace*)BucketAlloc(pMesh->pFaceBucket);
	THalfEdge *e;

	/* if any one is null then all get freed */
	if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) 
    {
		if (newVertex1 != NULL) BucketFree (pMesh->pVertexBucket, newVertex1) ;
		if (newVertex2 != NULL) BucketFree (pMesh->pVertexBucket, newVertex2) ;
		if (newFace != NULL) BucketFree (pMesh->pFaceBucket, newFace) ;     
		return NULL;
	} 

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

	MakeVertex (newVertex1, e, &pMesh->vHead) ;
	MakeVertex (newVertex2, e->Sym, &pMesh->vHead) ;
	MakeFace (newFace, e, &pMesh->fHead) ;
	return e;
}
예제 #17
0
파일: sphere.c 프로젝트: SR-dude/AvP-Wine
void Generate_Sphere(void)
{
    /* first generate vertices */
    {
        int i,j;
        VECTORCH *v = SphereVertex;
        VECTORCH *o = OctantVertex;

        Generate_SphereOctant();

        /* north pole */
        *v++ = *o;
        for (i=0; ++i<=SPHERE_ORDER;)
        {
            o += i;
            /* 1st Quadrant */
            for (j=i; --j>=0; o++, v++)
            {
                *v = *o;
            }
            /* 2nd Quadrant */
            for (j=i; --j>=0; o--, v++)
            {
                v->vx = -o->vx;
                v->vy = o->vy;
                v->vz = o->vz;
            }
            /* 3rd Quadrant */
            for (j=i; --j>=0; o++, v++)
            {
                v->vx = -o->vx;
                v->vy = -o->vy;
                v->vz = o->vz;
            }
            /* 4th Quadrant */
            for (j=i; --j>=0; o--, v++)
            {
                v->vx = o->vx;
                v->vy = -o->vy;
                v->vz = o->vz;
            }
        }
        for (; --i>1;)
        {
            o -= i;
            /* 5th Quadrant */
            for (j=i; --j>0; o++, v++)
            {
                v->vx = o->vx;
                v->vy = o->vy;
                v->vz = -o->vz;
            }
            /* 6th Quadrant */
            for (j=i; --j>0; o--, v++)
            {
                v->vx = -o->vx;
                v->vy = o->vy;
                v->vz = -o->vz;
            }
            /* 7th Quadrant */
            for (j=i; --j>0; o++, v++)
            {
                v->vx = -o->vx;
                v->vy = -o->vy;
                v->vz = -o->vz;
            }
            /* 8th Quadrant */
            for (j=i; --j>0; o--, v++)
            {
                v->vx = o->vx;
                v->vy = -o->vy;
                v->vz = -o->vz;
            }
        }
        o--;
        /* south pole */
        v->vx = -o->vx;
        v->vy = -o->vy;
        v->vz = -o->vz;
    }

    /* now generate face data */
    {
        TRI_FACE *f = SphereFace;
        int kv,kw,ko,kv0,kw0,i,j;

        kv = 0, kw = 1;

        for(i=0; i<SPHERE_ORDER; i++)
        {
            kv0 = kv, kw0 = kw;
            for (ko=1; ko<=3; ko++)
            {
                for (j=i;; j--)
                {
                    MakeFace(f,kv,kw,++kw);
                    if (j==0) break;
                    MakeFace(f,kv,kw,++kv);
                }
            }
            for (j=i;; j--)
            {
                if (j==0)
                {
                    MakeFace(f,kv0,kw,kw0);
                    kv++;
                    kw++;
                    break;
                }
                MakeFace(f,kv,kw,++kw);
                if (j==1)
                {
                    MakeFace(f,kv,kw,kv0);
                }
                else MakeFace(f,kv,kw,++kv);
            }
        }
        for(; --i>=0;)
        {
            kv0=kv,kw0=kw;
            for(ko=5; ko<=7; ko++)
            {
                for (j=i;; j--)
                {
                    MakeFace(f,kv,kw,++kv);
                    if (j==0) break;
                    MakeFace(f,kv,kw,++kw);
                }
            }
            for (j=i;; j--)
            {
                if (j==0)
                {
                    MakeFace(f,kv,kw0,kv0);
                    kv++;
                    kw++;
                    break;
                }
                MakeFace(f,kv,kw,++kv);
                if (j==1)
                {
                    MakeFace(f,kv,kw,kw0);
                }
                else MakeFace(f,kv,kw,++kw);
            }
        }
    }
    {
        int i;
        VECTORCH *vSphere = SphereVertex;
        for(i=0; i<SPHERE_VERTICES; i++,vSphere++)
        {
//			int radius = vSphere->vx*vSphere->vx+vSphere->vz*vSphere->vz;
//			if (radius<16384) radius = 16384;

//			SphereAtmosU[i] = DIV_FIXED(ArcCos(vSphere->vy)*32*128*8,radius);
            SphereAtmosV[i] = ArcCos(vSphere->vy)*32*128*SPHERE_TEXTURE_WRAP;//*8;
            SphereAtmosU[i] = ArcTan(vSphere->vz,vSphere->vx)*16*128*SPHERE_TEXTURE_WRAP;//*8;
        }
    }
}
예제 #18
0
ICHullError ICHull::DoubleTriangle()
{
    // find three non colinear points
    m_isFlat = false;
    CircularList<TMMVertex>& vertices = m_mesh.GetVertices();
    CircularListElement<TMMVertex>* v0 = vertices.GetHead();
    while (Colinear(v0->GetData().m_pos,
        v0->GetNext()->GetData().m_pos,
        v0->GetNext()->GetNext()->GetData().m_pos)) {
        if ((v0 = v0->GetNext()) == vertices.GetHead()) {
            return ICHullErrorCoplanarPoints;
        }
    }
    CircularListElement<TMMVertex>* v1 = v0->GetNext();
    CircularListElement<TMMVertex>* v2 = v1->GetNext();
    // mark points as processed
    v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true;

    // create two triangles
    CircularListElement<TMMTriangle>* f0 = MakeFace(v0, v1, v2, 0);
    MakeFace(v2, v1, v0, f0);

    // find a fourth non-coplanar point to form tetrahedron
    CircularListElement<TMMVertex>* v3 = v2->GetNext();
    vertices.GetHead() = v3;

    double vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos);
    while (fabs(vol) < sc_eps && !v3->GetNext()->GetData().m_tag) {
        v3 = v3->GetNext();
        vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos);
    }
    if (fabs(vol) < sc_eps) {
        // compute the barycenter
        Vec3<double> bary(0.0, 0.0, 0.0);
        CircularListElement<TMMVertex>* vBary = v0;
        do {
            bary += vBary->GetData().m_pos;
        } while ((vBary = vBary->GetNext()) != v0);
        bary /= static_cast<double>(vertices.GetSize());

        // Compute the normal to the plane
        Vec3<double> p0 = v0->GetData().m_pos;
        Vec3<double> p1 = v1->GetData().m_pos;
        Vec3<double> p2 = v2->GetData().m_pos;
        m_normal = (p1 - p0) ^ (p2 - p0);
        m_normal.Normalize();
        // add dummy vertex placed at (bary + normal)
        vertices.GetHead() = v2;
        Vec3<double> newPt = bary + m_normal;
        AddPoint(newPt, sc_dummyIndex);
        m_isFlat = true;
        return ICHullErrorOK;
    }
    else if (v3 != vertices.GetHead()) {
        TMMVertex temp;
        temp.m_name = v3->GetData().m_name;
        temp.m_pos = v3->GetData().m_pos;
        v3->GetData().m_name = vertices.GetHead()->GetData().m_name;
        v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos;
        vertices.GetHead()->GetData().m_name = temp.m_name;
        vertices.GetHead()->GetData().m_pos = temp.m_pos;
    }
    return ICHullErrorOK;
}