Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/boolop/intern/BOP_Merge2.cpp')
-rw-r--r--intern/boolop/intern/BOP_Merge2.cpp948
1 files changed, 0 insertions, 948 deletions
diff --git a/intern/boolop/intern/BOP_Merge2.cpp b/intern/boolop/intern/BOP_Merge2.cpp
deleted file mode 100644
index 6bec9ba8222..00000000000
--- a/intern/boolop/intern/BOP_Merge2.cpp
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- *
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Marc Freixas, Ken Hughes
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file boolop/intern/BOP_Merge2.cpp
- * \ingroup boolopintern
- */
-
-
-#include "BOP_Merge2.h"
-
-#ifdef BOP_NEW_MERGE
-
-static void deleteFace(BOP_Mesh *m, BOP_Face *face);
-
-/**
- * SINGLETON (use method BOP_Merge2.getInstance).
- */
-BOP_Merge2 BOP_Merge2::SINGLETON;
-
-#ifdef BOP_DEBUG
-void dumpmesh ( BOP_Mesh *m, bool force )
-{
- unsigned int nonmanifold = 0;
- {
- BOP_Edges edges = m->getEdges();
- int count = 0;
- for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
- ++count, ++edge) {
- if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue;
- BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
- BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
-
- if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
- int fcount = 0;
- BOP_Indexs faces = (*edge)->getFaces();
- for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
- BOP_Face *f = m->getFace(*face);
- if(f->getTAG()== UNCLASSIFIED) ++fcount;
- }
-
-
- if(fcount !=0 && fcount !=2 ) {
- ++nonmanifold;
- }
- }
- }
- if (!force && nonmanifold == 0) return;
- }
- if( nonmanifold )
- cout << nonmanifold << " edges detected" << endl;
-#ifdef BOP_DEBUG
- cout << "---------------------------" << endl;
-
- BOP_Edges edges = m->getEdges();
- int count = 0;
- for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
- ++count, ++edge) {
- BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
- BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
-
- if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
- int fcount = 0;
- BOP_Indexs faces = (*edge)->getFaces();
- cout << count << ", " << (*edge) << ", " << faces.size() << endl;
- for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
- BOP_Face *f = m->getFace(*face);
- if(f->getTAG()== UNCLASSIFIED) ++fcount;
- cout << " face " << f << endl;
- }
-
-
- if(fcount !=0 && fcount !=2 )
- cout << " NON-MANIFOLD" << endl;
- }
- }
-
- BOP_Faces faces = m->getFaces();
- count = 0;
- for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
- if( count < 12*2 || (*face)->getTAG() != BROKEN ) {
- cout << count << ", " << *face << endl;
- }
- ++count;
- }
-
- BOP_Vertexs verts = m->getVertexs();
- count = 0;
- for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) {
- cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl;
- BOP_Indexs edges = (*vert)->getEdges();
- for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
- BOP_Edge *edge = m->getEdge(*it);
- cout << " " << edge << endl;
- }
- }
- cout << "===========================" << endl;
-#endif
-}
-#endif
-
-/**
- * Simplifies a mesh, merging its faces.
- * @param m mesh
- * @param v index of the first mergeable vertex (can be removed by merge)
- */
-
-void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v)
-{
- m_mesh = m;
-
-#ifdef BOP_DEBUG
- cout << "##############################" << endl;
-#endif
- cleanup( );
-
- m_firstVertex = v;
- bool cont = false;
-
- // Merge faces
- mergeFaces();
-
- do {
- // Add quads ...
- cont = createQuads();
- // ... and merge new faces
- if( cont ) cont = mergeFaces();
-
-#ifdef BOP_DEBUG
- cout << "called mergeFaces " << cont << endl;
-#endif
- // ... until the merge is not succesful
- } while(cont);
-}
-
-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
- }
- }
- }
-}
-
-/**
- * Runs through mesh and makes sure vert/face/edge data is consistent. Most
- * importantly:
- * (1) mark edges which are no longer used
- * (2) remove broken faces from edges
- * (3) remove faces from mesh which have a single edge belonging to no other
- * face (non-manifold edges)
- */
-
-void BOP_Merge2::cleanup( void )
-{
- BOP_Edges edges = m_mesh->getEdges();
- for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) {
- BOP_Indexs faces = (*edge)->getFaces();
- for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) {
- BOP_Face *f = m_mesh->getFace(*face);
- if (f->getTAG()== UNCLASSIFIED);
- else (*edge)->removeFace(*face);
- }
- if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false);
- }
-
- BOP_Vertexs v = m_mesh->getVertexs();
- for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) {
- if( (*it)->getTAG() != BROKEN) {
- BOP_Indexs iedges = (*it)->getEdges();
- for(BOP_IT_Indexs i = iedges.begin();i!=iedges.end();i++)
- if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i );
- if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN);
- }
- }
- // clean_nonmanifold( m_mesh );
-}
-
-/**
- * Simplifies a mesh, merging its faces.
- */
-bool BOP_Merge2::mergeFaces()
-{
- BOP_Indexs mergeVertices;
- BOP_Vertexs vertices = m_mesh->getVertexs();
- BOP_IT_Vertexs v = vertices.begin();
- const BOP_IT_Vertexs verticesEnd = vertices.end();
-
- // Advance to first mergeable vertex
- advance(v,m_firstVertex);
- BOP_Index pos = m_firstVertex;
-
- // Add unbroken vertices to the list
- while(v!=verticesEnd) {
- if ((*v)->getTAG() != BROKEN) {
- mergeVertices.push_back(pos);
- }
-
- v++;
- pos++;
- }
-
- // Merge faces with that vertices
- return mergeFaces(mergeVertices);
-}
-
-/**
- * remove edges from vertices when the vertex is removed
- */
-void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert)
-{
- BOP_Indexs edges = vert->getEdges();
- BOP_Vertex *other;
-
- for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
- BOP_Edge *edge = m_mesh->getEdge(*it);
- BOP_Indexs edges2;
- if( edge->getVertex1() != v )
- other = m_mesh->getVertex( edge->getVertex1() );
- else
- other = m_mesh->getVertex( edge->getVertex2() );
- other->removeEdge(*it);
- vert->removeEdge(*it);
- }
-}
-
-/**
- * Simplifies a mesh, merging the faces with the specified vertices.
- * @param mergeVertices vertices to test
- * @return true if a face merge was performed
- */
-bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices)
-{
- // Check size > 0!
- if (mergeVertices.size() == 0) return false;
- bool didMerge = false;
-
- for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) {
- BOP_LFaces facesByOriginalFace;
- BOP_Index v = mergeVertices[i];
- BOP_Vertex *vert = m_mesh->getVertex(v);
-#ifdef BOP_DEBUG
- cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl;
- if (v==48)
- cout << "found vert 48" << endl;
-#endif
- if ( vert->getTAG() != BROKEN ) {
- getFaces(facesByOriginalFace,v);
-
- switch (facesByOriginalFace.size()) {
- case 0:
- // v has no unbroken faces (so it's a new BROKEN vertex)
- freeVerts( v, vert );
- vert->setTAG(BROKEN);
- break;
- case 2: {
-#ifdef BOP_DEBUG
- cout << "size of fBOF = " << facesByOriginalFace.size() << endl;
-#endif
- BOP_Faces ff = facesByOriginalFace.front();
- BOP_Faces fb = facesByOriginalFace.back();
- BOP_Index eindexs[2];
- int ecount = 0;
-
- // look for two edges adjacent to v which contain both ofaces
- BOP_Indexs edges = vert->getEdges();
-#ifdef BOP_DEBUG
- cout << " ff has " << ff.size() << " faces" << endl;
- cout << " fb has " << fb.size() << " faces" << endl;
- cout << " v has " << edges.size() << " edges" << endl;
-#endif
- for(BOP_IT_Indexs it = edges.begin(); it != edges.end();
- ++it ) {
- BOP_Edge *edge = m_mesh->getEdge(*it);
- BOP_Indexs faces = edge->getFaces();
-#ifdef BOP_DEBUG
- cout << " " << edge << " has " << edge->getFaces().size() << " faces" << endl;
-#endif
- if( faces.size() == 2 ) {
- BOP_Face *f0 = m_mesh->getFace(faces[0]);
- BOP_Face *f1 = m_mesh->getFace(faces[1]);
- if( f0->getOriginalFace() != f1->getOriginalFace() ) {
-#ifdef BOP_DEBUG
- cout << " " << f0 << endl;
- cout << " " << f1 << endl;
-#endif
- eindexs[ecount++] = (*it);
- }
- }
- }
- if(ecount == 2) {
-#ifdef BOP_DEBUG
- cout << " edge indexes are " << eindexs[0];
- cout << " and " << eindexs[1] << endl;
-#endif
- BOP_Edge *edge = m_mesh->getEdge(eindexs[0]);
- BOP_Index N = edge->getVertex1();
- if(N == v) N = edge->getVertex2();
-#ifdef BOP_DEBUG
- cout << " ## OK, replace "<<v<<" with "<<N << endl;
-#endif
- mergeVertex(ff , v, N );
- mergeVertex(fb , v, N );
-// now remove v and its edges
- vert->setTAG(BROKEN);
- for(BOP_IT_Indexs it = edges.begin(); it != edges.end();
- ++it ) {
- BOP_Edge *tedge = m_mesh->getEdge(*it);
- tedge->setUsed(false);
- }
- didMerge = true;
- }
-#ifdef BOP_DEBUG
- else {
- cout << " HUH: ecount was " << ecount << endl;
- }
-#endif
- }
- break;
- default:
- break;
- }
- }
- }
-
- return didMerge;
-}
-
-void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2)
-{
- for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) {
- if( (*face)->size() == 3)
- mergeVertex((BOP_Face3 *) *face, v1, v2);
- else
- mergeVertex((BOP_Face4 *) *face, v1, v2);
- (*face)->setTAG(BROKEN);
-#ifdef BOP_DEBUG
- cout << " breaking " << (*face) << endl;
-#endif
- }
-}
-
-/*
- * Remove a face from the mesh and from each edges's face list
- */
-
-static void deleteFace(BOP_Mesh *m, BOP_Face *face)
-{
- BOP_Index l2 = face->getVertex(0);
- BOP_Faces faces = m->getFaces();
- for(int i = face->size(); i-- ; ) {
- BOP_Indexs edges = m->getVertex(l2)->getEdges();
- BOP_Index l1 = face->getVertex(i);
- for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) {
- BOP_Edge *edge = m->getEdge(*it1);
- if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) ||
- ( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) {
- BOP_Indexs ef = edge->getFaces();
- for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) {
- if( m->getFace(*it) == face) {
- edge->removeFace(*it);
- break;
- }
- }
- break;
- }
- }
- l2 = l1;
- }
- face->setTAG(BROKEN);
-}
-
-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);
-}
-
-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);
-}
-
-// #define OLD_QUAD
-
-/**
- * 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);
-}
-
-/**
- * Returns a new quad (convex) from the merge of two triangles that share the
- * vertex index v.
- * @param faceI mesh triangle
- * @param faceJ mesh triangle
- * @param v vertex index shared by both triangles
- * @return a new convex quad if the merge is possible
- */
-BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ)
-{
- // Test if both triangles share a vertex index
- BOP_Index v;
- unsigned int i;
- for(i=0;i<3 ;i++) {
- v = faceI->getVertex(i);
- if( faceJ->containsVertex(v) ) break;
- }
- if (i == 3) return NULL;
-
- BOP_Face *faceK = NULL;
-
- // Get faces data
- BOP_Index prevI, nextI, prevJ, nextJ;
- faceI->getNeighbours(v,prevI,nextI);
- faceJ->getNeighbours(v,prevJ,nextJ);
- MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
- MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
- MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
- MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
- MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
-
- // Quad test
- if (prevI == nextJ) {
- if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
- BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
- faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- BOP_Index edge;
- m_mesh->getIndexEdge(v,prevI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- }
- }
- else if (nextI == prevJ) {
- if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
- BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
- faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- BOP_Index edge;
- m_mesh->getIndexEdge(v,nextI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- }
- }
- return faceK;
-}
-
-/**
- * Returns a new quad (convex) from the merge of two triangles that share the
- * vertex index v.
- * @param faceI mesh triangle
- * @param faceJ mesh triangle
- * @param v vertex index shared by both triangles
- * @return a new convex quad if the merge is possible
- */
-BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ)
-{
- // Test if triangle and quad share a vertex index
- BOP_Index v;
- unsigned int i;
- for(i=0;i<3 ;i++) {
- v = faceI->getVertex(i);
- if( faceJ->containsVertex(v) ) break;
- }
- if (i == 3) return NULL;
-
- BOP_Face *faceK = NULL;
-
- // Get faces data
- BOP_Index prevI, nextI, prevJ, nextJ, oppJ;
- faceI->getNeighbours(v,prevI,nextI);
- faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
-
- // Quad test
- BOP_Index edge;
- if (nextI == prevJ) {
- if (prevI == nextJ) { // v is in center
- faceK = new BOP_Face3(nextJ,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- m_mesh->getIndexEdge(v,prevI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- m_mesh->getIndexEdge(v,nextI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- freeVerts(v, m_mesh->getVertex(v));
- } else if (prevI == oppJ) { // nextI is in center
- faceK = new BOP_Face3(v,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- m_mesh->getIndexEdge(v,nextI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- m_mesh->getIndexEdge(prevI,nextI,edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- freeVerts(nextI, m_mesh->getVertex(nextI));
- }
- } else if (nextI == oppJ && prevI == nextJ ) { // prevI is in center
- faceK = new BOP_Face3(prevJ,v,oppJ,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- m_mesh->getIndexEdge(v,prevI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- m_mesh->getIndexEdge(nextI,prevI,edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- freeVerts(prevI, m_mesh->getVertex(prevI));
- }
- return faceK;
-}
-
-/**
- * Returns a new quad (convex) from the merge of two triangles that share the
- * vertex index v.
- * @param faceI mesh triangle
- * @param faceJ mesh triangle
- * @param v vertex index shared by both triangles
- * @return a new convex quad if the merge is possible
- */
-BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ)
-{
- BOP_Face *faceK = NULL;
- //
- // Test if both quads share a vertex index
- //
- BOP_Index v;
- unsigned int i;
- for(i=0;i<4 ;i++) {
- v = faceI->getVertex(i);
- if( faceJ->containsVertex(v) ) break;
- }
- if (i == 3) return NULL;
-
-
- // Get faces data
- BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
- faceI->getNeighbours(v,prevI,nextI,oppI);
- faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
-
- // Quad test
- BOP_Index edge;
- if (nextI == prevJ) {
- if (prevI == nextJ) { // v is in center
- faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- m_mesh->getIndexEdge(v,prevI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- m_mesh->getIndexEdge(v,nextI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- freeVerts(v, m_mesh->getVertex(v));
- } else if (oppI == oppJ) { // nextI is in center
- faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- m_mesh->getIndexEdge(v,nextI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- m_mesh->getIndexEdge(prevI,nextI,edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- freeVerts(nextI, m_mesh->getVertex(nextI));
- }
- } else if (prevI == nextJ && oppI == oppJ) { // prevI is in center
- faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
- faceK->setTAG(faceI->getTAG());
- m_mesh->getIndexEdge(v,prevI,edge);
- m_mesh->getVertex(v)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- m_mesh->getIndexEdge(nextI,prevI,edge);
- m_mesh->getVertex(nextI)->removeEdge(edge);
- m_mesh->getVertex(prevI)->removeEdge(edge);
- freeVerts(prevI, m_mesh->getVertex(prevI));
- }
- return faceK;
-}
-
-/**
- * Returns if a index is inside a set of indexs.
- * @param indexs set of indexs
- * @param i index
- * @return true if the index is inside the set, false otherwise
- */
-bool BOP_Merge2::containsIndex(BOP_Indexs indexs, BOP_Index i)
-{
- const BOP_IT_Indexs indexsEnd = indexs.end();
- for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) {
- if (*it == i) return true;
- }
- return false;
-}
-
-/**
- * Creates a list of lists L1, L2, ... LN where
- * LX = mesh faces with vertex v that come from the same original face
- * @param facesByOriginalFace list of faces lists
- * @param v vertex index
- */
-void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v)
-{
- // Get edges with vertex v
-
- BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
- const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
- for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {
- // For each edge, add its no broken faces to the output list
- BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
- BOP_Indexs faceIndexs = edge->getFaces();
- const BOP_IT_Indexs faceEnd = faceIndexs.end();
- for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
- BOP_Face* face = m_mesh->getFace(*faceIndex);
- if (face->getTAG() != BROKEN) {
- bool found = false;
- // Search if we already have created a list for the
- // faces that come from the same original face
- const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
- for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
- facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
- if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
- // Search that the face has not been added to the list before
- for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
- if ((*facesByOriginalFaceX)[i] == face) {
- found = true;
- break;
- }
- }
- if (!found) {
- // Add the face to the list
- if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
- else facesByOriginalFaceX->push_back(face);
- found = true;
- }
- break;
- }
- }
- if (!found) {
- // Create a new list and add the current face
- BOP_Faces facesByOriginalFaceX;
- facesByOriginalFaceX.push_back(face);
- facesByOriginalFace.push_back(facesByOriginalFaceX);
- }
- }
- }
- }
-}
-
-/**
- * Creates a list of lists L1, L2, ... LN where
- * LX = mesh faces with vertex v that come from the same original face
- * and without any of the vertices that appear before v in vertices
- * @param facesByOriginalFace list of faces lists
- * @param vertices vector with vertices indexs that contains v
- * @param v vertex index
- */
-void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v)
-{
- // Get edges with vertex v
- BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
- const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
- for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {
- // Foreach edge, add its no broken faces to the output list
- BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
- BOP_Indexs faceIndexs = edge->getFaces();
- const BOP_IT_Indexs faceEnd = faceIndexs.end();
- for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
- BOP_Face* face = m_mesh->getFace(*faceIndex);
- if (face->getTAG() != BROKEN) {
- // Search if the face contains any of the forbidden vertices
- bool found = false;
- for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) {
- if (face->containsVertex(*vertex)) {
- // face contains a forbidden vertex!
- found = true;
- break;
- }
- }
- if (!found) {
- // Search if we already have created a list with the
- // faces that come from the same original face
- const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
- for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
- facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
- if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
- // Search that the face has not been added to the list before
- for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
- if ((*facesByOriginalFaceX)[i] == face) {
- found = true;
- break;
- }
- }
- if (!found) {
- // Add face to the list
- if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
- else facesByOriginalFaceX->push_back(face);
- found = true;
- }
- break;
- }
- }
- if (!found) {
- // Create a new list and add the current face
- BOP_Faces facesByOriginalFaceX;
- facesByOriginalFaceX.push_back(face);
- facesByOriginalFace.push_back(facesByOriginalFaceX);
- }
- }
- }
- }
- }
-}
-
-#endif /* BOP_NEW_MERGE */