コード例 #1
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;
}
コード例 #2
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;
}
コード例 #3
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;
}
コード例 #4
0
ファイル: mesh.c プロジェクト: TomCN7/libtess2
/* MakeEdge creates a new pair of half-edges which form their own loop.
* No vertex or face structures are allocated, but these must be assigned
* before the current edge operation is completed.
*/
static THalfEdge *MakeEdge(TMesh* pMesh, THalfEdge *pEdgeNext) 
{
	THalfEdge *pEdge = NULL;
	THalfEdge *pSymEdge = NULL;
	THalfEdge *pPrevEdge = NULL;
	EdgePair *pPair = (EdgePair *)BucketAlloc(pMesh->pEdgeBucket);
	if (pPair == NULL) return NULL;

	pEdge = &pPair->Edge;
	pSymEdge = &pPair->SymEdge;

	/* Make sure eNext points to the first edge of the edge pair */
	if (pEdgeNext->Sym < pEdgeNext)  { pEdgeNext = pEdgeNext->Sym; }

	/* Insert in circular doubly-linked list before eNext.
	* Note that the prev pointer is stored in Sym->next.
	*/
	pPrevEdge = pEdgeNext->Sym->pNext;
	pSymEdge->pNext = pPrevEdge;
	pPrevEdge->Sym->pNext = pEdge;
	pEdge->pNext = pEdgeNext;
	pEdgeNext->Sym->pNext = pSymEdge;

	pEdge->Sym = pSymEdge;
	pEdge->Onext = pEdge;
	pEdge->Lnext = pSymEdge;
	pEdge->pOrigin = NULL;
	pEdge->Lface = NULL;
	pEdge->nWinding = 0;
	pEdge->pActiveRegion = NULL;

	pSymEdge->Sym = pEdge;
	pSymEdge->Onext = pSymEdge;
	pSymEdge->Lnext = pEdge;
	pSymEdge->pOrigin = NULL;
	pSymEdge->Lface = NULL;
	pSymEdge->nWinding = 0;
	pSymEdge->pActiveRegion = NULL;

	return pEdge;
}
コード例 #5
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;
}
コード例 #6
0
ファイル: mesh.c プロジェクト: TomCN7/libtess2
/* tessMeshAddEdgeVertex (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.
*/
THalfEdge *tessMeshAddEdgeVertex (TMesh *mesh, THalfEdge *eOrg) 
{
	THalfEdge *eNewSym;
	THalfEdge *eNew = MakeEdge (mesh, 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->pOrigin = eOrg->Dst;
	{
		TVertex *newVertex= (TVertex*)BucketAlloc (mesh->pVertexBucket) ;
		if (newVertex == NULL) return NULL;

		MakeVertex (newVertex, eNewSym, eNew->pOrigin) ;
	}
	eNew->Lface = eNewSym->Lface = eOrg->Lface;

	return eNew;
}
コード例 #7
0
ファイル: alloc.cpp プロジェクト: citiral/olliOS
//
// Created by citiral on 9/23/16.
//

#include "alloc.h"

#if __KERNEL_ALLOCATOR == __KERNEL_ALLOCATOR_LINEAR
LinearAlloc kernelAllocator = LinearAlloc();
#elif __KERNEL_ALLOCATOR == __KERNEL_ALLOCATOR_BUCKET
BucketAlloc kernelAllocator = BucketAlloc();
#endif