Пример #1
0
typename PolygonMesh<PointType>::VertexIterator PolygonMesh<PointType>::splitFace(const typename PolygonMesh<PointType>::FaceIterator& faceIt,typename PolygonMesh<PointType>::Vertex* facePoint)
	{
	/* Link the face point to the mesh: */
	facePoint->pred=lastVertex;
	facePoint->succ=0;
	if(lastVertex!=0)
		lastVertex->succ=facePoint;
	else
		vertices=facePoint;
	lastVertex=facePoint;

	/* Create a fan of triangles around the face point: */
	Edge* firstOuterEdge=faceIt->getEdge();
	deleteFace(faceIt.face);
	Edge* outerEdge=firstOuterEdge;
	Edge* firstInnerEdge;
	Edge* lastInnerEdge=0;
	do
		{
		Edge* nextOuterEdge=outerEdge->getFaceSucc();
		
		/* Create a new triangle: */
		Face* triangle=newFace();
		Edge* innerEdge1=newEdge();
		Edge* innerEdge2=newEdge();
		facePoint->setEdge(innerEdge1);
		innerEdge1->set(facePoint,triangle,innerEdge2,outerEdge,lastInnerEdge);
		innerEdge1->sharpness=0;
		if(lastInnerEdge!=0)
			lastInnerEdge->setOpposite(innerEdge1);
		else
			firstInnerEdge=innerEdge1;
		innerEdge2->set(outerEdge->getEnd(),triangle,outerEdge,innerEdge1,0);
		innerEdge2->sharpness=0;
		outerEdge->setFace(triangle);
		outerEdge->setFacePred(innerEdge1);
		outerEdge->setFaceSucc(innerEdge2);
		triangle->setEdge(outerEdge);
		
		#ifndef NDEBUG
		triangle->checkFace();
		#endif
		
		lastInnerEdge=innerEdge2;
		outerEdge=nextOuterEdge;
		}
	while(outerEdge!=firstOuterEdge);
	
	/* Close the fan by connecting the first and last inner edges: */
	lastInnerEdge->setOpposite(firstInnerEdge);
	firstInnerEdge->setOpposite(lastInnerEdge);
	
	#ifndef NDEBUG
	facePoint->checkVertex();
	#endif
	
	return VertexIterator(facePoint);
	}
Пример #2
0
void LookAlikeMainPrivate::processFaces()
{
    if (m_facesToProcess.isEmpty()) {
        m_progressDialog->dismiss();
    } else {
        QUrl toProcess = m_facesToProcess.first();
        if (m_currentAction == m_confirmFaceAction) {
            confirmFace(toProcess, m_personSelected);
        } else {
            deleteFace(toProcess, m_personSelected);
        }
        m_facesToProcess.removeFirst();
        m_progress->setValue(m_progress->value() + 1);
    }
}
Пример #3
0
void BOP_Merge2::mergeVertex(BOP_Face3 *face, BOP_Index v1, BOP_Index v2)
{
	BOP_Index next, prev;
	face->getNeighbours(v1,prev,next);

	// if new vertex is not already in the tri, make a new tri
	if( prev != v2 && next != v2 ) {
		m_mesh->addFace( new BOP_Face3(prev,v2,next,
					face->getPlane(),face->getOriginalFace()) );
#ifdef BOP_DEBUG
		cout << "mv3: add " << prev << "," << v2 << "," << next << endl;
	} else {
		cout << "mv3: vertex already in tri: doing nothing" << endl;
#endif
	}
	deleteFace(m_mesh, face);
}
Пример #4
0
void BOP_Merge2::mergeVertex(BOP_Face4 *face, BOP_Index v1, BOP_Index v2)
{
	BOP_Index next, prev, opp;
	face->getNeighbours(v1,prev,next,opp);

	// if new vertex is already in the quad, replace quad with new tri
	if( prev == v2 || next == v2 ) {
		m_mesh->addFace( new BOP_Face3(prev,next,opp,
					face->getPlane(),face->getOriginalFace()) );
#ifdef BOP_DEBUG
		cout << "mv4a: add " << prev << "," << next << "," << opp << endl;
#endif
	}
	// otherwise make a new quad
	else {
		m_mesh->addFace( new BOP_Face4(prev,v2,next,opp,
					face->getPlane(),face->getOriginalFace()) );
#ifdef BOP_DEBUG
		cout << "mv4b: add "<<prev<<","<<v2<<","<<next<<","<<opp<<endl;
#endif
	}
	deleteFace(m_mesh, face);
}
Пример #5
0
/** 
 * Simplifies the mesh, merging the pairs of triangles that come frome the
 * same original face and define a quad.
 * @return true if a quad was added, false otherwise
 */
