4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21
* All rights reserved.
23
* The Original Code is: all of this file.
25
* Contributor(s): none yet.
27
* ***** END GPL LICENSE BLOCK *****
30
/** \file boolop/intern/BOP_Mesh.cpp
31
* \ingroup boolopintern
36
#include "BOP_MathUtils.h"
40
#include "MEM_guardedalloc.h"
41
#include "BLI_blenlib.h"
46
#ifdef HASH_PRINTF_DEBUG
47
printf ("has hashing\n");
59
const BOP_IT_Vertexs vertexsEnd = m_vertexs.end();
60
for(BOP_IT_Vertexs itv=m_vertexs.begin();itv!=vertexsEnd;itv++){
65
const BOP_IT_Edges edgesEnd = m_edges.end();
66
for(BOP_IT_Edges ite=m_edges.begin();ite!=edgesEnd;ite++){
71
const BOP_IT_Faces facesEnd = m_faces.end();
72
for(BOP_IT_Faces itf=m_faces.begin();itf!=facesEnd;itf++){
80
BLI_freelistN( &hash[hashsize] );
89
* @param p vertex point
90
* @return mesh vertex index
92
BOP_Index BOP_Mesh::addVertex(MT_Point3 p)
94
m_vertexs.push_back(new BOP_Vertex(p));
95
return m_vertexs.size()-1;
100
* @param v1 mesh vertex index
101
* @param v2 mesh vertex index
102
* @return mesh edge index
104
BOP_Index BOP_Mesh::addEdge(BOP_Index v1, BOP_Index v2)
107
/* prepare a new hash entry for the edge */
109
EdgeEntry *h = (EdgeEntry *)MEM_callocN( sizeof( EdgeEntry ), "edgehash" );
111
/* store sorted, smallest vert first */
121
h->index = m_edges.size();
123
/* if hash index larger than hash list, extend the list */
124
if( minv >= hashsize ) {
125
int newsize = (minv + 8) & ~7;
126
ListBase *nhash = (ListBase *)MEM_mallocN(
127
newsize * sizeof( ListBase ),
129
/* copy old entries */
130
memcpy( nhash, hash, sizeof( ListBase ) * hashsize );
132
while( hashsize < newsize ) {
133
nhash[hashsize].first = nhash[hashsize].last = NULL;
141
/* add the entry to tail of the right hash list */
142
BLI_addtail( &hash[minv], h );
144
m_edges.push_back(new BOP_Edge(v1,v2));
145
return m_edges.size()-1;
150
* replace one vertex with another in the hash list
151
* @param o old mesh vertex index
152
* @param n new mesh vertex index
153
* @param x edge's other mesh vertex index
155
void BOP_Mesh::rehashVertex(BOP_Index o, BOP_Index n, BOP_Index x)
161
/* figure out where and what to look for */
170
/* if hash is valid, search for the match */
171
if( minv < hashsize ) {
172
for(edge = (EdgeEntry *)hash[minv].first;
173
edge; edge = edge->next ) {
174
if(edge->v1 == v1 && edge->v2 == v2)
178
/* NULL edge == no match */
180
#ifdef HASH_PRINTF_DEBUG
181
printf ("OOPS! didn't find edge (%d %d)\n",v1,v2);
185
#ifdef HASH_PRINTF_DEBUG
186
printf ("found edge (%d %d)\n",v1,v2);
188
/* remove the edge from the old hash list */
189
BLI_remlink( &hash[minv], edge );
191
/* decide where the new edge should go */
197
edge->v1 = x; edge->v2 = n;
200
/* if necessary, extend the hash list */
201
if( minv >= hashsize ) {
202
#ifdef HASH_PRINTF_DEBUG
203
printf ("OOPS! new vertex too large! (%d->%d)\n",o,n);
205
int newsize = (minv + 8) & ~7;
206
ListBase *nhash = (ListBase *)MEM_mallocN(
207
newsize * sizeof( ListBase ),
209
memcpy( nhash, hash, sizeof( ListBase ) * hashsize );
210
while( hashsize < newsize ) {
211
nhash[hashsize].first = nhash[hashsize].last = NULL;
219
/* add the entry to tail of the right hash list */
220
BLI_addtail( &hash[minv], edge );
222
#ifdef HASH_PRINTF_DEBUG
223
printf ("OOPS! hash not large enough for (%d %d)\n",minv,hashsize);
231
* @param face mesh face
232
* @return mesh face index
234
BOP_Index BOP_Mesh::addFace(BOP_Face *face)
237
return addFace((BOP_Face3 *)face);
239
return addFace((BOP_Face4 *)face);
243
* Adds a new triangle.
244
* @param face mesh triangle
245
* @return mesh face index
247
BOP_Index BOP_Mesh::addFace(BOP_Face3 *face)
249
BOP_Index indexface = m_faces.size();
251
BOP_Index index1 = face->getVertex(0);
252
BOP_Index index2 = face->getVertex(1);
253
BOP_Index index3 = face->getVertex(2);
255
m_faces.push_back((BOP_Face *)face);
259
if (!getIndexEdge(index1,index2,edge)) {
260
edge = addEdge(index1,index2);
261
getVertex(index1)->addEdge(edge);
262
getVertex(index2)->addEdge(edge);
265
getEdge(edge)->addFace(indexface);
267
if (!getIndexEdge(index2,index3,edge)) {
268
edge = addEdge(index2,index3);
269
getVertex(index2)->addEdge(edge);
270
getVertex(index3)->addEdge(edge);
273
getEdge(edge)->addFace(indexface);
275
if (!getIndexEdge(index3,index1,edge)) {
276
edge = addEdge(index3,index1);
277
getVertex(index3)->addEdge(edge);
278
getVertex(index1)->addEdge(edge);
281
getEdge(edge)->addFace(indexface);
283
if ((index1 == index2) || (index1 == index3) || (index2 == index3))
284
face->setTAG(BROKEN);
291
* @param face mesh quad
292
* @return mesh face index
294
BOP_Index BOP_Mesh::addFace(BOP_Face4 *face)
296
m_faces.push_back((BOP_Face *)face);
297
BOP_Index indexface = m_faces.size()-1;
299
BOP_Index index1 = face->getVertex(0);
300
BOP_Index index2 = face->getVertex(1);
301
BOP_Index index3 = face->getVertex(2);
302
BOP_Index index4 = face->getVertex(3);
306
if (!getIndexEdge(index1,index2,edge)) {
307
edge = addEdge(index1,index2);
308
getVertex(index1)->addEdge(edge);
309
getVertex(index2)->addEdge(edge);
312
getEdge(edge)->addFace(indexface);
314
if (!getIndexEdge(index2,index3,edge)) {
315
edge = addEdge(index2,index3);
316
getVertex(index2)->addEdge(edge);
317
getVertex(index3)->addEdge(edge);
320
getEdge(edge)->addFace(indexface);
322
if (!getIndexEdge(index3,index4,edge)) {
323
edge = addEdge(index3,index4);
324
getVertex(index3)->addEdge(edge);
325
getVertex(index4)->addEdge(edge);
328
getEdge(edge)->addFace(indexface);
330
if (!getIndexEdge(index4,index1,edge)) {
331
edge = addEdge(index4,index1);
332
getVertex(index4)->addEdge(edge);
333
getVertex(index1)->addEdge(edge);
336
getEdge(edge)->addFace(indexface);
338
if ((index1 == index2) || (index1 == index3) || (index1 == index4) ||
339
(index2 == index3) || (index2 == index4) || (index3 == index4))
340
face->setTAG(BROKEN);
342
return m_faces.size()-1;
346
* Returns if a faces set contains the specified face.
347
* @param faces faces set
349
* @return true if the set contains the specified face
351
bool BOP_Mesh::containsFace(BOP_Faces *faces, BOP_Face *face)
353
const BOP_IT_Faces facesEnd = faces->end();
354
for(BOP_IT_Faces it = faces->begin();it!=facesEnd;it++) {
362
* Returns the first edge with the specified vertex index from a list of edge indexs.
363
* @param edges edge indexs
364
* @param v vertex index
365
* @return first edge with the specified vertex index, NULL otherwise
367
BOP_Edge* BOP_Mesh::getEdge(BOP_Indexs edges, BOP_Index v)
369
const BOP_IT_Indexs edgesEnd = edges.end();
370
for(BOP_IT_Indexs it=edges.begin();it!=edgesEnd;it++){
371
BOP_Edge *edge = m_edges[*it];
372
if ((edge->getVertex1() == v) || (edge->getVertex2() == v))
379
* Returns the mesh edge with the specified vertex indexs.
380
* @param v1 vertex index
381
* @param v2 vertex index
382
* @return mesh edge with the specified vertex indexs, NULL otherwise
384
BOP_Edge* BOP_Mesh::getEdge(BOP_Index v1, BOP_Index v2)
390
/* figure out where and what to search for */
400
/* if hash index valid, search the list and return match if found */
401
if( minv < hashsize ) {
402
for(edge = (EdgeEntry *)hash[minv].first;
403
edge; edge = edge->next ) {
404
if(edge->v1 == v1 && edge->v2 == v2)
405
return m_edges[edge->index];
409
const BOP_IT_Edges edgesEnd = m_edges.end();
410
for(BOP_IT_Edges edge=m_edges.begin();edge!=edgesEnd;edge++) {
411
if (((*edge)->getVertex1() == v1 && (*edge)->getVertex2() == v2) ||
412
((*edge)->getVertex1() == v2 && (*edge)->getVertex2() == v1))
420
* Returns the mesh edge index with the specified vertex indexs.
421
* @param v1 vertex index
422
* @param v2 vertex index
423
* @param e edge index with the specified vertex indexs
424
* @return true if there is a mesh edge with the specified vertex indexs, false otherwise
426
bool BOP_Mesh::getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e)
432
/* figure out what and where to look */
442
/* if hash index is valid, look for a match */
443
if( minv < hashsize ) {
444
for(edge = (EdgeEntry *)hash[minv].first;
445
edge; edge = edge->next ) {
446
if(edge->v1 == v1 && edge->v2 == v2)
450
/* edge != NULL means match */
452
#ifdef HASH_PRINTF_DEBUG
453
printf ("found edge (%d %d)\n",v1,v2);
457
if( m_edges[e]->getUsed() == false ) {
458
m_edges[e]->setUsed(true);
459
m_vertexs[v1]->addEdge(e);
460
m_vertexs[v2]->addEdge(e);
465
#ifdef HASH_PRINTF_DEBUG
467
printf ("didn't find edge (%d %d)\n",v1,v2);
472
const BOP_IT_Edges edgesEnd = m_edges.end();
473
for(BOP_IT_Edges edge=m_edges.begin();edge!=edgesEnd;edge++,pos++) {
474
if (((*edge)->getVertex1() == v1 && (*edge)->getVertex2() == v2) ||
475
((*edge)->getVertex1() == v2 && (*edge)->getVertex2() == v1)){
485
* Returns the mesh edge on the specified face and relative edge index.
486
* @param face mesh face
487
* @param edge face relative edge index
488
* @return mesh edge on the specified face and relative index, NULL otherwise
490
BOP_Edge* BOP_Mesh::getEdge(BOP_Face *face, unsigned int edge)
493
return getEdge((BOP_Face3 *)face,edge);
495
return getEdge((BOP_Face4 *)face,edge);
499
* Returns the mesh edge on the specified triangle and relative edge index.
500
* @param face mesh triangle
501
* @param edge face relative edge index
502
* @return mesh edge on the specified triangle and relative index, NULL otherwise
504
BOP_Edge* BOP_Mesh::getEdge(BOP_Face3 *face, unsigned int edge)
508
return getEdge(m_vertexs[face->getVertex(0)]->getEdges(),face->getVertex(1));
510
return getEdge(m_vertexs[face->getVertex(1)]->getEdges(),face->getVertex(2));
512
return getEdge(m_vertexs[face->getVertex(2)]->getEdges(),face->getVertex(0));
519
* Returns the mesh edge on the specified quad and relative edge index.
520
* @param face mesh quad
521
* @param edge face relative edge index
522
* @return mesh edge on the specified quad and relative index, NULL otherwise
524
BOP_Edge * BOP_Mesh::getEdge(BOP_Face4 *face, unsigned int edge)
528
return getEdge(m_vertexs[face->getVertex(0)]->getEdges(),face->getVertex(1));
530
return getEdge(m_vertexs[face->getVertex(1)]->getEdges(),face->getVertex(2));
532
return getEdge(m_vertexs[face->getVertex(2)]->getEdges(),face->getVertex(3));
534
return getEdge(m_vertexs[face->getVertex(3)]->getEdges(),face->getVertex(0));
541
* Returns the mesh face with the specified vertex indexs.
542
* @param v1 vertex index
543
* @param v2 vertex index
544
* @param v3 vertex index
545
* @return mesh edge with the specified vertex indexs, NULL otherwise
547
BOP_Face* BOP_Mesh::getFace(BOP_Index v1, BOP_Index v2, BOP_Index v3)
549
const BOP_IT_Faces facesEnd = m_faces.end();
550
for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++) {
551
if ((*face)->containsVertex(v1) && (*face)->containsVertex(v2) &&
552
(*face)->containsVertex(v3))
559
* Returns the mesh face index with the specified vertex indexs.
560
* @param v1 vertex index
561
* @param v2 vertex index
562
* @param v3 vertex index
563
* @param f face index with the specified vertex indexs
564
* @return true if there is a mesh face with the specified vertex indexs, false otherwise
566
bool BOP_Mesh::getIndexFace(BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index &f)
569
const BOP_IT_Faces facesEnd = m_faces.end();
570
for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++,pos++) {
571
if ((*face)->containsVertex(v1) && (*face)->containsVertex(v2) &&
572
(*face)->containsVertex(v3)){
581
* Returns the vertices set of this mesh.
582
* @return vertices set
584
BOP_Vertexs &BOP_Mesh::getVertexs()
590
* Returns the edges set of this mesh.
593
BOP_Edges &BOP_Mesh::getEdges()
599
* Returns the faces set of this mesh.
602
BOP_Faces &BOP_Mesh::getFaces()
608
* Returns the mesh vertex with the specified index.
609
* @param i vertex index
610
* @return vertex with the specified index
612
BOP_Vertex* BOP_Mesh::getVertex(BOP_Index i)
618
* Returns the mesh edge with the specified index.
619
* @param i edge index
620
* @return edge with the specified index
622
BOP_Edge* BOP_Mesh::getEdge(BOP_Index i)
628
* Returns the mesh face with the specified index.
629
* @param i face index
630
* @return face with the specified index
632
BOP_Face* BOP_Mesh::getFace(BOP_Index i)
638
* Returns the number of vertices of this mesh.
639
* @return number of vertices
641
unsigned int BOP_Mesh::getNumVertexs()
643
return m_vertexs.size();
647
* Returns the number of edges of this mesh.
648
* @return number of edges
650
unsigned int BOP_Mesh::getNumEdges()
652
return m_edges.size();
656
* Returns the number of faces of this mesh.
657
* @return number of faces
659
unsigned int BOP_Mesh::getNumFaces()
661
return m_faces.size();
665
* Returns the number of vertices of this mesh with the specified tag.
666
* @return number of vertices with the specified tag
668
unsigned int BOP_Mesh::getNumVertexs(BOP_TAG tag)
670
unsigned int count = 0;
671
const BOP_IT_Vertexs vertexsEnd = m_vertexs.end();
672
for(BOP_IT_Vertexs vertex=m_vertexs.begin();vertex!=vertexsEnd;vertex++) {
673
if ((*vertex)->getTAG() == tag) count++;
678
* Returns the number of faces of this mesh with the specified tag.
679
* @return number of faces with the specified tag
681
unsigned int BOP_Mesh::getNumFaces(BOP_TAG tag)
683
unsigned int count = 0;
684
const BOP_IT_Faces facesEnd = m_faces.end();
685
for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++) {
686
if ((*face)->getTAG() == tag) count++;
692
* Marks faces which bad edges as BROKEN (invalid face, no further processing).
693
* @param edge edge which is being replaced
694
* @param mesh mesh containing faces
697
static void removeBrokenFaces( BOP_Edge *edge, BOP_Mesh *mesh )
699
BOP_Faces m_faces = mesh->getFaces();
701
BOP_Indexs edgeFaces = edge->getFaces();
702
const BOP_IT_Indexs edgeFacesEnd = edgeFaces.end();
703
for(BOP_IT_Indexs idxFace=edgeFaces.begin();idxFace!=edgeFacesEnd;
705
m_faces[*idxFace]->setTAG(BROKEN);
709
* Replaces a vertex index.
710
* @param oldIndex old vertex index
711
* @param newIndex new vertex index
713
BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
715
BOP_IT_Indexs oldEdgeIndex;
716
if (oldIndex==newIndex) return newIndex;
718
// Update faces, edges and vertices
719
BOP_Vertex *oldVertex = m_vertexs[oldIndex];
720
BOP_Vertex *newVertex = m_vertexs[newIndex];
721
BOP_Indexs oldEdges = oldVertex->getEdges();
723
// Update faces to the newIndex
724
BOP_IT_Indexs oldEdgesEnd = oldEdges.end();
725
for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd;
727
BOP_Edge *edge = m_edges[*oldEdgeIndex];
728
if ((edge->getVertex1()==oldIndex && edge->getVertex2()==newIndex) ||
729
(edge->getVertex2()==oldIndex && edge->getVertex1()==newIndex)) {
730
// Remove old edge ==> set edge faces to BROKEN
731
removeBrokenFaces( edge, this );
732
oldVertex->removeEdge(*oldEdgeIndex);
733
newVertex->removeEdge(*oldEdgeIndex);
736
BOP_Indexs faces = edge->getFaces();
737
const BOP_IT_Indexs facesEnd = faces.end();
738
for(BOP_IT_Indexs face=faces.begin();face!=facesEnd;face++) {
739
if (m_faces[*face]->getTAG()!=BROKEN)
740
m_faces[*face]->replaceVertexIndex(oldIndex,newIndex);
745
oldEdgesEnd = oldEdges.end();
746
for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd;
748
BOP_Edge * edge = m_edges[*oldEdgeIndex];
750
BOP_Index v1 = edge->getVertex1();
752
v1 = (v1==oldIndex?edge->getVertex2():v1);
753
if ((edge2 = getEdge(newIndex,v1)) == NULL) {
754
edge->replaceVertexIndex(oldIndex,newIndex);
755
if ( edge->getVertex1() == edge->getVertex2() ) {
756
removeBrokenFaces( edge, this );
757
oldVertex->removeEdge(*oldEdgeIndex);
760
rehashVertex(oldIndex,newIndex,v1);
762
newVertex->addEdge(*oldEdgeIndex);
765
BOP_Indexs faces = edge->getFaces();
766
const BOP_IT_Indexs facesEnd = faces.end();
767
for(BOP_IT_Indexs f=faces.begin();f!=facesEnd;f++) {
768
if (m_faces[*f]->getTAG()!=BROKEN)
771
BOP_Vertex *oppositeVertex = m_vertexs[v1];
772
oppositeVertex->removeEdge(*oldEdgeIndex);
773
edge->replaceVertexIndex(oldIndex,newIndex);
774
if ( edge->getVertex1() == edge->getVertex2() ) {
775
removeBrokenFaces( edge, this );
776
oldVertex->removeEdge(*oldEdgeIndex);
777
newVertex->removeEdge(*oldEdgeIndex);
780
rehashVertex(oldIndex,newIndex,v1);
784
oldVertex->setTAG(BROKEN);
789
bool BOP_Mesh::isClosedMesh()
791
for(unsigned int i=0; i<m_edges.size(); i++) {
792
BOP_Edge *edge = m_edges[i];
793
BOP_Indexs faces = edge->getFaces();
794
unsigned int count = 0;
795
const BOP_IT_Indexs facesEnd = faces.end();
796
for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) {
797
if (m_faces[*it]->getTAG()!=BROKEN)
801
if ((count%2)!=0) return false;
809
/******************************************************************************
811
* This functions are used to test the mesh state and debug program errors. *
812
******************************************************************************/
817
void BOP_Mesh::print()
820
cout << "--Faces--" << endl;
821
for(i=0;i<m_faces.size();i++){
822
cout << "Face " << i << ": " << m_faces[i] << endl;
825
cout << "--Vertices--" << endl;
826
for(i=0;i<m_vertexs.size();i++){
827
cout << "Point " << i << ": " << m_vertexs[i]->getPoint() << endl;
834
void BOP_Mesh::printFormat(BOP_Faces *faces)
837
for(unsigned int it=1;it<faces->size();it++) {
838
if ((*faces)[it]->getTAG()!=BROKEN) {
839
cout << m_vertexs[(*faces)[it]->getVertex(0)]->getPoint() << " ";
840
cout << m_vertexs[(*faces)[it]->getVertex(1)]->getPoint() << " ";
841
cout << m_vertexs[(*faces)[it]->getVertex(2)]->getPoint() << endl;
850
void BOP_Mesh::saveFormat(BOP_Faces *faces,char *filename)
852
ofstream fout(filename);
854
if (!fout.is_open()) {
855
cerr << "BOP_Mesh::saveFormat Error: Could not create file." << endl;
859
unsigned int count = 0;
861
for(unsigned int it=0;it<faces->size();it++) {
862
if ((*faces)[it]->getTAG()!=BROKEN) {
868
fout << count << endl;
870
for(unsigned int it=0;it<faces->size();it++) {
871
if ((*faces)[it]->getTAG()!=BROKEN){
872
fout << m_vertexs[(*faces)[it]->getVertex(0)]->getPoint() << " ";
873
fout << m_vertexs[(*faces)[it]->getVertex(1)]->getPoint() << " ";
874
fout << m_vertexs[(*faces)[it]->getVertex(2)]->getPoint() << endl;
885
void BOP_Mesh::printFormat()
887
cout << "--Vertices--" << endl;
888
if (m_vertexs.size()>0) {
889
cout << "{" << m_vertexs[0]->getPoint().x() << ",";
890
cout << m_vertexs[0]->getPoint().y() << ",";
891
cout << m_vertexs[0]->getPoint().z() << "}";
892
for(unsigned int i=1;i<m_vertexs.size();i++) {
893
cout << ",{" << m_vertexs[i]->getPoint().x() << ",";
894
cout << m_vertexs[i]->getPoint().y() << ",";
895
cout << m_vertexs[i]->getPoint().z() << "}";
900
cout << "--Faces--" << endl;
901
if (m_faces.size()>0) {
902
cout << "{" << m_faces[0]->getVertex(0) << ",";
903
cout << m_faces[0]->getVertex(1) << "," << m_faces[0]->getVertex(2) << "}";
904
for(unsigned int i=1;i<m_faces.size();i++) {
905
cout << ",{" << m_faces[i]->getVertex(0) << ",";
906
cout << m_faces[i]->getVertex(1) << "," << m_faces[i]->getVertex(2) << "}";
915
void BOP_Mesh::printFace(BOP_Face *face, int col)
917
cout << "--Face" << endl;
918
cout << m_vertexs[face->getVertex(0)]->getPoint();
919
cout << " " << m_vertexs[face->getVertex(1)]->getPoint();
920
cout << " " << m_vertexs[face->getVertex(2)]->getPoint();
922
cout << " " << m_vertexs[face->getVertex(3)]->getPoint();
923
cout << " " << col << endl;
929
void BOP_Mesh::testMesh()
933
unsigned int nedges=0,i;
934
for(i=0;i<m_edges.size();i++) {
935
BOP_Edge *edge = m_edges[i];
936
BOP_Indexs faces = edge->getFaces();
937
unsigned int count = 0;
938
const BOP_IT_Indexs facesEnd = faces.end();
939
for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) {
940
if (m_faces[*it]->getTAG()!=BROKEN) {
941
cares[count] = m_faces[*it];
947
if ((count%2)!=0) nedges++;
950
cout << nedges << " wrong edges." << endl;
952
cout << "well edges." << endl;
954
unsigned int duplFaces = 0;
955
unsigned int wrongFaces = 0;
956
for(i=0;i<m_faces.size();i++){
957
BOP_Face *faceI = m_faces[i];
958
if (faceI->getTAG()==BROKEN)
961
if (testFace(faceI)){
963
cout << "Wrong Face: " << faceI << endl;
966
for(unsigned int j=i+1;j<m_faces.size();j++){
967
BOP_Face *faceJ = m_faces[j];
969
if (faceJ->getTAG()==BROKEN)
972
if (testFaces(faceI,faceJ)){
974
cout << "Duplicate FaceI: " << faceI << endl;
975
cout << "Duplicate FaceJ: " << faceJ << endl;
980
cout << duplFaces << " duplicate faces." << endl;
981
cout << wrongFaces << " wrong faces." << endl;
987
bool BOP_Mesh::testFace(BOP_Face *face){
989
for(unsigned int i=0;i<face->size();i++){
990
for(unsigned int j=i+1;j<face->size();j++){
991
if (face->getVertex(i)==face->getVertex(j))
1002
bool BOP_Mesh::testFaces(BOP_Face *faceI, BOP_Face *faceJ){
1004
if (faceI->size()<faceJ->size()){
1005
for(unsigned int i=0;i<faceI->size();i++){
1006
if (!faceJ->containsVertex(faceI->getVertex(i)))
1009
//faceI->setTAG(BROKEN);
1012
for(unsigned int i=0;i<faceJ->size();i++){
1013
if (!faceI->containsVertex(faceJ->getVertex(i)))
1016
//faceJ->setTAG(BROKEN);
1025
void BOP_Mesh::testPlane(BOP_Face *face)
1027
MT_Plane3 plane1(m_vertexs[face->getVertex(0)]->getPoint(),
1028
m_vertexs[face->getVertex(1)]->getPoint(),
1029
m_vertexs[face->getVertex(2)]->getPoint());
1031
if (BOP_orientation(plane1,face->getPlane()) < 0) {
1032
cout << "Test Plane " << face << " v1: ";
1033
cout << m_vertexs[face->getVertex(0)]->getPoint() << " v2: ";
1034
cout << m_vertexs[face->getVertex(1)]->getPoint() << " v3: ";
1035
cout << m_vertexs[face->getVertex(2)]->getPoint() << " plane: ";
1036
cout << face->getPlane() << endl;
1037
cout << "Incorrect vertices order!!! plane1: " << plane1 << " (";
1038
cout << BOP_orientation(plane1,face->getPlane()) << ") " << " invert ";
1039
cout << MT_Plane3(m_vertexs[face->getVertex(2)]->getPoint(),
1040
m_vertexs[face->getVertex(1)]->getPoint(),
1041
m_vertexs[face->getVertex(0)]->getPoint()) << endl;
1042
if (BOP_collinear(m_vertexs[face->getVertex(0)]->getPoint(),
1043
m_vertexs[face->getVertex(1)]->getPoint(),
1044
m_vertexs[face->getVertex(2)]->getPoint())) {
1045
cout << " COLLINEAR!!!" << endl;
1056
bool BOP_Mesh::testEdges(BOP_Faces *facesObj)
1058
for(unsigned int i=0;i<m_edges.size();i++) {
1059
BOP_Edge *edge = m_edges[i];
1060
BOP_Indexs faces = edge->getFaces();
1061
unsigned int count = 0;
1062
const BOP_IT_Indexs facesEnd = faces.end();
1063
for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) {
1064
if ((m_faces[*it]->getTAG()!=BROKEN) && containsFace(facesObj,m_faces[*it]))
1078
void BOP_Mesh::updatePlanes()
1080
const BOP_IT_Faces facesEnd = m_faces.end();
1081
for(BOP_IT_Faces it = m_faces.begin();it!=facesEnd;it++) {
1082
BOP_Face *face = *it;
1083
MT_Plane3 plane(m_vertexs[face->getVertex(0)]->getPoint(),
1084
m_vertexs[face->getVertex(1)]->getPoint(),
1085
m_vertexs[face->getVertex(2)]->getPoint());
1086
face->setPlane(plane);