bool BOP_Merge2::createQuads()
{
  
	BOP_Faces quads;
	
	// Get mesh faces
	BOP_Faces faces = m_mesh->getFaces();
	
    // Merge mesh triangles
	const BOP_IT_Faces facesIEnd = (faces.end()-1);
	const BOP_IT_Faces facesJEnd = faces.end();
	for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
#ifdef OLD_QUAD
		if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
		for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
			if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
				(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;


			BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
			if (faceK != NULL) {
				// Set triangles to BROKEN
				deleteFace(m_mesh, *faceI);
				deleteFace(m_mesh, *faceJ);
#ifdef BOP_DEBUG
			cout << "createQuad: del " << *faceI << endl;
			cout << "createQuad: del " << *faceJ << endl;
			cout << "createQuad: add " << faceK << endl;
#endif
				quads.push_back(faceK);
				break;
			}
		}
#else
		if ((*faceI)->getTAG() == BROKEN ) continue;
		for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
			if ((*faceJ)->getTAG() == BROKEN ||
				(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;

			BOP_Face *faceK = NULL;
			if((*faceI)->size() == 3) {
				if((*faceJ)->size() == 3)
					faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
				else
					faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ);
			} else {
				if((*faceJ)->size() == 3)
					faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI);
				else
					faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ);
			}

			if (faceK != NULL) {
				// Set triangles to BROKEN
				deleteFace(m_mesh, *faceI);
				deleteFace(m_mesh, *faceJ);
#ifdef BOP_DEBUG
			cout << "createQuad: del " << *faceI << endl;
			cout << "createQuad: del " << *faceJ << endl;
			cout << "createQuad: add " << faceK << endl;
#endif
				quads.push_back(faceK);
				break;
			}
		}
#endif
	}

    // Add quads to mesh
	const BOP_IT_Faces quadsEnd = quads.end();
	for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
	return (quads.size() > 0);
}
Пример #6
0
void clean_nonmanifold( BOP_Mesh *m )
{
	return;

	BOP_Edges nme;
	BOP_Edges e = m->getEdges();
	for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) {
		BOP_Indexs faces = (*it)->getFaces();
		if( faces.size() & ~2 )
			nme.push_back(*it);
	}
	if (nme.size() == 0) return;
	for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) {
		if( (*it)->getFaces().size() > 1 ) {
			BOP_Indexs faces = (*it)->getFaces();
			for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) {
				MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint();
				MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint();
				MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint();
				if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle
					deleteFace(m,m->getFace(*face));
			}
			continue;
		}
		BOP_Face *oface1 = m->getFace((*it)->getFaces().front());
		BOP_Face *oface2, *tmpface;
		BOP_Index first =(*it)->getVertex1();
		BOP_Index next =(*it)->getVertex2();
		BOP_Index last = first;
		unsigned short facecount = 0;
		bool found = false;
		BOP_Indexs vertList;
#ifdef BOP_DEBUG
		cout << "  first edge is " << (*it) << endl;
#endif
		vertList.push_back(first);
		BOP_Edge *edge;
		while(true) {
			BOP_Vertex *vert = m->getVertex(next);
			BOP_Indexs edges = vert->getEdges();
			edge = NULL;
			for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) {
				edge = m->getEdge(*eit);
				if( edge->getFaces().size() > 1) {
					edge = NULL;
					continue;
				}
				if( edge->getVertex1() == next && edge->getVertex2() != last ) {
					last = next;
					next = edge->getVertex2();
					break;
				}
				if( edge->getVertex2() == next && edge->getVertex1() != last ) {
					last = next;
					next = edge->getVertex1();
					break;
				}
				edge = NULL;
			}
			if( !edge ) break;
#ifdef BOP_DEBUG
			cout << "   next edge is " << edge << endl;
#endif
			tmpface = m->getFace(edge->getFaces().front());
			if( oface1->getOriginalFace() != tmpface->getOriginalFace() )
				oface2 = tmpface;
			else
				++facecount;
			vertList.push_back(last);
			if( vertList.size() > 3 ) break;
			if( next == first ) {
				found = true;
				break;
			}
		}
		if(found) {
			edge = *it;
#ifdef BOP_DEBUG
			cout << "   --> found a loop" << endl;
#endif
			if( vertList.size() == 3 ) {
				BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front());
				face->getNeighbours(first,last,next);
			} else if( vertList.size() == 4 ) {
				BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front());
				face->getNeighbours(first,last,next,last);
			} else {
#ifdef BOP_DEBUG
				cout << "loop has " << vertList.size() << "verts"; 
#endif
				continue;
			}
			if(facecount == 1) oface1 = oface2;
			next = vertList[1];
			last = vertList[2];
			if( edge->getVertex2() == next ) { 
				BOP_Face3 *f = new BOP_Face3(next,first,last,
					oface1->getPlane(),oface1->getOriginalFace());
				m->addFace( f );
#ifdef BOP_DEBUG
				cout << "   face is backward: " << f << endl;
#endif
				
			} else {
				BOP_Face3 *f = new BOP_Face3(last,first,next,
					oface1->getPlane(),oface1->getOriginalFace());
				m->addFace( f );
#ifdef BOP_DEBUG
				cout << "   face is forward: " << f << endl;
#endif
			}
		}
	}
}
Пример #7
0
   VertexIter HalfedgeMesh::collapseEdge( EdgeIter e )
   {
      // TODO This method should collapse the given edge and return an iterator to the new vertex created by the collapse.
		 
		 //1. collect elements
		 EdgeIter e4 = e;

		 //Halfedges
		 HalfedgeIter h1 = e4->halfedge();
		 HalfedgeIter h5 = h1->twin();
		 
		 //Faces
		 FaceIter f0 = h1->face();
		 FaceIter f1 = h5->face();
		 
		 //Early Exit #1: Ignore requests to collapse boundary edges
		 if(f0->isBoundary() || f1->isBoundary())
			 return verticesEnd();
		 
		 //Halfedges, cont'
		 HalfedgeIter h2 = h1->next();
		 HalfedgeIter h0 = h2->next();
		 HalfedgeIter h3 = h5->next();
		 HalfedgeIter h4 = h3->next();
		 
		 HalfedgeIter h7 = h0->twin();
		 HalfedgeIter h12 = h3->twin();
		 
		 HalfedgeIter h20 = h2->twin();
		 HalfedgeIter h15 = h4->twin();
		 
		 //Edges
		 EdgeIter e0 = h0->edge();
		 EdgeIter e1 = h3->edge();
		 EdgeIter e2 = h4->edge();
		 EdgeIter e3 = h2->edge();
			//EdgeIter e4
		 
		 //Faces
		 
		 //Vertices
		 VertexIter v0 = h0->vertex();
		 VertexIter v1 = h3->vertex();
		 VertexIter v2 = h4->vertex();
		 VertexIter v3 = h2->vertex();
		 
		 //Early Exit #2: The number of the joint neighbor vertices of the two merging vertices
		 //must be EXACTLY TWO
		 std::vector<VertexIter> v1_neighbors;
		 std::vector<VertexIter> v3_neighbors;
		 HalfedgeIter h = h3;
		 do
		 {
			 h = h->twin();
			 if(h->vertex() != v1)
				 v1_neighbors.push_back(h->vertex());
			 h = h->next();
		 }
		 while(h != h3);
		 h = h2;
		 do
		 {
			 h = h->twin();
			 if(h->vertex() != v3)
				 v3_neighbors.push_back(h->vertex());
			 h = h->next();
		 }
		 while(h != h2);
		 std::sort(v1_neighbors.begin(), v1_neighbors.end());
		 std::sort(v3_neighbors.begin(), v3_neighbors.end());
		 std::vector<VertexIter> joint_neighbors;
		 std::set_intersection(v1_neighbors.begin(), v1_neighbors.end(),
													 v3_neighbors.begin(), v3_neighbors.end(),
													 std::back_inserter(joint_neighbors));
		 if(joint_neighbors.size() != 2)
			 return verticesEnd();
		 
		 //Early Exit #3: mesh must have more than 4 vertices if neither v1 nor v3 is boundary vertex,
		 //and more than 3 vertices if either v1 or v3 is boundary vertex
		 if(!v1->isBoundary() && !v3->isBoundary() && nVertices() <= 4)
			 return verticesEnd();
		 if((v1->isBoundary() || v3->isBoundary()) && nVertices() <= 3)
			 return verticesEnd();
		 
		 //Early Exit #4: v1, v3 cannot be both boundary vertex
		 if(v1->isBoundary() && v3->isBoundary())
			 return verticesEnd();
		 
		 //Early Exit #5: boundary vertex needs at least one triangle
		 //By convention, Vertex::degree() returns the face degree
		 if(v0->isBoundary() && v0->degree() <= 1)
			 return verticesEnd();
		 if(v1->isBoundary() && v1->degree() <= 1)
			 return verticesEnd();
		 if(v2->isBoundary() && v2->degree() <= 1)
			 return verticesEnd();
		 if(v3->isBoundary() && v3->degree() <= 1)
			 return verticesEnd();
		
		 //Early Exit #6: degenerated case: v0/v1/v2/v3 are duplicated
		 if(v0 == v1 || v0 == v2 || v0 == v3 || v1 == v2 || v1 == v3 || v2 == v3)
			 return verticesEnd();
		 

		 
		 VertexIter output = verticesEnd();
		 if(v3->isBoundary())
		 {
			 std::vector<HalfedgeIter> v1_out;
			 HalfedgeIter h = v1->halfedge();
			 do
			 {
				 v1_out.push_back(h);
				 h = h->next()->next()->twin();
			 }
			 while(h != v1->halfedge());
			 
			 //2. reassign elements
			 
			 //Halfedges
			 h7->twin() = h20; h7->edge() = e3;
			 h20->twin() = h7;
			 h12->twin() = h15; h12->edge() = e2;
			 h15->twin() = h12;
			 
			 for(auto h = v1_out.begin(); h!= v1_out.end(); ++h)
				 (*h)->vertex() = v3;
			 
			 //Vertices
			 v0->halfedge() = h20;
			 v3->halfedge() = h15;
			 v3->position = 0.5f * (v1->position + v3->position);
			 v2->halfedge() = h12;
			 
			 //Edges
			 e3->halfedge() = h20;
			 e2->halfedge() = h15;
			 
			 //Faces
			 
			 //3. delete elements
			 //Halfedges
			 deleteHalfedge(h0);
			 deleteHalfedge(h1);
			 deleteHalfedge(h2);
			 deleteHalfedge(h3);
			 deleteHalfedge(h4);
			 deleteHalfedge(h5);
			 
			 //Vertices
			 deleteVertex(v1);
			 
			 //Edges
			 deleteEdge(e0);
			 deleteEdge(e1);
			 deleteEdge(e4);
			 
			 //Faces
			 deleteFace(f0);
			 deleteFace(f1);
			 
			 output = v3;
		 }
		 else
		 {
			 std::vector<HalfedgeIter> v3_out;
			 HalfedgeIter h = v3->halfedge();
			 do
			 {
				 v3_out.push_back(h);
				 h = h->next()->next()->twin();
			 }
			 while(h != v3->halfedge());
			 
			 //2. reassign elements
			 
			 //Halfedges
			 h7->twin() = h20;
			 h20->twin() = h7; h20->edge() = e0;
			 h12->twin() = h15;
			 h15->twin() = h12; h15->edge() = e1;
			 
			 for(auto h = v3_out.begin(); h!= v3_out.end(); ++h)
				 (*h)->vertex() = v1;
			 
			 //Vertices
			 v0->halfedge() = h20;
			 v1->halfedge() = h15;
			 v1->position = 0.5f * (v1->position + v3->position);
			 v2->halfedge() = h12;
			 
			 //Edges
			 e0->halfedge() = h20;
			 e1->halfedge() = h15;
			 
			 //Faces
			 
			 //3. delete elements
			 //Halfedges
			 deleteHalfedge(h0);
			 deleteHalfedge(h1);
			 deleteHalfedge(h2);
			 deleteHalfedge(h3);
			 deleteHalfedge(h4);
			 deleteHalfedge(h5);
			 
			 //Vertices
			 deleteVertex(v3);
			 
			 //Edges
			 deleteEdge(e2);
			 deleteEdge(e3);
			 deleteEdge(e4);
			 
			 //Faces
			 deleteFace(f0);
			 deleteFace(f1);
			 
			 output = v1;
		 }
		 
		 return output;
   }
Пример #8
0
void HMesh::collapseEdge(Edge* edgy)
{
    Vertex* v1 = edgy->start;
    Vertex* v2 = edgy->end;

    if(v1 == v2) return;
    *v1 = (*v1 + *v2) * 0.5;
    edgy->start = v1;
    if (edgy->face)
    {   
		 if(edgy->next->next->pair != NULL)
		 {
			edgy->next->next->pair->pair = edgy->next->pair;
			if(edgy->next->pair != NULL)
			{
				edgy->next->pair->pair = edgy->next->next->pair;

				Edge* e1 = edgy->next->next;

				Edge* e2 = edgy->next;

				//delete old edges
				deleteEdge(e1, false);    
				deleteEdge(e2, false);
			}
		}
    }
    
    if(edgy->pair != NULL)
    {
		if (edgy->pair->face)
		{
			if(edgy->pair->next->next->pair != NULL)
			{	
				edgy->pair->next->next->pair->pair = edgy->pair->next->pair;
				if(edgy->pair->next->pair != NULL)
				{
					edgy->pair->next->pair->pair = edgy->pair->next->next->pair;
					//delete old edges
				
					Edge* e1 = edgy->pair->next->next;
					Edge* e2 = edgy->pair->next;

					deleteEdge(e1, false);    
					deleteEdge(e2, false);
				}
			}
		}

		// Now really delete faces
		if(edgy->pair->face)
		{
			deleteFace(edgy->pair->face);
			edgy->pair = 0;
		}
	}
	
	if(edgy->face)
	{
		deleteFace(edgy->face);
		edgy->face = 0;
	}

    deleteEdge(edgy);

    auto it =v2->out_edges.begin();

    while(it !=v2->out_edges.end())
    {
        (*it)->start = v1;
        v1->out_edges.push_back(*it);
        it++;
    }

    auto it2 = v2->in_edges.begin();
    while(it2 != v2->in_edges.end())
    {
        (*it2)->end = v1;
        v1->in_edges.push_back(*it2);
        it2++;
    }
    //v2->out_edges.clear();
    //v2->in_edges.clear();
    
}
Пример #9
0
bool AutoTriangleMesh<PointType>::collapseEdge(const typename AutoTriangleMesh<PointType>::EdgeIterator& edge)
	{
	/* Get triangle topology: */
	Edge* e1=&(*edge);
	Edge* e2=e1->getFaceSucc();
	Edge* e3=e1->getFacePred();
	Edge* e4=e1->getOpposite();
	if(e4==0)
		return false;
	
	Edge* e5=e4->getFaceSucc();
	Edge* e6=e4->getFacePred();
	Edge* e7=e2->getOpposite();
	Edge* e8=e3->getOpposite();
	Edge* e9=e5->getOpposite();
	Edge* e10=e6->getOpposite();
	Vertex* v1=e1->getStart();
	Vertex* v2=e2->getStart();
	Vertex* v3=e3->getStart();
	Vertex* v4=e6->getStart();
	Face* f1=e1->getFace();
	Face* f2=e4->getFace();
	
	/* Check if v3 has valence of at least 4: */
	if(e7->getFacePred()->getOpposite()->getFacePred()==e8)
		return false;
	
	/* Check if v4 has valence of at least 4: */
	if(e9->getFacePred()->getOpposite()->getFacePred()==e10)
		return false;
	
	/* Check if v1 and v2 together have at least valence 7 (then collapsed v1 will have at least valence 3): */
	if(e7->getFaceSucc()==e10&&e9->getFaceSucc()==e8)
		return false;
	
	/* Check if platelets of v1 and v2 have common vertices (except each other, of course): */
	/* Currently highly inefficient at O(n^2); need to optimize! */
	for(Edge* ve1=e10->getFacePred();ve1!=e7;ve1=ve1->getOpposite()->getFacePred())
		for(Edge* ve2=e8->getFacePred();ve2!=e9;ve2=ve2->getOpposite()->getFacePred())
			if(ve1->getStart()==ve2->getStart())
				return false;
	
	assert(v2->getEdge()!=0);
	assert(f1->getEdge()!=0);
	assert(f2->getEdge()!=0);
	
	assert(e2->getFaceSucc()==e3&&e3->getFacePred()==e2);
	assert(e5->getFaceSucc()==e6&&e6->getFacePred()==e5);
	assert(e4->getStart()==v2);
	assert(e5->getStart()==v1);
	assert(e7->getOpposite()==e2);
	assert(e8->getOpposite()==e3);
	assert(e9->getOpposite()==e5);
	assert(e10->getOpposite()==e6);
	assert(e7->getStart()==v3);
	assert(e8->getStart()==v1);
	assert(e9->getStart()==v4);
	assert(e10->getStart()==v2);
	assert(e2->getFace()==f1);
	assert(e3->getFace()==f1);
	assert(e5->getFace()==f2);
	assert(e6->getFace()==f2);
	assert(f1->getEdge()==e1||f1->getEdge()==e2||f1->getEdge()==e3);
	assert(f2->getEdge()==e4||f2->getEdge()==e5||f2->getEdge()==e6);
	
	/* Move v1 to edge midpoint: */
	Point p=Point::zero();
	p.add(*v1);
	p.add(*v2);
	p.normalize(2);
	p.index=v1->index;
	v1->setPoint(p);
	
	/* Remove both faces from mesh: */
	e7->setOpposite(e8);
	e8->setOpposite(e7);
	if(e7->sharpness<e8->sharpness)
		e7->sharpness=e8->sharpness;
	else
		e8->sharpness=e7->sharpness;
	e9->setOpposite(e10);
	e10->setOpposite(e9);
	if(e9->sharpness<e10->sharpness)
		e9->sharpness=e10->sharpness;
	else
		e10->sharpness=e9->sharpness;
	v1->setEdge(e8);
	v3->setEdge(e7);
	v4->setEdge(e9);
	
	/* Remove v2 from mesh: */
	/* Note: Works currently only for closed meshes! */
	for(Edge* e=e10;e!=e8;e=e->getVertexSucc())
		{
		assert(e->getStart()==v2);
		e->setStart(v1);
		}
	
	assert(e7->getOpposite()==e8);
	assert(e8->getOpposite()==e7);
	assert(e9->getOpposite()==e10);
	assert(e10->getOpposite()==e9);
	assert(e7->getStart()==v3);
	assert(e8->getStart()==v1);
	assert(e9->getStart()==v4);
	assert(e10->getStart()==v1);
	
	/* Delete removed objects: */
	v2->setEdge(0);
	f1->setEdge(0);
	f2->setEdge(0);
	
	deleteEdge(e1);
	deleteEdge(e2);
	deleteEdge(e3);
	deleteEdge(e4);
	deleteEdge(e5);
	deleteEdge(e6);
	deleteVertex(v2);
	deleteFace(f1);
	deleteFace(f2);
	
	/* Update version numbers of all involved vertices: */
	++version;
	v1->version=version;
	Edge* e=v1->getEdge();
	do
		{
		e->getEnd()->version=version;
		e=e->getVertexSucc();
		}
	while(e!=v1->getEdge());
	
	return true;
	}
Пример #10
0
typename PolygonMesh<PointType>::FaceIterator PolygonMesh<PointType>::splitFaceDooSabin(const typename PolygonMesh<PointType>::FaceIterator& faceIt)
	{
	/* Calculate the face's centroid: */
	PointType centroid=PointType::zero();
	int numVertices=0;
	for(FaceEdgeIterator feIt=faceIt.beginEdges();feIt!=faceIt.endEdges();++feIt,++numVertices)
		centroid.add(*feIt->getStart());
	centroid.normalize(numVertices);
	
	/* Walk around the face again and create the inner face: */
	Face* innerFace=newFace();
	Edge* lastInnerEdge=0;
	Edge* outerEdge=faceIt->getEdge();
	for(int i=0;i<numVertices;++i,outerEdge=outerEdge->getFaceSucc())
		{
		/* Create a new vertex and a new edge: */
		PointType newPoint=PointType::zero();
		newPoint.add(centroid);
		newPoint.add(*outerEdge->getStart());
		newPoint.normalize(2);
		Vertex* newV=newVertex(newPoint);
		Edge* newE=newEdge();
		newV->setEdge(newE);
		newE->set(newV,innerFace,lastInnerEdge,0,0);
		newE->sharpness=0;
		if(lastInnerEdge!=0)
			lastInnerEdge->setFaceSucc(newE);
		else
			innerFace->setEdge(newE);
		lastInnerEdge=newE;
		}
	lastInnerEdge->setFaceSucc(innerFace->getEdge());
	innerFace->getEdge()->setFacePred(lastInnerEdge);
	
	/* Walk around the face again and create one quad face for each edge: */
	Edge* innerEdge=innerFace->getEdge();
	outerEdge=faceIt->getEdge();
	Edge* lastCrossEdge=0;
	Edge* firstCrossEdge;
	for(int i=0;i<numVertices;++i,innerEdge=innerEdge->getFaceSucc())
		{
		Edge* nextOuterEdge=outerEdge->getFaceSucc();
		
		/* Create a new face and three new edges: */
		Face* quad=newFace();
		quad->setEdge(outerEdge);
		Edge* e1=newEdge();
		Edge* e2=newEdge();
		Edge* e3=newEdge();
		e1->set(innerEdge->getEnd(),quad,e3,e2,innerEdge);
		e1->sharpness=0;
		innerEdge->setOpposite(e1);
		e2->set(innerEdge->getStart(),quad,e1,outerEdge,lastCrossEdge);
		e2->sharpness=0;
		if(lastCrossEdge!=0)
			lastCrossEdge->setOpposite(e2);
		else
			firstCrossEdge=e2;
		e3->set(outerEdge->getEnd(),quad,outerEdge,e1,0);
		e3->sharpness=0;
		lastCrossEdge=e3;
		outerEdge->set(outerEdge->getStart(),quad,e2,e3,outerEdge->getOpposite());
		
		outerEdge=nextOuterEdge;
		}
	lastCrossEdge->setOpposite(firstCrossEdge);
	firstCrossEdge->setOpposite(lastCrossEdge);
	
	/* Delete the old face and return the inner one: */
	deleteFace(faceIt.face);
	
	return FaceIterator(innerFace);
	}
Пример #11
0
typename PolygonMesh<PointType>::FaceIterator PolygonMesh<PointType>::removeEdge(const typename PolygonMesh<PointType>::EdgeIterator& edgeIt)
	{
	Edge* edge2=edgeIt->getOpposite();
	if(edge2!=0)
		{
		/* Have all edges of the second face point to the first instead: */
		Face* newFace=edgeIt->getFace();
		for(Edge* ePtr=edge2->getFaceSucc();ePtr!=edge2;ePtr=ePtr->getFaceSucc())
			ePtr->setFace(newFace);
		
		/* Fix up the edge's start vertex: */
		edgeIt->getFacePred()->setFaceSucc(edge2->getFaceSucc());
		edge2->getFaceSucc()->setFacePred(edgeIt->getFacePred());
		edgeIt->getStart()->setEdge(edge2->getFaceSucc());
		
		/* Fix up the edge's end vertex: */
		edgeIt->getFaceSucc()->setFacePred(edge2->getFacePred());
		edge2->getFacePred()->setFaceSucc(edgeIt->getFaceSucc());
		edge2->getStart()->setEdge(edgeIt->getFaceSucc());
		
		/* Remove the edge and the second face: */
		newFace->setEdge(edgeIt->getFaceSucc());
		deleteFace(edge2->getFace());
		deleteEdge(edgeIt.edge);
		deleteEdge(edge2);
		
		return FaceIterator(newFace);
		}
	else
		{
		/* Fix up all vertices around the face: */
		Edge* ePtr=edgeIt.edge;
		do
			{
			/* Fix up the edge's start vertex: */
			if(ePtr->getVertexSucc()!=0)
				ePtr->getStart()->setEdge(ePtr->getVertexSucc());
			else
				ePtr->getStart()->setEdge(ePtr->getVertexPred());
			
			/* Go to the next edge: */
			ePtr=ePtr->getFaceSucc();
			}
		while(ePtr!=edgeIt.edge);
		
		/* Delete the face: */
		deleteFace(ePtr->getFace());
		
		/* Delete all edges: */
		ePtr=edgeIt.edge;
		ePtr->getFacePred()->setFaceSucc(0);
		while(ePtr!=0)
			{
			Edge* next=ePtr->getFaceSucc();
			deleteEdge(ePtr);
			ePtr=next;
			}
		
		return FaceIterator(0);
		}
	}
Пример #12
0
typename PolygonMesh<PointType>::FaceIterator PolygonMesh<PointType>::vertexToFace(const typename PolygonMesh<PointType>::VertexIterator& vertexIt)
	{
	/* Remove solitary vertices: */
	if(vertexIt->getEdge()==0)
		{
		deleteVertex(vertexIt.vertex);
		return FaceIterator(0);
		}
	
	/* Walk around the vertex and flip its edges: */
	Face* vertexFace=newFace();
	Edge* lastEdge=0;
	Edge* ePtr=vertexIt->getEdge();
	do
		{
		Edge* nextEdge=ePtr->getFacePred()->getOpposite();
		
		/* Remove the edge from its current face and add it to the vertex face: */
		Edge* pred=ePtr->getFacePred();
		Edge* succ=ePtr->getFaceSucc();
		
		/* Test for the dangerous special case of a triangle: */
		if(succ->getFaceSucc()==pred)
			{
			/* Remove the triangle completely: */
			deleteFace(succ->getFace());
			deleteEdge(ePtr);
			deleteEdge(pred);
			
			/* Put the outside edge into the new face loop: */
			succ->set(succ->getStart(),vertexFace,lastEdge,0,succ->getOpposite());
			ePtr=succ;
			}
		else
			{
			pred->setFaceSucc(succ);
			succ->setFacePred(pred);
			ePtr->set(succ->getStart(),vertexFace,lastEdge,0,pred);
			pred->setOpposite(ePtr);
			ePtr->sharpness=pred->sharpness=0;
			pred->getFace()->setEdge(pred);

			#ifndef NDEBUG
			pred->getFace()->checkFace();
			#endif
			}
		
		if(lastEdge!=0)
			{
			lastEdge->setFaceSucc(ePtr);
			
			#ifndef NDEBUG
			ePtr->getStart()->checkVertex();
			#endif
			}
		else
			vertexFace->setEdge(ePtr);
		lastEdge=ePtr;
		
		ePtr=nextEdge;
		}
	while(ePtr!=vertexIt->getEdge());
	lastEdge->setFaceSucc(vertexFace->getEdge());
	vertexFace->getEdge()->setFacePred(lastEdge);
	
	#ifndef NDEBUG
	ePtr->getStart()->checkVertex();
	vertexFace->checkFace();
	#endif
	
	/* Delete the vertex and return the new face: */
	vertexIt->setEdge(0);
	deleteVertex(vertexIt.vertex);
	
	return FaceIterator(vertexFace);
	}
Пример #13
0
typename PolygonMesh<PointType>::FaceIterator PolygonMesh<PointType>::removeVertex(const typename PolygonMesh<PointType>::VertexIterator& vertexIt)
	{
	if(vertexIt->isInterior())
		{
		/* Combine all surrounding faces into a single face: */
		Face* vertexFace=newFace();
		Edge* lastEdge=0;
		Edge* ePtr=vertexIt->getEdge();
		ePtr->getOpposite()->setOpposite(0);
		while(ePtr!=0)
			{
			/* Re-arrange all face pointers: */
			Edge* vePtr=ePtr->getFaceSucc();
			while(vePtr!=ePtr->getFacePred())
				{
				vePtr->setFace(vertexFace);
				vePtr=vePtr->getFaceSucc();
				}
			
			/* Fix up the vertex: */
			ePtr->getEnd()->setEdge(ePtr->getFaceSucc());
			
			/* Delete the outgoing and incoming edges: */
			Edge* nextEptr=ePtr->getVertexSucc();
			ePtr->getFaceSucc()->setFacePred(lastEdge);
			if(lastEdge!=0)
				lastEdge->setFacePred(ePtr->getFaceSucc());
			else
				vertexFace->setEdge(ePtr->getFaceSucc());
			lastEdge=ePtr->getFacePred()->getFacePred();
			deleteFace(ePtr->getFace());
			deleteEdge(ePtr->getFacePred());
			deleteEdge(ePtr);
			
			/* Go to the next face: */
			ePtr=nextEptr;
			}
		
		/* Close the face loop: */
		lastEdge->setFaceSucc(vertexFace->getEdge());
		vertexFace->getEdge()->setFacePred(lastEdge);
		
		deleteVertex(vertexIt.vertex);
		return vertexFace;
		}
	else if(vertexIt->getEdge()!=0)
		{
		/* Go backwards until border edge is hit: */
		Edge* ePtr;
		for(ePtr=vertexIt->getEdge();ePtr->getOpposite()!=0;ePtr=ePtr->getVertexPred())
			;
		
		/* Remove all surrounding faces: */
		while(ePtr!=0)
			{
			Edge* nextEptr=ePtr->getVertexSucc();
			deleteFace(ePtr->getFace());
			Edge* fePtr=ePtr;
			do
				{
				Edge* nextFePtr=fePtr->getFaceSucc();
				
				/* Fix up the vertex: */
				if(nextFePtr!=ePtr)
					{
					if(nextFePtr->getVertexPred()!=0)
						nextFePtr->getStart()->setEdge(nextFePtr->getVertexPred());
					else
						nextFePtr->getStart()->setEdge(fePtr->getOpposite()->getFacePred());
					}
				
				/* Remove the edge: */
				if(fePtr->getOpposite()!=0)
					fePtr->getOpposite()->setOpposite(0);
				deleteEdge(fePtr);
				}
			while(fePtr!=ePtr);
			
			ePtr=nextEptr;
			}
		
		deleteVertex(vertexIt.vertex);
		return FaceIterator(0);
		}
	else // Dangling vertex
		{
		deleteVertex(vertexIt.vertex);
		return FaceIterator(0);
		}
	}