00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <set>
00025 #include <cfloat>
00026
00027
00028
00029
00030
00031 #include "message-macros.hh"
00032
00033 #include "corefine-3d-face-face.hh"
00034
00035 using namespace std;
00036 using namespace GMap3d;
00037
00038
00039
00040 #define a0 FMap->alpha0
00041 #define a1 FMap->alpha1
00042 #define a2 FMap->alpha2
00043 #define a3 FMap->alpha3
00044
00045
00046 #define VTX(d) ((CAttributeVertex*)FMap->getDirectInfo(d, FVertexDI))
00047 #define LINK(d) ((CDart*)FMap->getDirectInfo(d, FLinkedVertexDI))
00048
00049 #ifdef DEBUG_MARKS
00050 #define freeMark(m) (assert(FMap->isWholeMapUnmarked(m)), FMap->freeMark(m))
00051 #else // DEBUG_MARKS
00052 #define freeMark(m) (FMap->freeMark(m))
00053 #endif // DEBUG_MARKS
00054
00055
00056
00057 struct SFaceListIterators
00058 {
00059 SFaceListIterators() {}
00060 SFaceListIterators(TCorefFaceList::iterator f1, TCorefFaceList::iterator l1,
00061 TCorefFaceList::iterator f2, TCorefFaceList::iterator l2)
00062 : first1(f1), last1(l1), first2(f2), last2(l2) {}
00063 TCorefFaceList::iterator first1, last1, first2, last2;
00064 };
00065
00066
00067
00068 CCorefine3dFF::CCorefine3dFF(CGMapVertex * AMap, bool ACalculateOrientation,
00069 TCoordinate AEpsilon, int AVertexDI)
00070 : CCorefine(AMap, AEpsilon), FCalculateOrientation(ACalculateOrientation),
00071 FOptimizeSearch(true), FGridResolution(64), FDisplayMessages(2)
00072 {
00073 FTools = new CCorefine3dTools(FMap, AEpsilon);
00074 CBoundingBox::setEpsilon(AEpsilon);
00075
00076 if (AVertexDI < 0) {
00077 FLocalVertexDI = true;
00078 FVertexDI = FMap->getNewDirectInfo();
00079 }
00080 else {
00081 FLocalVertexDI = false;
00082 FVertexDI = AVertexDI;
00083 }
00084 FMesh1 = FMesh2 = NULL;
00085 }
00086
00087
00088
00089 CCorefine3dFF::~CCorefine3dFF()
00090 {
00091 if (FLocalVertexDI)
00092 FMap->freeDirectInfo(FVertexDI);
00093 clear();
00094 delete FTools;
00095 }
00096
00097
00098
00099 int CCorefine3dFF::corefine(CDart *& AMesh1, CDart *& AMesh2,
00100 bitset<NB_MARKS> ACopyMarks)
00101 {
00102 CDart *meshes[2] = {AMesh1, AMesh2};
00103
00104 splitMeshes(AMesh1, AMesh2, ACopyMarks);
00105 mergeMeshes();
00106 removeDoubleFaces(meshes, 2);
00107
00108 AMesh1 = meshes[0];
00109 AMesh2 = meshes[1];
00110
00111 return FInterEdges.size() / 2;
00112 }
00113
00114
00115
00116 int CCorefine3dFF::corefine(int AMark1, int AMark2,
00117 bitset<NB_MARKS> ACopyMarks)
00118 {
00119 splitMeshes(AMark1, AMark2, ACopyMarks);
00120 mergeMeshes();
00121 removeDoubleFaces();
00122
00123 return FInterEdges.size() / 2;
00124 }
00125
00126
00127
00128 void CCorefine3dFF::splitMeshes(CDart * AMesh1, CDart * AMesh2,
00129 bitset<NB_MARKS> ACopyMarks)
00130 {
00131 DEBUG_FUNCTION;
00132
00133 CTime start, end;
00134
00135 FInterPointDI = FMap->getNewDirectInfo();
00136 FLinkedVertexDI = FMap->getNewDirectInfo();
00137 FFictiveVertexMark = FMap->getNewMark();
00138 FFictiveEdgeMark = FMap->getNewMark();
00139
00140 clear();
00141
00142 if (FDisplayMessages) cout << "Initialisation des maillages" << endl;
00143 start.updateTime();
00144 CBoundingBox box1 = initMesh(AMesh1);
00145 CBoundingBox box2 = initMesh(AMesh2);
00146 end.updateTime();
00147 FInitialisationTime = end - start;
00148 if (FDisplayMessages) cout << "Durée de l'initialisation : "
00149 << FInitialisationTime << endl;
00150
00151 if (FCalculateOrientation) {
00152 if (FDisplayMessages) cout << "Orientation des maillages" << endl;
00153 start.updateTime();
00154 AMesh1 = FTools->findWellOrientedDart(AMesh1, FVertexDI);
00155 AMesh2 = FTools->findWellOrientedDart(AMesh2, FVertexDI);
00156 end.updateTime();
00157 if (FDisplayMessages) cout << "Durée de l'orientation : "
00158 << end - start << endl;
00159 }
00160
00161 if (FDisplayMessages) cout << "Construction des listes de faces" << endl;
00162 start.updateTime();
00163 FMesh1 = buildFaceList(AMesh1);
00164 FMesh2 = buildFaceList(AMesh2);
00165 end.updateTime();
00166 FFaceListCreationTime = end - start;
00167 if (FDisplayMessages) cout << "Durée de la construction des listes : "
00168 << FFaceListCreationTime << endl;
00169 if (FDisplayMessages)
00170 cout << "Le premier objet possède " << FMesh1->size()
00171 << (FMesh1->size() > 1 ? " faces" : " face") << endl
00172 << "Le second objet possède " << FMesh2->size()
00173 << (FMesh2->size() > 1 ? " faces" : " face")<< endl;
00174
00175 if (FOptimizeSearch) {
00176 if (FDisplayMessages) cout << "Réduction de la taille des listes" << endl;
00177 start.updateTime();
00178 reduceFaceLists(FMesh1, FMesh2, box1 + box2);
00179 end.updateTime();
00180 FFaceListReductionTime = end - start;
00181 if (FDisplayMessages) cout << "Durée de la réduction : "
00182 << FFaceListReductionTime << endl;
00183 }
00184
00185 splitMeshes(ACopyMarks);
00186
00187 if (FDisplayMessages) cout << "Nettoyage des maillages" << endl;
00188 start.updateTime();
00189 cleanMesh(AMesh1);
00190 cleanMesh(AMesh2);
00191 end.updateTime();
00192 if (FDisplayMessages) cout << "Durée du nettoyage : " << end - start << endl;
00193
00194 FMap->freeDirectInfo(FInterPointDI);
00195 FMap->freeDirectInfo(FLinkedVertexDI);
00196 freeMark(FFictiveVertexMark);
00197 freeMark(FFictiveEdgeMark);
00198 }
00199
00200
00201
00202 void CCorefine3dFF::splitMeshes(int AMark1, int AMark2,
00203 bitset<NB_MARKS> ACopyMarks)
00204 {
00205 DEBUG_FUNCTION;
00206
00207 CTime start, end;
00208
00209 FInterPointDI = FMap->getNewDirectInfo();
00210 FLinkedVertexDI = FMap->getNewDirectInfo();
00211 FFictiveVertexMark = FMap->getNewMark();
00212 FFictiveEdgeMark = FMap->getNewMark();
00213
00214 clear();
00215
00216 if (FDisplayMessages) cout << "Initialisation des faces" << endl;
00217 start.updateTime();
00218 CBoundingBox box1 = initFaces(AMark1);
00219 CBoundingBox box2 = initFaces(AMark2);
00220 end.updateTime();
00221 if (FDisplayMessages) cout << "Durée de l'initialisation : "
00222 << end - start << endl;
00223
00224 if (FDisplayMessages) cout << "Construction des listes de faces" << endl;
00225 start.updateTime();
00226 FMesh1 = buildFaceList(AMark1);
00227 FMesh2 = buildFaceList(AMark2);
00228 end.updateTime();
00229 if (FDisplayMessages) cout << "Durée de la construction des listes : "
00230 << end - start << endl;
00231 if (FDisplayMessages)
00232 cout << "Le premier objet possède " << FMesh1->size()
00233 << (FMesh1->size() > 1 ? " faces" : " face") << endl
00234 << "Le second objet possède " << FMesh2->size()
00235 << (FMesh2->size() > 1 ? " faces" : " face")<< endl;
00236
00237 if (FOptimizeSearch) {
00238 if (FDisplayMessages) cout << "Réduction de la taille des listes" << endl;
00239 start.updateTime();
00240 reduceFaceLists(FMesh1, FMesh2, box1 + box2);
00241 end.updateTime();
00242 if (FDisplayMessages) cout << "Durée de la réduction : "
00243 << end - start << endl;
00244 }
00245
00246 splitMeshes(ACopyMarks);
00247
00248 if (FDisplayMessages) cout << "Nettoyage des faces" << endl;
00249 start.updateTime();
00250 for (CDynamicCoverageAll dca(FMap); dca.cont(); ++dca) {
00251 FMap->unsetMark(*dca, FFictiveVertexMark);
00252 FMap->unsetMark(*dca, FFictiveEdgeMark);
00253 }
00254 end.updateTime();
00255 if (FDisplayMessages) cout << "Durée du nettoyage : " << end - start << endl;
00256
00257 FMap->freeDirectInfo(FInterPointDI);
00258 FMap->freeDirectInfo(FLinkedVertexDI);
00259 freeMark(FFictiveVertexMark);
00260 freeMark(FFictiveEdgeMark);
00261 }
00262
00263
00264
00265 void CCorefine3dFF::mergeMeshes()
00266 {
00267 if (!FInterEdges.empty()) {
00268 CTime start, end;
00269
00270 if (FDisplayMessages) cout << "Mise à jour de le topologie" << endl;
00271 start.updateTime();
00272
00273 int face_plane_di = FMap->getNewDirectInfo();
00274 int negative_mark = FMap->getNewMark();
00275
00276 for (CDynamicCoverageAll dca(FMap); dca.cont(); ++dca)
00277 FMap->setDirectInfo(*dca, face_plane_di, NULL);
00278
00279 assignFacesPlaneInfo(face_plane_di, negative_mark, FMesh1);
00280 assignFacesPlaneInfo(face_plane_di, negative_mark, FMesh2);
00281
00282 sortFacesAroundEdges(face_plane_di, negative_mark);
00283
00284 removeFacesPlaneInfo(face_plane_di, negative_mark, FMesh1);
00285 removeFacesPlaneInfo(face_plane_di, negative_mark, FMesh2);
00286
00287 FMap->freeDirectInfo(face_plane_di);
00288 freeMark(negative_mark);
00289
00290 end.updateTime();
00291 FMergeTime = end - start;
00292 if (FDisplayMessages) cout << "Durée de la mise à jour : "
00293 << FMergeTime << endl;
00294 }
00295 }
00296
00297
00298
00299 void CCorefine3dFF::removeDoubleFaces(CDart **ADarts, int ANbDarts)
00300 {
00301 DEBUG_FUNCTION;
00302
00303 if (!FDoubleFaces.empty()) {
00304 int mark = FMap->getNewMark();
00305 int i;
00306 CTime start, end;
00307
00308 if (FDisplayMessages) cout << "Suppression des faces doubles" << endl;
00309 start.updateTime();
00310
00311 markDoubleFaces(mark);
00312
00313 for (i = 0; i < ANbDarts; ++i)
00314 if (FMap->isMarked(ADarts[i], mark)) {
00315 CDart *d = ADarts[i];
00316 do d = a3(FTools->alpha2(d));
00317 while (d != ADarts[i] && FMap->isMarked(d, mark));
00318 ADarts[i] = (d == ADarts[i] ? NULL : d);
00319 }
00320
00321 TCorefFaceList::iterator fit, tmp_fit;
00322 TCorefFaceList *face_list[2] = {FMesh1, FMesh2};
00323 for (i = 0; i < 2; ++i)
00324 for (fit = face_list[i]->begin(); fit != face_list[i]->end(); ) {
00325 tmp_fit = fit++;
00326 if (FMap->isMarked(tmp_fit->face, mark))
00327 face_list[i]->erase(tmp_fit);
00328 }
00329
00330 list<CDart*>::iterator it;
00331 for (it = FInterEdges.begin(); it != FInterEdges.end(); ++it)
00332 if (FMap->isMarked(*it, mark))
00333 *it = NULL;
00334
00335 while (!FDoubleFaces.empty()) {
00336 removeDoubleFace(FDoubleFaces.front());
00337 FDoubleFaces.pop_front();
00338 }
00339
00340 freeMark(mark);
00341
00342 end.updateTime();
00343 if (FDisplayMessages) cout << "Durée de la suppression : "
00344 << end - start << endl;
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 void CCorefine3dFF::linkCompounds(CDart * AMesh1, CDart * AMesh2,
00457 std::bitset<NB_MARKS> ACopyMarks)
00458 {
00459 DEBUG_FUNCTION;
00460
00461 if (FInterEdges.empty()) {
00462 CDart *d1 = AMesh1, *d2 = AMesh2;
00463 CVertex line = *VTX(d2) - *VTX(d1);
00464
00465 if (line.getX() == 0.0 && line.getY() == 0.0 && line.getZ() == 0.0) {
00466 d1 = a1(a0(d1));
00467 line = *VTX(d2) - *VTX(d1);
00468 }
00469
00470 CPlane ref_plane(line, *VTX(d1));
00471 TCoordinate dist, best_dist = 0.0;
00472 CVertex normal;
00473 int mark = FMap->getNewMark();
00474
00475 MSG("Recherche d'un sommet de l'enveloppe convexe du premier objet");
00476 FMap->halfMarkOrbit(d1, ORBIT_CC, mark);
00477 FMap->unmarkOrbit(d1, ORBIT_VERTEX, mark);
00478 for (CDynamicCoverageCC dcc(FMap, d1); dcc.cont(); ++dcc)
00479 if (FMap->isMarked(*dcc, mark)) {
00480 FMap->unmarkOrbit(*dcc, ORBIT_VERTEX, mark);
00481 dist = ref_plane.pointDistance(*VTX(*dcc));
00482 if (dist > best_dist) {
00483 d1 = *dcc;
00484 best_dist = dist;
00485 }
00486 }
00487
00488 MSG("Calcul d'un nouveau vecteur directeur");
00489 line = *VTX(d2) - *VTX(d1);
00490 if (line.getX() == 0.0 && line.getY() == 0.0 && line.getZ() == 0.0) {
00491 d2 = a1(a0(d2));
00492 line = *VTX(d2) - *VTX(d1);
00493 }
00494
00495 MSG("Recherche d'une arête de l'enveloppe convexe du premier objet");
00496 ref_plane.setPlane(line, *VTX(d1));
00497 best_dist = -FLT_MAX;
00498 FMap->halfMarkOrbit(d1, ORBIT_VERTEX, mark);
00499 for (CDynamicCoverageVertex dcv(FMap, d1); dcv.cont(); ++dcv)
00500 if (FMap->isMarked(*dcv, mark)) {
00501 FMap->unsetMark(*dcv, mark);
00502 normal = FTools->faceNormalVector(*dcv, FVertexDI);
00503 if (!FMap->isFree2(*dcv))
00504 normal += FTools->faceNormalVector(a0(a2(*dcv)), FVertexDI);
00505 if (normal.dot(line) > 0.0) {
00506 dist = ref_plane.pointDistance(*VTX(a0(*dcv)));
00507 if (dist > best_dist) {
00508 d1 = *dcv;
00509 best_dist = dist;
00510 }
00511 }
00512 }
00513
00514 MSG("Recherche de la plus proche cellule du deuxième objet");
00515 CEdgeIntersection inter;
00516 inter = FTools->findNearestIntersectionInOrbit(*VTX(d1), line, d2,
00517 ORBIT_CC, FVertexDI);
00518 assert(inter.getCell());
00519 d2 = inter.getCell();
00520
00521 MSG("Recherche d'une arête de l'enveloppe convexe du deuxième objet");
00522 TOrbit cell_orbit = ORBIT_VERTEX;
00523 switch (inter.getCellDimension()) {
00524 case 1: cell_orbit = ORBIT_EDGE;
00525 case 2: cell_orbit = ORBIT_FACE;
00526 }
00527 ref_plane.setPlane(-line, *VTX(d2));
00528 best_dist = -FLT_MAX;
00529 FMap->halfMarkOrbit(d2, cell_orbit, mark);
00530 CCoverage *cov = FMap->getDynamicCoverage(d2, cell_orbit);
00531 for (; cov->cont(); ++(*cov))
00532 if (FMap->isMarked(**cov, mark)) {
00533 FMap->unsetMark(**cov, mark);
00534 normal = FTools->faceNormalVector(**cov, FVertexDI);
00535 if (!FMap->isFree2(**cov))
00536 normal += FTools->faceNormalVector(a0(a2(**cov)), FVertexDI);
00537 if (normal.dot(-line) > 0.0) {
00538 dist = ref_plane.pointDistance(*VTX(a0(**cov)));
00539 if (dist > best_dist) {
00540 d2 = **cov;
00541 best_dist = dist;
00542 }
00543 }
00544 }
00545 delete cov;
00546
00547 if ((*VTX(a0(d1)) - *VTX(d1)).dot(*VTX(a0(d2)) - *VTX(d2)) > 0.0)
00548 d2 = FTools->alpha2(a0(d2));
00549
00550 freeMark(mark);
00551
00552 CDart *square = FMap->createTopoSquare();
00553 FMap->topoSew3(square, FMap->createTopoSquare());
00554
00555
00556
00557 CDart *a2d1 = FTools->alpha2(d1);
00558 CDart *a2d2 = FTools->alpha2(d2);
00559
00560 if (!FMap->isFree2(d1)) FMap->unsew2(d1);
00561 if (!FMap->isFree2(d2)) FMap->unsew2(d2);
00562
00563 FMap->sew2(square, d1);
00564 FMap->sew2(a3(square), a2d1);
00565 square = a3(a1(a0(a1(a0(square)))));
00566 FMap->sew2(square, d2);
00567 FMap->sew2(a3(square), a2d2);
00568
00569 for (int m = 0; m < NB_MARKS; ++m)
00570 if (ACopyMarks[m]) {
00571 if (FMap->isMarked(d1, m)) FMap->markOrbit(a2(d1), ORBIT_01, m);
00572 if (FMap->isMarked(a2d1, m)) FMap->markOrbit(a2(a2d1), ORBIT_01, m);
00573 if (FMap->isMarked(d2, m)) FMap->markOrbit(a2(d2), ORBIT_01, m);
00574 if (FMap->isMarked(a2d2, m)) FMap->markOrbit(a2(a2d2), ORBIT_01, m);
00575 }
00576
00577 FMap->pointDirectInfoToAttributeVertex(FVertexDI, d1);
00578 FMap->pointDirectInfoToAttributeVertex(FVertexDI, a0(d1));
00579 FMap->pointDirectInfoToAttributeVertex(FVertexDI, d2);
00580 FMap->pointDirectInfoToAttributeVertex(FVertexDI, a0(d2));
00581 }
00582 }
00583
00584
00585
00586 void CCorefine3dFF::markIntersectionEdges(int AMark, int AObjectsToMark)
00587 {
00588 CDart *edge1, *edge2;
00589 for (list<CDart*>::iterator it = FInterEdges.begin();
00590 it != FInterEdges.end(); ) {
00591 edge1 = *it++;
00592 edge2 = *it++;
00593 if (AObjectsToMark & 1 && edge1 && !FMap->isMarked(edge1, AMark))
00594 FMap->markOrbit(edge1, ORBIT_EDGE, AMark);
00595 if (AObjectsToMark & 2 && edge2 && !FMap->isMarked(edge2, AMark))
00596 FMap->markOrbit(edge2, ORBIT_EDGE, AMark);
00597 }
00598 }
00599
00600
00601
00602 void CCorefine3dFF::markDoubleFaces(int AMark)
00603 {
00604 for (list<CDart*>::iterator it = FDoubleFaces.begin();
00605 it != FDoubleFaces.end(); ++it)
00606 if (!FMap->isMarked(*it, AMark))
00607 FMap->markOrbit(*it, ORBIT_FACE, AMark);
00608 }
00609
00610
00611
00612 void CCorefine3dFF::spreadMarksWithoutMerging(bitset<NB_MARKS> AMarks)
00613 {
00614 int face_plane_di = FMap->getNewDirectInfo();
00615 int negative_mark = FMap->getNewMark();
00616 CDart *edge1, *edge2;
00617 TFaceSet *face_set;
00618
00619 assignFacesPlaneInfo(face_plane_di, negative_mark, FMesh1);
00620 assignFacesPlaneInfo(face_plane_di, negative_mark, FMesh2);
00621
00622 for (list<CDart*>::iterator it = FInterEdges.begin();
00623 it != FInterEdges.end(); ) {
00624 edge1 = *it++;
00625 edge2 = *it++;
00626 if (edge1 && edge2) {
00627 face_set = sortFacesAroundEdges(edge1, edge2,
00628 face_plane_di, negative_mark);
00629 spreadMarksAroundEdges(face_set, AMarks);
00630 delete face_set;
00631 }
00632 }
00633
00634 removeFacesPlaneInfo(face_plane_di, negative_mark, FMesh1);
00635 removeFacesPlaneInfo(face_plane_di, negative_mark, FMesh2);
00636
00637 FMap->freeDirectInfo(face_plane_di);
00638 freeMark(negative_mark);
00639 }
00640
00641
00642
00643 void CCorefine3dFF::clear()
00644 {
00645 if (FMesh1) delete FMesh1;
00646 if (FMesh2) delete FMesh2;
00647 FInterEdges.clear();
00648 }
00649
00650
00651
00652 void CCorefine3dFF::splitMeshes(bitset<NB_MARKS> ACopyMarks)
00653 {
00654 CTime start, end;
00655
00656 FInterEdgeMark = FMap->getNewMark();
00657 FFaceMark = FMap->getNewMark();
00658 FDoubleFaceMark = FMap->getNewMark();
00659 FCopyMarks = ACopyMarks;
00660 FCopyMarks[FFaceMark] = true;
00661
00662 list<SFaceListIterators> inter_list;
00663 SFaceListIterators iters, next_iters;
00664 TCorefFaceList::iterator it1, it2;
00665 list<CDart*> face_list1, face_list2;
00666 bool found;
00667
00668 inter_list.push_back(SFaceListIterators(FMesh1->begin(), FMesh1->end(),
00669 FMesh2->begin(), FMesh2->end()));
00670
00671 if (FDisplayMessages) {
00672 cout << "Création des intersections..." << endl;
00673 if (FDisplayMessages > 2)
00674 cout << "+ intersection franche" << endl
00675 << "# faces coplanaires" << endl;
00676 }
00677 start.updateTime();
00678 while (!inter_list.empty()) {
00679 iters = inter_list.front();
00680 inter_list.pop_front();
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 for (it1 = iters.first1; it1 != iters.last1;) {
00710 found = false;
00711 for (it2 = iters.first2; it2 != iters.last2 && !found; ++it2) {
00712 if (it1->box * it2->box && intersectFaces(it1->face, it2->face,
00713 it1->plane, it2->plane,
00714 &face_list1, &face_list2)) {
00715 next_iters.first1 = it1;
00716 next_iters.last1 = it1; ++next_iters.last1;
00717 next_iters.first2 = it2; ++next_iters.first2;
00718 next_iters.last2 = iters.last2;
00719 if (face_list1.size() > 1) updateFaceInList(FMesh1, it1, &face_list1);
00720 if (face_list2.size() > 1) updateFaceInList(FMesh2, it2, &face_list2);
00721 if (next_iters.first2 != next_iters.last2)
00722 inter_list.push_back(next_iters);
00723 found = true;
00724 it1 = next_iters.last1;
00725 }
00726 }
00727 if (!found) ++it1;
00728 }
00729 }
00730 end.updateTime();
00731 FSplitTime = end - start;
00732 if (FDisplayMessages) {
00733 if (FDisplayMessages > 1) cout << endl;
00734 cout << "Durée de la création des intersections : "
00735 << FSplitTime << endl;
00736 }
00737
00738 FCopyMarks[FFaceMark] = false;
00739 freeMark(FFaceMark);
00740
00741 if (FDisplayMessages)
00742 cout << "Il y a eu " << FInterEdges.size() / 2
00743 << (FInterEdges.size() / 2 > 1 ? " arêtes" : " arête")
00744 << " d'intersection" << endl;
00745
00746 list<CDart*>::iterator it;
00747 for (it = FInterEdges.begin(); it != FInterEdges.end(); ++it)
00748 FMap->unmarkOrbit(*it, ORBIT_EDGE, FInterEdgeMark);
00749 freeMark(FInterEdgeMark);
00750
00751 for (it = FDoubleFaces.begin(); it != FDoubleFaces.end(); ++it)
00752 FMap->unmarkOrbit(*it, ORBIT_FACE, FDoubleFaceMark);
00753 freeMark(FDoubleFaceMark);
00754 }
00755
00756
00757
00758 bool CCorefine3dFF::checkEdges()
00759 {
00760 int mark = FMap->getNewMark();
00761 bool result = true;
00762
00763 for (CDynamicCoverageAll dca(FMap); dca.cont(); ++dca)
00764 if (!FMap->isMarked(*dca, mark)) {
00765 FMap->markOrbit(*dca, ORBIT_EDGE, mark);
00766 if (FTools->arePointsEqual(*VTX(*dca), *VTX(a0(*dca)))) {
00767 cout << "Arête de longueur nulle trouvée : [" << *VTX(*dca)
00768 << ", " << *VTX(a0(*dca)) << "]" << endl;
00769 result = false;
00770 }
00771 }
00772 FMap->negateMaskMark(mark);
00773 freeMark(mark);
00774
00775 return result;
00776 }
00777
00778
00779
00780 void CCorefine3dFF::pointDirectInfoToData(int ADirectInfo, CDart * ADart,
00781 TOrbit AOrbit, void * AData)
00782 {
00783 CCoverage *cov = FMap->getDynamicCoverage(ADart, AOrbit);
00784 for (; cov->cont(); ++(*cov))
00785 FMap->setDirectInfo(**cov, ADirectInfo, AData);
00786 delete cov;
00787 }
00788
00789
00790
00791 CBoundingBox CCorefine3dFF::initMesh(CDart * AMesh)
00792 {
00793 DEBUG_FUNCTION;
00794
00795 MSG("Fermeture des 3-bords");
00796 for (CStaticCoverageCC scc(FMap, AMesh); scc.cont(); ++scc)
00797 if (FMap->isFree3(*scc))
00798 FMap->stopUp(*scc, 3);
00799
00800 CBoundingBox box;
00801 int mark = FMap->getNewMark();
00802 CDynamicCoverageCC dcc(FMap, AMesh);
00803 CAttributeVertex *vtx;
00804
00805 MSG("Mise à jour des champs FVertexDI");
00806
00807 for (; dcc.cont(); ++dcc)
00808 if (!FMap->isMarked(*dcc, mark)) {
00809 vtx = FMap->findVertex(*dcc);
00810 assert(vtx != NULL);
00811 box.addPoint(*vtx);
00812 for (CDynamicCoverageVertex dcv(FMap, *dcc); dcv.cont(); ++dcv) {
00813 FMap->setMark(*dcv, mark);
00814 FMap->setDirectInfo(*dcv, FVertexDI, vtx);
00815 }
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827 MSG("Initialisation des champs FInterPointDI et FLinkedVertexDI");
00828 for (dcc.reinit(); dcc.cont(); ++dcc) {
00829 FMap->unsetMark(*dcc, mark);
00830 FMap->setDirectInfo(*dcc, FInterPointDI, NULL);
00831 FMap->setDirectInfo(*dcc, FLinkedVertexDI, NULL);
00832 }
00833
00834 freeMark(mark);
00835
00836 return box;
00837 }
00838
00839
00840
00841 CBoundingBox CCorefine3dFF::initFaces(int AMark)
00842 {
00843 DEBUG_FUNCTION;
00844
00845 CDynamicCoverageAll dca(FMap);
00846
00847 MSG("Fermeture des 3-bords");
00848 for (; dca.cont(); ++dca)
00849 if (FMap->isMarked(*dca, AMark) && FMap->isFree3(*dca))
00850 FMap->stopUp(*dca, 3);
00851
00852 CBoundingBox box;
00853 int mark = FMap->getNewMark();
00854 CAttributeVertex *vtx;
00855
00856 FMap->markCopy(AMark, mark);
00857 FMap->markIncidentCells(ORBIT_FACE, mark);
00858 FMap->markIncidentCells(ORBIT_VERTEX, mark);
00859 FMap->markIncidentCells(ORBIT_FACE, mark);
00860
00861 MSG("Mise à jour des champs FVertexDI, FInterPointDI et FLinkedVertexDI");
00862 for (dca.reinit(); dca.cont(); ++dca)
00863 if (FMap->isMarked(*dca, mark)) {
00864 vtx = FMap->findVertex(*dca);
00865 assert(vtx != NULL);
00866 box.addPoint(*vtx);
00867 for (CDynamicCoverageVertex dcv(FMap, *dca); dcv.cont(); ++dcv) {
00868 FMap->unsetMark(*dcv, mark);
00869 FMap->setDirectInfo(*dcv, FVertexDI, vtx);
00870 FMap->setDirectInfo(*dcv, FInterPointDI, NULL);
00871 FMap->setDirectInfo(*dcv, FLinkedVertexDI, NULL);
00872 }
00873 }
00874
00875 freeMark(mark);
00876
00877 return box;
00878 }
00879
00880
00881
00882 void CCorefine3dFF::cleanMesh(CDart * AMesh)
00883 {
00884 DEBUG_FUNCTION;
00885
00886 for (CDynamicCoverageCC dcc(FMap, AMesh); dcc.cont(); ++dcc) {
00887 FMap->unsetMark(*dcc, FFictiveVertexMark);
00888 FMap->unsetMark(*dcc, FFictiveEdgeMark);
00889 }
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 SCorefFace CCorefine3dFF::computeFaceInfos(CDart * AFace, int AMark)
00936 {
00937 SCorefFace infos;
00938 CVertex *vtx, pt, center, normal(0.0, 0.0, 0.0);
00939 int nb = 2;
00940 CDart *d;
00941
00942 infos.face = AFace;
00943
00944
00945
00946
00947
00948
00949 d = AFace; FMap->unsetMark(d, AMark);
00950 d = a0(d); FMap->unsetMark(d, AMark);
00951 d = a3(d); FMap->unsetMark(d, AMark);
00952 d = a0(d); FMap->unsetMark(d, AMark);
00953 d = a1(d); FMap->unsetMark(d, AMark);
00954 d = a3(d); FMap->unsetMark(d, AMark);
00955 d = a0(d); FMap->unsetMark(d, AMark);
00956 d = a3(d); FMap->unsetMark(d, AMark);
00957
00958 pt = *VTX(AFace);
00959 infos.box.addPoint(pt);
00960 infos.box.addPoint(*VTX(d));
00961 center = pt;
00962 center += *VTX(d);
00963
00964 for (CDynamicCoverage01 cov(FMap, AFace); cov.cont(); ++cov)
00965 if (FMap->isMarked(*cov, AMark)) {
00966 vtx = VTX(*cov);
00967 d = *cov; FMap->unsetMark(d, AMark);
00968 d = a3(d); FMap->unsetMark(d, AMark);
00969 d = a0(d); FMap->unsetMark(d, AMark);
00970 d = a3(d); FMap->unsetMark(d, AMark);
00971 normal += (*vtx - pt) * (*VTX(d) - pt);
00972 center += *vtx;
00973 infos.box.addPoint(*vtx);
00974 ++nb;
00975 }
00976
00977 infos.plane.setPlane(normal, center / nb);
00978
00979 return infos;
00980 }
00981
00982
00983
00984 TCorefFaceList * CCorefine3dFF::buildFaceList(CDart * AMesh)
00985 {
00986 DEBUG_FUNCTION;
00987
00988 TCorefFaceList *faces = new TCorefFaceList;
00989
00990 int mark = FMap->getNewMark();
00991 FMap->halfMarkOrbit(AMesh, ORBIT_CC, mark);
00992 for (CDynamicCoverageCC dcc(FMap, AMesh); dcc.cont(); ++dcc)
00993 if (FMap->isMarked(*dcc, mark))
00994 faces->push_back(computeFaceInfos(*dcc, mark));
00995 freeMark(mark);
00996
00997 return faces;
00998 }
00999
01000
01001
01002 TCorefFaceList * CCorefine3dFF::buildFaceList(int AMark)
01003 {
01004 DEBUG_FUNCTION;
01005
01006 TCorefFaceList *faces = new TCorefFaceList;
01007
01008 int mark = FMap->getNewMark();
01009 FMap->markCopy(AMark, mark);
01010 FMap->halfMarkIncidentCells(ORBIT_FACE, mark);
01011 for (CDynamicCoverageAll dca(FMap); dca.cont(); ++dca)
01012 if (FMap->isMarked(*dca, mark))
01013 faces->push_back(computeFaceInfos(*dca, mark));
01014 freeMark(mark);
01015
01016 return faces;
01017 }
01018
01019
01020
01021 void CCorefine3dFF::reduceFaceLists(TCorefFaceList * AList1,
01022 TCorefFaceList * AList2,
01023 const CBoundingBox & ABox)
01024 {
01025 CVertex size;
01026 TCoordinate max;
01027 long size_i, size_j, size_k;
01028 long nb_faces = (AList1->size() > AList2->size() ?
01029 AList1->size() : AList2->size());
01030
01031 if (nb_faces < 50) {
01032 if (FDisplayMessages)
01033 cout << "Nombre de faces trop faible => aucune réduction !" << endl;
01034 return;
01035 }
01036
01037
01038 size = ABox.getEpsMaxBound() - ABox.getEpsMinBound();
01039 max = (size.getX() > size.getY() ?
01040 (size.getX() > size.getZ() ? size.getX() : size.getZ()) :
01041 (size.getY() > size.getZ() ? size.getY() : size.getZ()));
01042 size /= max;
01043
01044
01045
01046
01047
01048
01049 size_i = (int)(size.getX() * FGridResolution + 0.5);
01050 size_j = (int)(size.getY() * FGridResolution + 0.5);
01051 size_k = (int)(size.getZ() * FGridResolution + 0.5);
01052 if (size_i <= 0) size_i = 1;
01053 if (size_j <= 0) size_j = 1;
01054 if (size_k <= 0) size_k = 1;
01055
01056 if (FDisplayMessages)
01057 cout << "Résolution de la grille = "
01058 << size_i << "x" << size_j << "x" << size_k << endl;
01059
01060 TCorefFaceGrid grid(size_i, size_j, size_k, ABox);
01061 TCorefFaceList::iterator it, tmp_it;
01062 list<CDart*>::iterator li;
01063 int mark = FMap->getNewMark();
01064 int nb;
01065
01066 for (it = AList1->begin(); it != AList1->end(); ++it)
01067 for (TCorefFaceGridIter gi(grid, it->box); gi.cont(); ++gi)
01068 gi->first.push_back(it->face);
01069 for (it = AList2->begin(); it != AList2->end(); ++it)
01070 for (TCorefFaceGridIter gi(grid, it->box); gi.cont(); ++gi)
01071 gi->second.push_back(it->face);
01072
01073 for (TCorefFaceGridIter gi(grid); gi.cont(); ++gi) {
01074 if (gi->first.size() > 0 && gi->second.size() > 0) {
01075 for (li = gi->first.begin(); li != gi->first.end(); ++li)
01076 FMap->setMark(*li, mark);
01077 for (li = gi->second.begin(); li != gi->second.end(); ++li)
01078 FMap->setMark(*li, mark);
01079 }
01080 }
01081
01082 nb = 0;
01083 for (it = AList1->begin(); it != AList1->end(); ) {
01084 tmp_it = it++;
01085 if (FMap->isMarked(tmp_it->face, mark))
01086 FMap->unsetMark(tmp_it->face, mark);
01087 else {
01088 ++nb;
01089 AList1->erase(tmp_it);
01090 }
01091 }
01092 if (FDisplayMessages)
01093 cout << nb << (nb == 1 ?
01094 " face a été supprimée" :
01095 " faces ont été supprimées")
01096 << " de la première liste" << endl;
01097
01098 nb = 0;
01099 for (it = AList2->begin(); it != AList2->end(); ) {
01100 tmp_it = it++;
01101 if (FMap->isMarked(tmp_it->face, mark))
01102 FMap->unsetMark(tmp_it->face, mark);
01103 else {
01104 ++nb;
01105 AList2->erase(tmp_it);
01106 }
01107 }
01108 if (FDisplayMessages)
01109 cout << nb << (nb == 1 ?
01110 " face a été supprimée" :
01111 " faces ont été supprimées")
01112 << " de la seconde liste" << endl;
01113
01114 freeMark(mark);
01115 }
01116
01117
01118
01119 void CCorefine3dFF::updateFaceInList(TCorefFaceList * AList,
01120 TCorefFaceList::iterator AElt,
01121 list<CDart*> * AFaces)
01122 {
01123 DEBUG_FUNCTION;
01124
01125 TCorefFaceList::iterator pos = AElt;
01126 list<CDart*>::iterator it = AFaces->begin();
01127
01128 MSG("La face à été éclatée en " << AFaces->size() << " faces");
01129
01130 *AElt = SCorefFace(*it, AElt->plane,
01131 FTools->orbitBoundingBox(*it, ORBIT_01, FVertexDI));
01132 ++pos; ++it;
01133
01134 for (; it != AFaces->end(); ++it)
01135 AList->insert(pos, SCorefFace(*it, AElt->plane,
01136 FTools->orbitBoundingBox(*it, ORBIT_01,
01137 FVertexDI)));
01138 }
01139
01140
01141
01142 bool CCorefine3dFF::isVertexLinkedWithFace(CDart * AVertex, int AFaceMark)
01143 {
01144 DEBUG_FUNCTION;
01145 if (LINK(AVertex) == NULL)
01146 return false;
01147
01148 bool result = false;
01149 for (CDynamicCoverageVertex dcv(FMap, LINK(AVertex));
01150 dcv.cont() && !result; ++dcv)
01151 if (FMap->isMarked(*dcv, AFaceMark))
01152 result = true;
01153
01154 return result;
01155 }
01156
01157
01158
01159 void CCorefine3dFF::markFaceVertex(CDart * AVertex, int AFaceMark, int AMark)
01160 {
01161 for (CDynamicCoverageVertex dcv(FMap, AVertex); dcv.cont(); ++dcv)
01162 if (FMap->isMarked(*dcv, AFaceMark))
01163 FMap->setMark(*dcv, AMark);
01164 }
01165
01166
01167
01168 CDart * CCorefine3dFF::getTwinDartOnFace(CDart * ADart, int AFaceMark)
01169 {
01170 CDart *d = NULL;
01171 for (CDynamicCoverage23 cov(FMap, ADart); cov.cont() && !d; ++cov)
01172 if (*cov != ADart && FMap->isMarked(*cov, AFaceMark)) d = *cov;
01173 return d;
01174 }
01175
01176
01177
01178 CDart * CCorefine3dFF::findFaceSector(CDart * AFaceVertex,
01179 const CPlane & AFacePlane,
01180 int AFaceMark, const CVertex & AVector)
01181 {
01182 DEBUG_FUNCTION;
01183
01184 int orient_mark = FMap->getNewMark();
01185 CDart *d = NULL;
01186 CVertex pt = *VTX(AFaceVertex);
01187
01188 MSG("AVector = " << AVector);
01189 MSG("sommet testé : " << pt);
01190
01191 FMap->halfMarkOrbit(AFaceVertex, ORBIT_VERTEX, orient_mark);
01192 for (CDynamicCoverageVertex dcv(FMap, AFaceVertex); dcv.cont(); ++dcv)
01193 if (FMap->isMarked(*dcv, orient_mark)) {
01194 FMap->unsetMark(*dcv, orient_mark);
01195 if (FMap->isMarked(*dcv, AFaceMark)) {
01196 if (a1(*dcv) == getTwinDartOnFace(*dcv, AFaceMark) ||
01197 FTools->isVectorInSector(AVector,
01198 *VTX(a0(*dcv)) - pt,
01199 *VTX(a0(a1(*dcv))) - pt,
01200 AFacePlane)) {
01201 assert(d == NULL);
01202 d = *dcv;
01203 MSG("secteur trouvé : " << *VTX(a0(*dcv))
01204 << ", " << *VTX(a0(a1(*dcv))));
01205 }
01206 }
01207 }
01208 freeMark(orient_mark);
01209
01210 return d;
01211 }
01212
01213
01214
01215 CDart * CCorefine3dFF::findNearestFaceVertex(CDart * AFace,
01216 const CPlane & ARefPlane,
01217 const CPlane & AClipPlane1,
01218 const CPlane & AClipPlane2)
01219 {
01220 CDart *d, *nearest = NULL;
01221 TCoordinate best_dist = 0, dist;
01222 CVertex pt;
01223
01224 d = AFace;
01225 do {
01226 pt = *VTX(d);
01227
01228 if (AClipPlane1.pointDistance(pt) >= -FEps &&
01229 AClipPlane2.pointDistance(pt) >= -FEps) {
01230 dist = abs(ARefPlane.pointDistance(pt));
01231 if (!nearest || dist < best_dist) {
01232 nearest = d;
01233 best_dist = dist;
01234 }
01235 }
01236
01237 d = a1(a0(d));
01238 }
01239 while (d != AFace);
01240
01241 return nearest;
01242 }
01243
01244
01245
01246 CVertex CCorefine3dFF::edgeInsideVector(CDart * AEdge,
01247 const CPlane & AFacePlane)
01248 {
01249 return AFacePlane.getNormal() * (*VTX(a0(AEdge)) - *VTX(AEdge));
01250 }
01251
01252
01253
01254 CVertex CCorefine3dFF::vertexInsideVector(CDart * AVertex,
01255 const CPlane & AFacePlane)
01256 {
01257 return (edgeInsideVector(AVertex, AFacePlane) +
01258 edgeInsideVector(a0(a1(AVertex)), AFacePlane)) / 2.0;
01259 }
01260
01261
01262
01263 void CCorefine3dFF::classifyFaceVertices(CDart * AFace, const CPlane & APlane,
01264 int APositiveMark, int ANegativeMark,
01265 int AFacesMark, bool AUseVerticesLinks,
01266 int * ANbVertices,
01267 int * ANbPositiveVertices,
01268 int * ANbNegativeVertices)
01269 {
01270 CDart *d = AFace;
01271 TCoordinate dist;
01272 int treated_mark = FMap->getNewMark();
01273 int nb = 0, nb_pos = 0, nb_neg = 0;
01274
01275 MSG("Classement des sommets de AFace par rapport à APlane");
01276 do {
01277 if (!FMap->isMarked(d, treated_mark)) {
01278 markFaceVertex(d, AFacesMark, treated_mark);
01279 ++nb;
01280 if (!AUseVerticesLinks || !isVertexLinkedWithFace(d, AFacesMark)) {
01281 dist = APlane.pointDistance(*VTX(d));
01282 if (dist < -FEps) {
01283 markFaceVertex(d, AFacesMark, ANegativeMark);
01284 ++nb_neg;
01285 }
01286 else if (dist > FEps) {
01287 markFaceVertex(d, AFacesMark, APositiveMark);
01288 ++nb_pos;
01289 }
01290 }
01291 }
01292
01293 d = a1(a0(d));
01294 }
01295 while (d != AFace);
01296
01297 MSG("Démarquage des brins de la face");
01298 do {
01299 FMap->unsetMark(d, treated_mark);
01300 d = a0(d);
01301 FMap->unsetMark(d, treated_mark);
01302 d = a1(d);
01303 }
01304 while (d != AFace);
01305
01306 freeMark(treated_mark);
01307
01308 MSG("La face comporte " << nb << " sommets dont :");
01309 MSG(" " << nb_pos << " du côté positif");
01310 MSG(" " << nb_neg << " du côté negatif");
01311
01312 if (ANbVertices) *ANbVertices = nb;
01313 if (ANbPositiveVertices) *ANbPositiveVertices = nb_pos;
01314 if (ANbNegativeVertices) *ANbNegativeVertices = nb_neg;
01315 }
01316
01317
01318
01319 void CCorefine3dFF::getFaceFictiveElements(CDart * AFace, int AFaceMark,
01320 std::list<CDart*> * AFictVertices,
01321 std::list<CDart*> * AFictEdges)
01322 {
01323 int fict_mark = FMap->getNewMark();
01324 CDart *d = AFace;
01325
01326
01327 do {
01328 if (!FMap->isMarked(d, fict_mark) &&
01329 !FMap->isMarked(d, FFictiveEdgeMark)) {
01330 markFaceVertex(d, AFaceMark, fict_mark);
01331 if (FMap->isMarked(d, FFictiveVertexMark)) {
01332 MSG("Récupération du sommet fictif " << *VTX(d));
01333 AFictVertices->push_back(d);
01334 }
01335 }
01336 d = a1(a0(d));
01337 }
01338 while (d != AFace);
01339
01340
01341 do {
01342 if (FMap->isMarked(d, fict_mark)) {
01343 FMap->unmarkOrbit(d, ORBIT_EDGE, fict_mark);
01344 if (FMap->isMarked(d, FFictiveEdgeMark))
01345 AFictEdges->push_back(d);
01346 }
01347 d = a1(a0(d));
01348 }
01349 while (d != AFace);
01350
01351 freeMark(fict_mark);
01352 }
01353
01354
01355
01356 void CCorefine3dFF::testPointInside(CDart * AVertex, TInterPt * APoint,
01357 int AFaceMark,
01358 const CVertex & AInterLine,
01359 const CPlane & AFacePlane)
01360 {
01361 MSG("sector = " << *VTX(a0(a1(AVertex))) << ","
01362 << *VTX(AVertex) << "," << *VTX(a0(AVertex)));
01363 if (APoint->getPosition() == FP_Outside &&
01364
01365
01366 (a1(AVertex) == getTwinDartOnFace(AVertex, AFaceMark) ||
01367 FTools->isVectorInSector(AInterLine,
01368 *VTX(a0(AVertex)) - *VTX(AVertex),
01369 *VTX(a0(a1(AVertex))) - *VTX(AVertex),
01370 AFacePlane))) {
01371 MSG("On entre dans la face");
01372 APoint->setPosition(FP_Inside);
01373 APoint->setEnteringSector(AVertex);
01374 }
01375 if (FTools->isVectorInSector(-AInterLine,
01376 *VTX(a0(AVertex)) - *VTX(AVertex),
01377 *VTX(a0(a1(AVertex))) - *VTX(AVertex),
01378 AFacePlane)) {
01379 MSG("On sort de la face");
01380 APoint->setLeavingSector(AVertex);
01381 }
01382 }
01383
01384
01385
01386 void CCorefine3dFF::testPointBorder(CDart * AVertex,
01387 TInterPt * ANewPoint, TInterPt * AOldPoint,
01388 const TInterPtCmp & AComparator)
01389 {
01390 if (AOldPoint) {
01391 MSG("Il y a une intersetion avec le bord");
01392 if (AComparator(AOldPoint, ANewPoint)) {
01393 MSG("AOldPoint < ANewPoint ==> OnBorder");
01394 AOldPoint->setPosition(FP_OnBorder);
01395 AOldPoint->setEnteringSector(a0(a1(AVertex)));
01396 if (!AOldPoint->getLeavingSector())
01397 AOldPoint->setLeavingSector(AOldPoint->getEnteringSector());
01398 }
01399 else {
01400 MSG("ANewPoint < AOldPoint ==> OnReversedBorder");
01401 ANewPoint->setPosition(FP_OnReversedBorder);
01402 ANewPoint->setEnteringSector(a0(a1(AVertex)));
01403 if (!ANewPoint->getLeavingSector())
01404 ANewPoint->setLeavingSector(AVertex);
01405 }
01406 }
01407 }
01408
01409
01410 #define GET_IP(d) ((TInterPt*)FMap->getDirectInfo(d, FInterPointDI))
01411
01412 TInterPtSet *
01413 CCorefine3dFF::findIntersectionPoints(CDart * AFace,
01414 const CPlane & AFacePlane,
01415 const CPlane & AInterPlane,
01416 const CVertex & AInterLine,
01417 int APositiveMark, int ANegativeMark,
01418 int AFacesMark,
01419 const TInterPtCmp & AComparator)
01420 {
01421 DEBUG_FUNCTION;
01422
01423 TInterPtSet *inter_set;
01424 TInterPt *inter_point, *old_point;
01425 CAttributeVertex *vtx1, *vtx2, pt;
01426 CVertex dir;
01427 TCoordinate t;
01428 CDart *d, *d2;
01429
01430 inter_set = new TInterPtSet(AComparator);
01431
01432 MSG("normale au plan : " << AFacePlane.getNormal());
01433
01434
01435
01436 inter_point = NULL;
01437 d = a0(a1(AFace));
01438 if (!FMap->isMarked(d, APositiveMark) && !FMap->isMarked(d, ANegativeMark)) {
01439 inter_point = new TInterPt(*VTX(d), 0);
01440 inter_point->setLeavingSector(d);
01441 pointDirectInfoToData(FInterPointDI, d, ORBIT_VERTEX, inter_point);
01442 MSG("première intersection avec le sommet " << inter_point->getPoint());
01443 inter_set->insert(inter_point);
01444 testPointInside(d, inter_point, AFacesMark, AInterLine, AFacePlane);
01445 }
01446
01447 MSG("Recherche des sommets de AFace se trouvant sur AInterPlane");
01448 d = AFace;
01449 do {
01450 old_point = inter_point;
01451 inter_point = GET_IP(d);
01452
01453
01454 if (inter_point) {
01455 MSG("intersection déjà existante avec un sommet");
01456 MSG(inter_point->getPoint());
01457 testPointInside(d, inter_point, AFacesMark, AInterLine, AFacePlane);
01458 testPointBorder(d, inter_point, old_point, AComparator);
01459 }
01460 else {
01461 if (!FMap->isMarked(d, APositiveMark) &&
01462 !FMap->isMarked(d, ANegativeMark)) {
01463 inter_point = new TInterPt(*VTX(d), 0);
01464 inter_point->setLeavingSector(d);
01465 pointDirectInfoToData(FInterPointDI, d, ORBIT_VERTEX, inter_point);
01466 MSG("nouvelle intersection avec un sommet");
01467 MSG(inter_point->getPoint());
01468 inter_set->insert(inter_point);
01469 testPointInside(d, inter_point, AFacesMark, AInterLine, AFacePlane);
01470 testPointBorder(d, inter_point, old_point, AComparator);
01471 }
01472 }
01473
01474 d = a1(a0(d));
01475 }
01476 while (d != AFace);
01477
01478 MSG("Recherche des arêtes de AFace intersectant AInterPlane");
01479 do {
01480
01481 if (GET_IP(d)) pointDirectInfoToData(FInterPointDI, d, ORBIT_VERTEX, NULL);
01482
01483 if ( (FMap->isMarked(d, APositiveMark) &&
01484 FMap->isMarked(a0(d), ANegativeMark)) ||
01485 (FMap->isMarked(d, ANegativeMark) &&
01486 FMap->isMarked(a0(d), APositiveMark))) {
01487 vtx1 = VTX(d);
01488 vtx2 = VTX(a0(d));
01489 dir = *vtx2 - *vtx1;
01490
01491 MSG("dir = " << dir);
01492
01493 if (AInterPlane.getLineIntersection(*vtx1, dir, &t)) {
01494 assert(t >= 0.0 && t <= 1.0);
01495
01496 pt = *vtx1 + t * dir;
01497 inter_point = new TInterPt(pt, 1);
01498 inter_set->insert(inter_point);
01499 MSG("intersection avec l'arête [" << *vtx1 << "," << *vtx2 << "] en "
01500 << pt);
01501
01502 if ((AFacePlane.getNormal() * dir).dot(AInterLine) > 0.0) {
01503 inter_point->setPosition(FP_Inside);
01504 inter_point->setEnteringSector(d);
01505 }
01506 else {
01507 inter_point->setPosition(FP_Outside);
01508 inter_point->setLeavingSector(d);
01509 }
01510
01511
01512 if (!FMap->isFree2(d) || !FMap->isFree2(a3(d))) {
01513 d2 = NULL;
01514 for (CDynamicCoverage23 cov(FMap, d); cov.cont() && !d2; ++cov)
01515 if (*cov != d && FMap->isMarked(*cov, AFacesMark)) d2 = *cov;
01516 if (d2) {
01517 d2 = a0(d2);
01518
01519 if (inter_point->getPosition() == FP_Outside) {
01520 inter_point->setPosition(FP_Inside);
01521 inter_point->setEnteringSector(d2);
01522 }
01523 else {
01524 inter_point->setLeavingSector(d2);
01525 }
01526 }
01527 }
01528
01529 MSG("pos = " << inter_point->getPosition());
01530 }
01531 }
01532
01533
01534 for (CDynamicCoverageEdge dce(FMap, d); dce.cont(); ++dce) {
01535 FMap->unsetMark(*dce, APositiveMark);
01536 FMap->unsetMark(*dce, ANegativeMark);
01537 }
01538
01539 d = a1(a0(d));
01540 }
01541 while (d != AFace);
01542
01543 return inter_set;
01544 }
01545
01546
01547
01548 CDart * CCorefine3dFF::createEdge()
01549 {
01550 CDart *d[8];
01551
01552 for (int i=0; i<8; ++i) {
01553 d[i] = FMap->addMapDart();
01554 FMap->setDirectInfo(d[i], FInterPointDI, NULL);
01555 FMap->setDirectInfo(d[i], FLinkedVertexDI, NULL);
01556 }
01557
01558 FMap->linkAlpha0(d[0], d[1]);
01559 FMap->linkAlpha0(d[2], d[3]);
01560 FMap->linkAlpha0(d[4], d[5]);
01561 FMap->linkAlpha0(d[6], d[7]);
01562
01563 FMap->linkAlpha2(d[0], d[2]);
01564 FMap->linkAlpha2(d[1], d[3]);
01565 FMap->linkAlpha2(d[4], d[6]);
01566 FMap->linkAlpha2(d[5], d[7]);
01567
01568 FMap->linkAlpha3(d[0], d[4]);
01569 FMap->linkAlpha3(d[1], d[5]);
01570 FMap->linkAlpha3(d[2], d[6]);
01571 FMap->linkAlpha3(d[3], d[7]);
01572
01573 return d[0];
01574 }
01575
01576
01577
01578 CDart * CCorefine3dFF::insertVertexInFace(CDart * AFace, const CVertex & APoint)
01579 {
01580 DEBUG_FUNCTION;
01581
01582 CDart *vertex = a1(a0(insertEdgeInFace(AFace, APoint)));
01583 FMap->markOrbit(vertex, ORBIT_EDGE, FFictiveEdgeMark);
01584
01585 return vertex;
01586 }
01587
01588
01589
01590 CDart * CCorefine3dFF::insertEdgeInFace(CDart * AVertex1,
01591 const CVertex & AVertex2)
01592 {
01593 DEBUG_FUNCTION;
01594
01595 CDart *link = LINK(AVertex1);
01596 CDart *edge = createEdge();
01597
01598 CDart *old_a1 = a1(AVertex1);
01599 FMap->unsew1(AVertex1);
01600 FMap->sew1(AVertex1, a2(edge));
01601 FMap->sew1(old_a1, edge);
01602 FMap->sew1(a0(edge), a0(a2(edge)));
01603
01604 if (FMap->isMarked(AVertex1, FFictiveVertexMark))
01605 FMap->markOrbit(edge, ORBIT_23, FFictiveVertexMark);
01606
01607 for (CDynamicCoverage23 dc(FMap, edge); dc.cont(); ++dc) {
01608 FMap->setDirectInfo(*dc, FLinkedVertexDI, link);
01609 for (int m = 0; m < NB_MARKS; m++)
01610 if (FCopyMarks[m] && FMap->isMarked(a1(*dc), m)) {
01611 FMap->setMark(*dc, m);
01612 FMap->setMark(a0(*dc), m);
01613 }
01614 }
01615 FMap->pointDirectInfoToAttributeVertex(FVertexDI, AVertex1);
01616
01617 CAttributeVertex *vtx = new CAttributeVertex(AVertex2);
01618 FMap->setVertex(a0(edge), vtx);
01619
01620 for (CDynamicCoverageVertex dcv(FMap, a0(edge)); dcv.cont(); ++dcv) {
01621 FMap->setDirectInfo(*dcv, FVertexDI, vtx);
01622 FMap->setDirectInfo(*dcv, FLinkedVertexDI, NULL);
01623 }
01624
01625 MSG("arête insérée : [" << *VTX(AVertex1) << ";" << AVertex2 << "]");
01626
01627 return edge;
01628 }
01629
01630
01631
01632 CDart * CCorefine3dFF::splitEdge(CDart * AEdge, const CVertex & APoint,
01633 list<CDart*> * AFictiveEdges)
01634 {
01635 DEBUG_FUNCTION;
01636
01637 FMap->CGMapGeneric::insertVertex(AEdge);
01638
01639 CDart *d = a1(a0(AEdge));
01640
01641 if (FMap->isMarked(AEdge, FFictiveEdgeMark)) {
01642 FMap->markOrbit(d, ORBIT_VERTEX, FFictiveEdgeMark);
01643
01644
01645 if (AFictiveEdges) {
01646 CDart *edge = a2(a3(AEdge));
01647 bool found = false;
01648 for (list<CDart*>::iterator it = AFictiveEdges->begin();
01649 it != AFictiveEdges->end() && !found; ++it)
01650 if (*it == AEdge || *it == edge)
01651 found = true;
01652 AFictiveEdges->push_back(found ? d : AEdge);
01653 }
01654 }
01655
01656 CAttributeVertex *vtx = new CAttributeVertex(APoint);
01657 FMap->setVertex(d, vtx);
01658
01659 for (CDynamicCoverageVertex dcv(FMap, d); dcv.cont(); ++dcv) {
01660 FMap->setDirectInfo(*dcv, FInterPointDI, NULL);
01661 FMap->setDirectInfo(*dcv, FLinkedVertexDI, NULL);
01662 FMap->setDirectInfo(*dcv, FVertexDI, vtx);
01663 for (int m = 0; m < NB_MARKS; m++)
01664 if (FCopyMarks[m] && FMap->isMarked(a0(*dcv), m))
01665 FMap->setMark(*dcv, m);
01666 }
01667
01668 MSG("sommet inséré : " << APoint);
01669
01670 return d;
01671 }
01672
01673
01674
01675 CDart * CCorefine3dFF::splitFace(CDart * AVertex1, CDart * AVertex2)
01676 {
01677 DEBUG_FUNCTION;
01678
01679 assert(AVertex1 != AVertex2);
01680
01681 CDart *edge = createEdge();
01682 CDart *link;
01683
01684 CDart *old_a1[2] = {a1(AVertex1), a1(AVertex2)};
01685 FMap->unsew1(AVertex1);
01686 FMap->sew1(AVertex1, a2(edge));
01687 FMap->sew1(old_a1[0], edge);
01688 FMap->unsew1(AVertex2);
01689 FMap->sew1(AVertex2, a0(edge));
01690 FMap->sew1(old_a1[1], a2(a0(edge)));
01691
01692 if (FMap->isMarked(AVertex1, FFictiveVertexMark))
01693 FMap->markOrbit(edge, ORBIT_23, FFictiveVertexMark);
01694 if (FMap->isMarked(AVertex2, FFictiveVertexMark))
01695 FMap->markOrbit(a0(edge), ORBIT_23, FFictiveVertexMark);
01696
01697 link = LINK(AVertex1);
01698 for (CDynamicCoverage23 dc1(FMap, edge); dc1.cont(); ++dc1) {
01699 FMap->setDirectInfo(*dc1, FLinkedVertexDI, link);
01700 for (int m = 0; m < NB_MARKS; m++)
01701 if (FCopyMarks[m] && FMap->isMarked(a1(*dc1), m))
01702 FMap->setMark(*dc1, m);
01703 }
01704 FMap->pointDirectInfoToAttributeVertex(FVertexDI, AVertex1);
01705
01706 link = LINK(AVertex2);
01707 for (CDynamicCoverage23 dc2(FMap, a0(edge)); dc2.cont(); ++dc2) {
01708 FMap->setDirectInfo(*dc2, FLinkedVertexDI, link);
01709 for (int m = 0; m < NB_MARKS; m++)
01710 if (FCopyMarks[m] && FMap->isMarked(a1(*dc2), m))
01711 FMap->setMark(*dc2, m);
01712 }
01713 FMap->pointDirectInfoToAttributeVertex(FVertexDI, AVertex2);
01714
01715 MSG("arête insérée : [" << *VTX(AVertex1) << ";" << *VTX(AVertex2) << "]");
01716
01717 return edge;
01718 }
01719
01720
01721
01722 bool CCorefine3dFF::isUselessFictiveVertex(CDart * AVertex)
01723 {
01724 bool result = true;
01725
01726 for (CDynamicCoverageVertex dcv(FMap, AVertex); dcv.cont() && result; ++dcv)
01727 if (FMap->isMarked(*dcv, FFictiveEdgeMark))
01728 result = false;
01729
01730 return result;
01731 }
01732
01733
01734
01735 bool CCorefine3dFF::isUselessFictiveEdge(CDart * AEdge)
01736 {
01737 return (a1(AEdge) == a2(AEdge) || a1(a0(AEdge)) == a2(a0(AEdge)) ||
01738 !FMap->isSameOrbit(AEdge, a2(AEdge), ORBIT_01));
01739 }
01740
01741
01742
01743 bool CCorefine3dFF::isWholeFaceMarked(CDart * AFace, int AMark)
01744 {
01745 bool result = true;
01746 for (CDynamicCoverageFace dcf(FMap, AFace); dcf.cont() && result; ++dcf)
01747 if (!FMap->isMarked(*dcf, AMark))
01748 result = false;
01749 return result;
01750 }
01751
01752
01753
01754 CDart * CCorefine3dFF::copyDoubleFaceData(CDart * AFace)
01755 {
01756 DEBUG_FUNCTION;
01757
01758 int edge_mark = FMap->getNewMark();
01759 CDart *d1, *d2, *other;
01760 int m;
01761
01762 MSG("Marquage des arêtes de la face");
01763 d1 = AFace;
01764 do {
01765 FMap->markOrbit(d1, ORBIT_EDGE, edge_mark);
01766 d1 = a1(a0(d1));
01767 }
01768 while (d1 != AFace);
01769
01770 MSG("Recherche de la face jumelle");
01771 if (isWholeFaceMarked(a2(AFace), edge_mark)) {
01772 other = a3(a2(AFace));
01773 }
01774 else {
01775 other = a2(a3(AFace));
01776 assert(isWholeFaceMarked(other, edge_mark));
01777 }
01778
01779
01780
01781
01782
01783
01784
01785 MSG("Copie des marques se trouvant sur la face à supprimer");
01786 d2 = other;
01787 do {
01788 FMap->unmarkOrbit(d1, ORBIT_EDGE, edge_mark);
01789 for (m = 0; m < NB_MARKS; ++m) {
01790 if (FCopyMarks[m] && FMap->isMarked(d1, m))
01791 FMap->setMark(d2, m);
01792 if (FCopyMarks[m] && FMap->isMarked(a3(d1), m))
01793 FMap->setMark(a3(d2), m);
01794 }
01795 d1 = a0(d1);
01796 d2 = a0(d2);
01797 for (m = 0; m < NB_MARKS; ++m) {
01798 if (FCopyMarks[m] && FMap->isMarked(d1, m))
01799 FMap->setMark(d2, m);
01800 if (FCopyMarks[m] && FMap->isMarked(a3(d1), m))
01801 FMap->setMark(a3(d2), m);
01802 }
01803 d1 = a1(d1);
01804 d2 = a1(d2);
01805 }
01806 while (d1 != AFace);
01807 assert(d2 == other);
01808
01809 freeMark(edge_mark);
01810
01811 return other;
01812 }
01813
01814
01815
01816 CDart * CCorefine3dFF::removeFictiveVertex(CDart * AVertex, int ADeleteMark)
01817 {
01818 DEBUG_FUNCTION;
01819
01820 assert(FMap->isMarked(AVertex, FFictiveVertexMark));
01821 assert(LINK(AVertex) == NULL);
01822
01823 CDart *d = a0(AVertex);
01824
01825 if (ADeleteMark < 0)
01826 FMap->merge(AVertex, a1(AVertex), 1, true);
01827 else {
01828 FMap->markOrbit(AVertex, ORBIT_VERTEX, ADeleteMark);
01829 FMap->merge(AVertex, a1(AVertex), 1, false);
01830 }
01831
01832 return d;
01833 }
01834
01835
01836
01837 CDart * CCorefine3dFF::removeFictiveEdge(CDart * AEdge, int ADeleteMark)
01838 {
01839 DEBUG_FUNCTION;
01840
01841 assert(FMap->isMarked(AEdge, FFictiveEdgeMark));
01842 assert(!FMap->isFree2(AEdge));
01843 assert(a3(a2(AEdge)) == a2(a3(AEdge)));
01844
01845 CDart *d1 = a1(AEdge);
01846 CDart *d2 = a1(a0(AEdge));
01847 CDart *l1, *l2;
01848
01849 if (a2(AEdge) == d1) d1 = NULL;
01850 if (a2(a0(AEdge)) == d2) d2 = NULL;
01851
01852 l2 = LINK(AEdge);
01853 if (l2) {
01854 l1 = LINK(l2);
01855 if (AEdge == l1 || a3(a2(AEdge)) == l1 ||
01856 a2(AEdge) == l1 || a3(AEdge) == l1) {
01857 MSG("Déplacement des liens sur le premier sommet");
01858 pointDirectInfoToData(FLinkedVertexDI, l2, ORBIT_VERTEX, a1(a3(AEdge)));
01859 }
01860 }
01861 l2 = LINK(a0(AEdge));
01862 if (l2) {
01863 l1 = LINK(l2);
01864 if (a2(a0(AEdge)) == l1 || a3(a0(AEdge)) == l1 ||
01865 a0(AEdge) == l1 || a3(a2(a0(AEdge))) == l1) {
01866 MSG("Déplacement des liens sur le second sommet");
01867 pointDirectInfoToData(FLinkedVertexDI, l2, ORBIT_VERTEX, a1(a0(AEdge)));
01868 }
01869 }
01870
01871 MSG("Démarquage des sommets de l'arête");
01872 if (FMap->isMarked(AEdge, FFictiveVertexMark))
01873 FMap->unmarkOrbit(AEdge, ORBIT_23, FFictiveVertexMark);
01874 if (FMap->isMarked(a0(AEdge), FFictiveVertexMark))
01875 FMap->unmarkOrbit(a0(AEdge), ORBIT_23, FFictiveVertexMark);
01876
01877 MSG("Suppression de l'arête");
01878 if (ADeleteMark < 0)
01879 FMap->merge(AEdge, a2(AEdge), 2, true);
01880 else {
01881 FMap->markOrbit(AEdge, ORBIT_EDGE, ADeleteMark);
01882 FMap->merge(AEdge, a2(AEdge), 2, false);
01883 }
01884
01885 MSG("Mise à jour des champs FVertexDI");
01886 if (d1) FMap->pointDirectInfoToAttributeVertex(FVertexDI, d1);
01887 if (d2) FMap->pointDirectInfoToAttributeVertex(FVertexDI, d2);
01888
01889 return d1;
01890 }
01891
01892
01893
01894 CDart * CCorefine3dFF::removeDoubleFace(CDart * AFace)
01895 {
01896 DEBUG_FUNCTION;
01897
01898 CDart *other = copyDoubleFaceData(AFace);
01899
01900 MSG("Suppression de la face en trop");
01901 FMap->merge(AFace, a3(AFace), 3, true);
01902
01903 MSG("Mise à jour des champs FVertexDI");
01904 CDart *d = other;
01905 do {
01906 FMap->pointDirectInfoToAttributeVertex(FVertexDI, d);
01907 d = a1(a0(d));
01908 }
01909 while (d != other);
01910
01911 return other;
01912 }
01913
01914
01915
01916 void CCorefine3dFF::linkVertices(CDart * AVertex1, CDart * AVertex2)
01917 {
01918 DEBUG_FUNCTION;
01919 MSG("AVertex1 = " << *VTX(AVertex1));
01920 MSG("AVertex2 = " << *VTX(AVertex2));
01921 assert(FTools->arePointsEqual(*VTX(AVertex1), *VTX(AVertex2)));
01922 for (CDynamicCoverageVertex dcv1(FMap, AVertex1); dcv1.cont(); ++dcv1)
01923 FMap->setDirectInfo(*dcv1, FLinkedVertexDI, AVertex2);
01924 for (CDynamicCoverageVertex dcv2(FMap, AVertex2); dcv2.cont(); ++dcv2)
01925 FMap->setDirectInfo(*dcv2, FLinkedVertexDI, AVertex1);
01926 }
01927
01928
01929
01930 void CCorefine3dFF::addIntersectionPoint(CDart *AVertices[2], int AFaceNumber,
01931 int AFacesMark, int AInterMark,
01932 std::list<CDart*> * AInterList)
01933 {
01934 MSG("Ajout du point d'intersection " << *VTX(AVertices[0]));
01935 if (FMap->isMarked(AVertices[0], FFictiveVertexMark))
01936 FMap->unmarkOrbit(AVertices[0], ORBIT_VERTEX, FFictiveVertexMark);
01937 if (FMap->isMarked(AVertices[1], FFictiveVertexMark))
01938 FMap->unmarkOrbit(AVertices[1], ORBIT_VERTEX, FFictiveVertexMark);
01939 linkVertices(AVertices[0], AVertices[1]);
01940 AInterList->push_back(AVertices[AFaceNumber]);
01941 markFaceVertex(AVertices[0], AFacesMark, AInterMark);
01942 markFaceVertex(AVertices[1], AFacesMark, AInterMark);
01943 }
01944
01945
01946
01947 bool CCorefine3dFF::intersectFaces(CDart * AFace1, CDart * AFace2,
01948 const CPlane & APlane1,
01949 const CPlane & APlane2,
01950 list<CDart*> * AFaceList1,
01951 list<CDart*> * AFaceList2)
01952 {
01953 DEBUG_FUNCTION;
01954
01955 list<CDart*> fict_vertices, fict_edges;
01956 list<CDart*>::iterator it, last_edge = FInterEdges.begin();
01957 int positive_mark = FMap->getNewMark();
01958 int negative_mark = FMap->getNewMark();
01959 int nb1, nb_pos1, nb_neg1, nb2, nb_pos2, nb_neg2;
01960 char inter_type = 0;
01961
01962 FMap->markOrbit(AFace1, ORBIT_01, FFaceMark);
01963 FMap->markOrbit(AFace2, ORBIT_01, FFaceMark);
01964
01965 #ifdef DEBUG_MESSAGES
01966 static int nb = 0;
01967 MSG("**** ETAPE N°" << nb << " ****");
01968 #ifdef SAVE_STEPS_SINCE
01969 #ifdef SAVE_STEPS_UNTIL
01970 if (nb >= SAVE_STEPS_SINCE && nb <= SAVE_STEPS_UNTIL) {
01971 #else
01972 if (nb >= SAVE_STEPS_SINCE) {
01973 #endif
01974 char file_name[256] = "\0";
01975 sprintf(file_name, "CCorefine3DFF_intersectFaces%04i.map", nb);
01976 FMap->markCopy(FFictiveEdgeMark, 0);
01977 FMap->markCopy(FInterEdgeMark, 1);
01978 FMap->markCopy(FFaceMark, 2);
01979 FMap->save(file_name, AsciiFormat);
01980 }
01981 #endif
01982 ++nb;
01983 #endif
01984
01985 classifyFaceVertices(AFace1, APlane2, positive_mark, negative_mark,
01986 FFaceMark, true, &nb1, &nb_pos1, &nb_neg1);
01987 classifyFaceVertices(AFace2, APlane1, positive_mark, negative_mark,
01988 FFaceMark, true, &nb2, &nb_pos2, &nb_neg2);
01989
01990 MSG("Récupération des sommets fictifs et des arêtes fictives sur les faces");
01991 getFaceFictiveElements(AFace1, FFaceMark, &fict_vertices, &fict_edges);
01992 getFaceFictiveElements(AFace2, FFaceMark, &fict_vertices, &fict_edges);
01993
01994 if ((nb_pos1 == 0 && nb_neg1 == 0) || (nb_pos2 == 0 && nb_neg2 == 0)) {
01995 inter_type = '#';
01996 if (nb_pos1 > 0) FMap->unmarkOrbit(AFace1, ORBIT_01, positive_mark);
01997 if (nb_neg1 > 0) FMap->unmarkOrbit(AFace1, ORBIT_01, negative_mark);
01998 if (nb_pos2 > 0) FMap->unmarkOrbit(AFace2, ORBIT_01, positive_mark);
01999 if (nb_neg2 > 0) FMap->unmarkOrbit(AFace2, ORBIT_01, negative_mark);
02000 intersectCoplanarFaces(AFace1, AFace2, APlane1, APlane2,
02001 positive_mark, negative_mark, FFaceMark,
02002 &fict_vertices, &fict_edges);
02003 }
02004 else if (nb_pos1 < nb1 && nb_neg1 < nb1 && nb_pos2 < nb2 && nb_neg2 < nb2) {
02005 inter_type = '+';
02006 intersectSecantFaces(AFace1, AFace2, APlane1, APlane2,
02007 positive_mark, negative_mark, FFaceMark,
02008 &fict_vertices, &fict_edges);
02009 }
02010 else {
02011 for (CDynamicCoverage01 cov1(FMap, AFace1); cov1.cont(); ++cov1) {
02012 FMap->unsetMark(*cov1, positive_mark);
02013 FMap->unsetMark(*cov1, negative_mark);
02014 }
02015 for (CDynamicCoverage01 cov2(FMap, AFace2); cov2.cont(); ++cov2) {
02016 FMap->unsetMark(*cov2, positive_mark);
02017 FMap->unsetMark(*cov2, negative_mark);
02018 }
02019 }
02020
02021 MSG("Suppression des arêtes fictives inutiles");
02022 for (it = fict_edges.begin(); it != fict_edges.end(); ++it)
02023 if (FMap->isMarked(*it, FFictiveEdgeMark) &&
02024 isUselessFictiveEdge(*it))
02025 removeFictiveEdge(*it);
02026
02027 MSG("Suppression des sommets fictifs inutiles");
02028 for (it = fict_vertices.begin(); it != fict_vertices.end(); ++it)
02029 if (FMap->isMarked(*it, FFictiveVertexMark) &&
02030 isUselessFictiveVertex(*it))
02031 removeFictiveVertex(*it);
02032
02033 MSG("Récupération des faces résultantes");
02034 assert(AFaceList1 != NULL);
02035 assert(AFaceList2 != NULL);
02036 AFaceList1->clear();
02037 AFaceList2->clear();
02038
02039 bool result = last_edge != FInterEdges.begin();
02040
02041 if (result) {
02042 if (FDisplayMessages > 1 && inter_type) {
02043 cout << inter_type;
02044 cout.flush();
02045 }
02046
02047 list<CDart*> *face_list[2] = {AFaceList1, AFaceList2};
02048 CDart *edge;
02049 int i;
02050
02051 for (it = FInterEdges.begin(); it != last_edge; ) {
02052 for (i = 0; i < 2; ++i) {
02053 edge = *it++;
02054 if (FMap->isMarked(edge, FFaceMark)) {
02055 FMap->unmarkOrbit(edge, ORBIT_01, FFaceMark);
02056 face_list[i]->push_back(edge);
02057 }
02058 if (FMap->isMarked(a2(edge), FFaceMark)) {
02059 FMap->unmarkOrbit(a2(edge), ORBIT_01, FFaceMark);
02060 face_list[i]->push_back(a0(a2(edge)));
02061 }
02062 }
02063 }
02064 }
02065 else {
02066 FMap->unmarkOrbit(AFace1, ORBIT_01, FFaceMark);
02067 FMap->unmarkOrbit(AFace2, ORBIT_01, FFaceMark);
02068 }
02069
02070 freeMark(positive_mark);
02071 freeMark(negative_mark);
02072
02073 return result;
02074 }
02075
02076
02077
02078 void CCorefine3dFF::intersectSecantFaces(CDart * AFace1, CDart * AFace2,
02079 const CPlane & APlane1,
02080 const CPlane & APlane2,
02081 int APositiveMark, int ANegativeMark,
02082 int AFacesMark,
02083 list<CDart*> * ,
02084 list<CDart*> * AFictiveEdges)
02085 {
02086 DEBUG_FUNCTION;
02087
02088
02089
02090 CPlane plane[2] = {APlane1, APlane2};
02091 CVertex line;
02092
02093 line = APlane1.getNormal() * APlane2.getNormal();
02094
02095 MSG("line = " << line);
02096
02097 assert(line.getX() != 0.0 || line.getY() != 0.0 || line.getZ() != 0.0);
02098
02099
02100
02101
02102
02103 TInterPtCmp comp(FTools, line);
02104 TInterPtSet *inter_set[2];
02105
02106 MSG("Recherche des intersections sur la première face");
02107 inter_set[0] = findIntersectionPoints(AFace1, APlane1, APlane2, line,
02108 APositiveMark, ANegativeMark,
02109 AFacesMark, comp);
02110
02111 MSG("Recherche des intersections sur la deuxième face");
02112 inter_set[1] = findIntersectionPoints(AFace2, APlane2, APlane1, line,
02113 APositiveMark, ANegativeMark,
02114 AFacesMark, comp);
02115
02116 TInterPtSet::iterator it[2] = {inter_set[0]->begin(), inter_set[1]->begin()};
02117 TInterPt *ip[2];
02118 TPositionInFace pos[2], prev_pos[2];
02119 int prev_point, next_point;
02120 CDart *vtx[2], *edge[2], *last_vertex[2];
02121 int mark = FMap->getNewMark();
02122 int i;
02123
02124 ip[0] = ip[1] = NULL;
02125 prev_pos[0] = prev_pos[1] = pos[0] = pos[1] = FP_Outside;
02126 prev_point = next_point = 0;
02127 last_vertex[0] = last_vertex[1] = NULL;
02128
02129
02130 while (it[0] != inter_set[0]->end() && it[1] != inter_set[1]->end()) {
02131
02132 if (FTools->arePointsEqual((*it[0])->getPoint(), (*it[1])->getPoint()))
02133 next_point = 3;
02134
02135 else if (comp(*it[0], *it[1]))
02136 next_point = 1;
02137
02138 else
02139 next_point = 2;
02140
02141 MSG("prev_point = " << prev_point);
02142 MSG("next_point = " << next_point);
02143 MSG("pos1 = " << pos[0]);
02144 MSG("pos2 = " << pos[1]);
02145
02146 if (pos[0] != FP_Outside && pos[1] != FP_Outside) {
02147 for (i = 0; i < 2; ++i) {
02148 BEGIN("Création d'une arête d'intersection sur la face " << i);
02149 MSG("prev dim = " << ip[i]->getCellDim());
02150 MSG("prev point = " << ip[i]->getPoint());
02151 MSG("next dim = " << (*it[i])->getCellDim());
02152 MSG("next point = " << (*it[i])->getPoint());
02153
02154
02155 if (pos[i] == FP_OnBorder || pos[i] == FP_OnReversedBorder) {
02156 MSG("test d'erreur numérique");
02157 CDart *d;
02158
02159
02160
02161 if (pos[i] == FP_OnBorder) {
02162 if (!(prev_point & (i+1)) && prev_pos[(i+1)%2] != FP_Outside) {
02163 assert(last_vertex[i] != NULL);
02164 vtx[0] = last_vertex[i];
02165 }
02166 else
02167 vtx[0] = ip[i]->getEnteringSector();
02168 d = a1(a0(vtx[0]));
02169 }
02170 else {
02171 d = ip[i]->getEnteringSector();
02172 vtx[0] = a1(a0(d));
02173 }
02174 vtx[1] = ((*it[i])->getPosition() == FP_Inside ?
02175 (*it[i])->getEnteringSector() :
02176 (*it[i])->getLeavingSector());
02177 markFaceVertex(vtx[1], AFacesMark, mark);
02178 MSG("vtx[0] = " << *VTX(vtx[0]));
02179 MSG("vtx[1] = " << *VTX(vtx[1]));
02180
02181 if (!FMap->isMarked(d, mark)) {
02182 cerr << "Erreur numérique détectée : " << pos[i] << " ==> ";
02183 CDart *d_on = NULL;
02184
02185 markFaceVertex(vtx[0], AFacesMark, mark);
02186 d = vtx[0];
02187 do {
02188 if (FMap->isMarked(d, mark) && FMap->isMarked(a0(d), mark))
02189 d_on = d;
02190 FMap->unsetMark(d, mark);
02191 d = a0(d);
02192 FMap->unsetMark(d, mark);
02193 d = a1(d);
02194 }
02195 while (d != vtx[0]);
02196 if (d_on) {
02197 ip[i]->setEnteringSector(d_on);
02198 if ((*VTX(a0(d_on)) - *VTX(d_on)).dot(line) > 0.0)
02199 ip[i]->setPosition(FP_OnBorder);
02200 else
02201 ip[i]->setPosition(FP_OnReversedBorder);
02202 }
02203 else {
02204
02205 CDart *d_in = findFaceSector(vtx[0], plane[i], AFacesMark, line);
02206 ip[i]->setEnteringSector(d_in);
02207 ip[i]->setPosition(d_in ? FP_Inside : FP_Outside);
02208 }
02209 pos[i] = ip[i]->getPosition();
02210 cerr << pos[i] << endl;
02211 }
02212 else {
02213 FMap->unmarkOrbit(vtx[0], ORBIT_VERTEX, mark);
02214 FMap->unmarkOrbit(vtx[1], ORBIT_VERTEX, mark);
02215 }
02216 }
02217
02218
02219 if (pos[i] == FP_OnBorder) {
02220 vtx[0] = ip[i]->getEnteringSector();
02221 if (!(prev_point & (i+1))) {
02222 if (prev_pos[(i+1)%2] != FP_Outside) {
02223 assert(last_vertex[i] != NULL);
02224 vtx[0] = last_vertex[i];
02225 }
02226 else {
02227 vtx[0] = splitEdge(vtx[0], ip[(i+1)%2]->getPoint(),
02228 AFictiveEdges);
02229 ip[i]->setEnteringSector(vtx[0]);
02230 }
02231 }
02232 if (!(next_point & (i+1)))
02233 splitEdge(vtx[0], (*it[(i+1)%2])->getPoint(), AFictiveEdges);
02234 edge[i] = vtx[0];
02235 last_vertex[i] = vtx[1] = a1(a0(edge[i]));
02236 }
02237
02238 else if (pos[i] == FP_OnReversedBorder) {
02239 last_vertex[i] = ip[i]->getEnteringSector();
02240 if (!(prev_point & (i+1))) {
02241 if (prev_pos[(i+1)%2] == FP_Outside)
02242 splitEdge(last_vertex[i], ip[(i+1)%2]->getPoint(), AFictiveEdges);
02243 }
02244 if (!(next_point & (i+1)))
02245 last_vertex[i] = splitEdge(last_vertex[i],
02246 (*it[(i+1)%2])->getPoint(),
02247 AFictiveEdges);
02248 vtx[0] = edge[i] = last_vertex[i];
02249 vtx[1] = a1(a0(edge[i]));
02250 }
02251
02252 else {
02253
02254 if (prev_point & (i+1)) {
02255 MSG("Le premier sommet se trouve sur la face courante");
02256 if (ip[i]->getCellDim() == 0)
02257 vtx[0] = ip[i]->getEnteringSector();
02258 else
02259 vtx[0] = splitEdge(ip[i]->getEnteringSector(),
02260 ip[i]->getPoint(), AFictiveEdges);
02261 MSG("sommet trouvé : " << *VTX(vtx[0]));
02262 }
02263 else {
02264 MSG("Le premier sommet se trouve sur l'autre face");
02265 if (prev_pos[(i+1)%2] != FP_Outside) {
02266 assert(last_vertex[i] != NULL);
02267 vtx[0] = last_vertex[i];
02268 }
02269 else if (!(next_point & (i+1))) {
02270 if (!last_vertex[i]) {
02271 if (ip[i]->getCellDim() == 1) {
02272
02273
02274
02275
02276 vtx[0] = ip[i]->getEnteringSector();
02277 CPlane clip_plane1(edgeInsideVector(vtx[0], plane[i]),
02278 ip[i]->getPoint());
02279 CPlane clip_plane2(-line, ip[(i+1)%2]->getPoint());
02280 vtx[0] = findNearestFaceVertex(vtx[0], plane[(i+1)%2],
02281 clip_plane1, clip_plane2);
02282 vtx[0] = findFaceSector(vtx[0], plane[i], AFacesMark,
02283 ip[(i+1)%2]->getPoint() -
02284 *VTX(vtx[0]));
02285 assert(vtx[0]);
02286 }
02287 else
02288 vtx[0] = ip[i]->getEnteringSector();
02289 }
02290 else
02291 vtx[0] = last_vertex[i];
02292 vtx[0] = insertVertexInFace(vtx[0], ip[(i+1)%2]->getPoint());
02293 AFictiveEdges->push_back(vtx[0]);
02294 }
02295 else
02296 vtx[0] = NULL;
02297 }
02298
02299
02300 if (next_point & (i+1)) {
02301 MSG("Le second sommet se trouve sur la face courante");
02302 MSG("next_point = " << (*it[i])->getPoint());
02303 if ((*it[i])->getCellDim() == 0)
02304 vtx[1] = ((*it[i])->getLeavingSector() ?
02305 (*it[i])->getLeavingSector() :
02306 (*it[i])->getEnteringSector());
02307 else
02308 vtx[1] = splitEdge((*it[i])->getLeavingSector(),
02309 (*it[i])->getPoint(), AFictiveEdges);
02310
02311 if (vtx[0])
02312 edge[i] = splitFace(vtx[0], vtx[1]);
02313 else {
02314 edge[i] = a2(a0(insertEdgeInFace(vtx[1],
02315 ip[(i+1)%2]->getPoint())));
02316 vtx[0] = edge[i];
02317 }
02318
02319 if ((*it[i])->getPosition() == FP_Inside) {
02320 if ((*it[i])->getCellDim() == 1) {
02321 (*it[i])->setCellDim(0);
02322 (*it[i])->setEnteringSector(a1(a0((*it[i])->getEnteringSector())));
02323 }
02324 else if (((*VTX(a0((*it[i])->getEnteringSector())) -
02325 *VTX((*it[i])->getEnteringSector()))
02326 * line).dot(plane[i].getNormal()) < 0.0)
02327 (*it[i])->setEnteringSector(a2(a0(edge[i])));
02328 }
02329 last_vertex[i] = NULL;
02330 }
02331 else {
02332 MSG("Le second sommet se trouve sur l'autre face");
02333 edge[i] = insertEdgeInFace(vtx[0], (*it[(i+1)%2])->getPoint());
02334 vtx[1] = last_vertex[i] = a1(a0(edge[i]));
02335 }
02336 }
02337 if (FMap->isMarked(vtx[0], FFictiveVertexMark))
02338 FMap->unmarkOrbit(vtx[0], ORBIT_VERTEX, FFictiveVertexMark);
02339 if (FMap->isMarked(vtx[1], FFictiveVertexMark))
02340 FMap->unmarkOrbit(vtx[1], ORBIT_VERTEX, FFictiveVertexMark);
02341 MSG("arête d'intersection trouvée : [" << *VTX(edge[i]) << ";"
02342 << *VTX(a0(edge[i])) << "]");
02343
02344 END("");
02345 }
02346
02347 if (!FMap->isMarked(edge[0], FInterEdgeMark) &&
02348 !FMap->isMarked(edge[1], FInterEdgeMark)) {
02349 MSG("Marquage et stockage des arêtes d'intersection");
02350 FInterEdges.push_front(edge[1]);
02351 FInterEdges.push_front(edge[0]);
02352
02353
02354 FMap->markOrbit(edge[0], ORBIT_EDGE, FInterEdgeMark);
02355
02356
02357
02358 FMap->markOrbit(edge[1], ORBIT_EDGE, FInterEdgeMark);
02359
02360
02361
02362 if (FMap->isMarked(edge[0], FFictiveEdgeMark))
02363 FMap->unmarkOrbit(edge[0], ORBIT_EDGE, FFictiveEdgeMark);
02364 if (FMap->isMarked(edge[1], FFictiveEdgeMark))
02365 FMap->unmarkOrbit(edge[1], ORBIT_EDGE, FFictiveEdgeMark);
02366
02367 if (pos[0] == FP_OnReversedBorder) edge[0] = a0(edge[0]);
02368 if (pos[1] == FP_OnReversedBorder) edge[1] = a0(edge[1]);
02369 linkVertices(edge[0], edge[1]);
02370 linkVertices(a1(a0(edge[0])), a1(a0(edge[1])));
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382 }
02383 else if (FMap->isMarked(edge[0], FInterEdgeMark) !=
02384 FMap->isMarked(edge[1], FInterEdgeMark)) {
02385 cerr << "Intersection incohérante ignorée !" << endl;
02386 }
02387 }
02388
02389
02390 for (i = 0; i < 2; ++i) {
02391 if (next_point & (i+1)) {
02392 ip[i] = *it[i]++;
02393 prev_pos[i] = pos[i];
02394 pos[i] = ip[i]->getPosition();
02395 last_vertex[i] = NULL;
02396 }
02397 }
02398 prev_point = next_point;
02399 }
02400
02401 freeMark(mark);
02402
02403 MSG("Destruction des ensembles de points d'intersection");
02404 for (i = 0; i < 2; ++i) {
02405 for (it[i] = inter_set[i]->begin(); it[i] != inter_set[i]->end(); ++it[i])
02406 delete *it[i];
02407 delete inter_set[i];
02408 }
02409 }
02410
02411
02412
02413 void CCorefine3dFF::intersectCoplanarFaces(CDart * AFace1, CDart * AFace2,
02414 const CPlane & APlane1,
02415 const CPlane & APlane2,
02416 int APositiveMark, int ANegativeMark,
02417 int AFacesMark,
02418 list<CDart*> * ,
02419 list<CDart*> * AFictiveEdges)
02420 {
02421 DEBUG_FUNCTION;
02422
02423 CDart *d, *face[2], *vtx[2], *edge[2];
02424 CPlane plane[2], edge_plane;
02425 CVertex edge_vector, pt1, pt2;
02426 int i, j, nb, nb_pos, nb_neg;
02427 int inter_mark = FMap->getNewMark();
02428 list<CDart*> inter_points;
02429 bool local_inside, inside;
02430
02431
02432 face[0] = AFace1; plane[0] = APlane1;
02433 face[1] = AFace2; plane[1] = APlane2;
02434 for (i = 0; i < 2 && inter_points.empty(); ++i) {
02435 MSG("Recherche des points d'intersection entre les arêtes de la face "
02436 << i << " et les arêtes de la face " << (i+1)%2);
02437 inside = true;
02438 d = face[i];
02439 do {
02440 vtx[0] = d;
02441 d = a1(a0(d));
02442
02443 pt1 = *VTX(vtx[0]);
02444 pt2 = *VTX(a0(vtx[0]));
02445 edge_vector = pt2 - pt1;
02446 edge_plane.setPlane(plane[i].getNormal() * edge_vector, pt1);
02447 local_inside = false;
02448
02449 MSG("arête testée : [" << pt1 << " ; " << pt2 << "]");
02450
02451 classifyFaceVertices(face[(i+1)%2], edge_plane,
02452 APositiveMark, ANegativeMark, AFacesMark,
02453 false, &nb, &nb_pos, &nb_neg);
02454 if (nb_pos == nb)
02455 FMap->unmarkOrbit(face[(i+1)%2], ORBIT_01, APositiveMark);
02456 else if (nb_neg == nb)
02457 FMap->unmarkOrbit(face[(i+1)%2], ORBIT_01, ANegativeMark);
02458 else {
02459 TInterPtCmp comp(FTools, edge_vector);
02460 TInterPtSet *inter_set[2];
02461 TInterPtSet::iterator it[2];
02462 TInterPt *ip[2];
02463 TPositionInFace pos[2];
02464 int prev_point, next_point;
02465
02466 inter_set[0] = new TInterPtSet(comp);
02467 ip[0] = new TInterPt(pt1, 0, FP_OnBorder);
02468 ip[0]->setEnteringSector(vtx[0]);
02469 ip[0]->setLeavingSector(vtx[0]);
02470 inter_set[0]->insert(ip[0]);
02471 ip[0] = new TInterPt(pt2, 0, FP_Outside);
02472 ip[0]->setLeavingSector(d);
02473 inter_set[0]->insert(ip[0]);
02474
02475 inter_set[1] = findIntersectionPoints(face[(i+1)%2], plane[(i+1)%2],
02476 edge_plane, edge_vector,
02477 APositiveMark, ANegativeMark,
02478 AFacesMark, comp);
02479
02480 it[0] = inter_set[0]->begin();
02481 it[1] = inter_set[1]->begin();
02482 ip[0] = ip[1] = NULL;
02483 pos[0] = pos[1] = FP_Outside;
02484 prev_point = next_point = 0;
02485
02486
02487 while (it[0] != inter_set[0]->end() && it[1] != inter_set[1]->end()) {
02488
02489 if (FTools->arePointsEqual((*it[0])->getPoint(),
02490 (*it[1])->getPoint()))
02491 next_point = 3;
02492
02493 else if (comp(*it[0], *it[1]))
02494 next_point = 1;
02495
02496 else
02497 next_point = 2;
02498
02499 MSG("prev_point = " << prev_point);
02500 MSG("next_point = " << next_point);
02501 MSG("pos[0] = " << pos[0]);
02502 MSG("pos[1] = " << pos[1]);
02503
02504
02505 if (pos[0] != FP_Outside) {
02506
02507 if (local_inside && (prev_point != 1 || next_point != 1))
02508 local_inside = false;
02509
02510
02511
02512 if (prev_point & 1 && pos[1] != FP_Outside) {
02513 if (pos[1] == FP_Inside ||
02514 edgeInsideVector(vtx[0], plane[i])
02515 .dot(edgeInsideVector(ip[1]->getEnteringSector(),
02516 plane[(i+1)%2])) > 0.0) {
02517 MSG("Le premier sommet est à l'intérieur");
02518 FMap->setMark(vtx[0], FDoubleFaceMark);
02519 }
02520 }
02521
02522 if (pos[1] == FP_OnBorder || pos[1] == FP_OnReversedBorder) {
02523 if (prev_point == 1) {
02524 vtx[1] = splitEdge(ip[1]->getEnteringSector(), pt1,
02525 AFictiveEdges);
02526 if (pos[1] == FP_OnBorder)
02527 ip[1]->setEnteringSector(vtx[1]);
02528 }
02529 else
02530 vtx[1] = ip[1]->getLeavingSector();
02531 if (prev_point & 1 && !FMap->isMarked(vtx[0], inter_mark))
02532 addIntersectionPoint(vtx, i, AFacesMark, inter_mark,
02533 &inter_points);
02534
02535 edge[0] = vtx[0];
02536
02537 if (next_point == 1) {
02538 vtx[0] = a1(a0(vtx[0]));
02539 vtx[1] = splitEdge(ip[1]->getEnteringSector(), pt2,
02540 AFictiveEdges);
02541 if (pos[1] == FP_OnReversedBorder)
02542 ip[1]->setEnteringSector(vtx[1]);
02543 }
02544 else {
02545 if (next_point == 2) {
02546 vtx[0] = splitEdge(vtx[0], (*it[1])->getPoint(),
02547 AFictiveEdges);
02548 }
02549 else if (next_point == 3) {
02550 vtx[0] = a1(a0(vtx[0]));
02551 }
02552 vtx[1] = ((*it[1])->getPosition() == FP_Inside ?
02553 (*it[1])->getEnteringSector() :
02554 (*it[1])->getLeavingSector());
02555 }
02556
02557 edge[1] = ip[1]->getEnteringSector();
02558
02559 if (!FMap->isMarked(vtx[0], inter_mark))
02560 addIntersectionPoint(vtx, i, AFacesMark, inter_mark,
02561 &inter_points);
02562
02563 MSG("edge[0] = [" << *VTX(edge[0]) << ";"
02564 << *VTX(a0(edge[0])) << "]");
02565 MSG("edge[1] = [" << *VTX(edge[1]) << ";"
02566 << *VTX(a0(edge[1])) << "]");
02567
02568 if (!FMap->isMarked(edge[0], FInterEdgeMark) ||
02569 !FMap->isMarked(edge[1], FInterEdgeMark)) {
02570 MSG("Une arête d'intersection avec un bord trouvée");
02571 FInterEdges.push_front(edge[(i+1)%2]);
02572 FInterEdges.push_front(edge[i]);
02573
02574 if (!FMap->isMarked(edge[0], FInterEdgeMark))
02575 FMap->markOrbit(edge[0], ORBIT_EDGE, FInterEdgeMark);
02576 else
02577 cerr << "topologie de l'objet " << (i+2)%2
02578 << " incorrecte !" << endl;
02579 if (!FMap->isMarked(edge[1], FInterEdgeMark))
02580 FMap->markOrbit(edge[1], ORBIT_EDGE, FInterEdgeMark);
02581 else
02582 cerr << "topologie de l'objet " << i+1
02583 << " incorrecte !" << endl;
02584
02585 if (FMap->isMarked(edge[0], FFictiveEdgeMark))
02586 FMap->unmarkOrbit(edge[0], ORBIT_EDGE, FFictiveEdgeMark);
02587 if (FMap->isMarked(edge[1], FFictiveEdgeMark))
02588 FMap->unmarkOrbit(edge[1], ORBIT_EDGE, FFictiveEdgeMark);
02589 }
02590 else {
02591 assert(FMap->isMarked(edge[1], FInterEdgeMark));
02592 }
02593 }
02594 else {
02595 if (prev_point == 3 && ip[1]->getCellDim() == 1) {
02596 vtx[1] = splitEdge(pos[1] == FP_Outside ?
02597 ip[1]->getLeavingSector() :
02598 ip[1]->getEnteringSector(), pt1,
02599 AFictiveEdges);
02600 if (!FMap->isMarked(vtx[0], inter_mark))
02601 addIntersectionPoint(vtx, i, AFacesMark, inter_mark,
02602 &inter_points);
02603 }
02604
02605 if (next_point != 1) {
02606 if (next_point == 2) {
02607 vtx[0] = splitEdge(vtx[0], (*it[1])->getPoint(),
02608 AFictiveEdges);
02609 vtx[1] = ((*it[1])->getPosition() == FP_Inside ?
02610 (*it[1])->getEnteringSector() :
02611 (*it[1])->getLeavingSector());
02612 if ((*it[1])->getCellDim() == 1)
02613 vtx[1] = splitEdge(vtx[1], (*it[1])->getPoint(),
02614 AFictiveEdges);
02615 }
02616 else {
02617 vtx[0] = a1(a0(vtx[0]));
02618 vtx[1] = ((*it[1])->getPosition() == FP_Inside ?
02619 (*it[1])->getEnteringSector() :
02620 (*it[1])->getLeavingSector());
02621 if ((*it[1])->getCellDim() == 1)
02622 vtx[1] = splitEdge(vtx[1], pt2, AFictiveEdges);
02623 }
02624 if (!FMap->isMarked(vtx[0], inter_mark))
02625 addIntersectionPoint(vtx, i, AFacesMark, inter_mark,
02626 &inter_points);
02627 }
02628 }
02629
02630
02631
02632 if (next_point == 2 && (*it[1])->getPosition() != FP_Outside) {
02633 if ((*it[1])->getPosition() == FP_Inside ||
02634 edgeInsideVector(vtx[0], plane[i])
02635 .dot(edgeInsideVector((*it[1])->getEnteringSector(),
02636 plane[(i+1)%2])) > 0.0) {
02637 MSG("Le nouveau sommet est à l'intérieur");
02638 FMap->setMark(vtx[0], FDoubleFaceMark);
02639 }
02640 }
02641 }
02642
02643 else if (!ip[0]) {
02644 local_inside = (pos[1] == FP_Inside);
02645
02646
02647 }
02648
02649
02650 for (j = 0; j < 2; ++j) {
02651 if (next_point & (j+1)) {
02652 ip[j] = *it[j]++;
02653 pos[j] = ip[j]->getPosition();
02654 }
02655 }
02656 prev_point = next_point;
02657 }
02658
02659 for (j = 0; j < 2; ++j) {
02660 for (it[j] = inter_set[j]->begin(); it[j] != inter_set[j]->end();
02661 ++it[j]) delete *it[j];
02662 delete inter_set[j];
02663 }
02664 }
02665 MSG("local_inside = " << local_inside);
02666 if (!local_inside) inside = false;
02667 }
02668 while (d != face[i]);
02669
02670 MSG(inter_points.size() << " points d'intersection trouvés");
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685 if (inside) {
02686 MSG("La première face se trouve à l'intérieur de l'autre");
02687 assert(inter_points.empty());
02688
02689 TCoordinate dist, best_dist = 0;
02690 CPlane ref_plane(vertexInsideVector(d, plane[i]), *VTX(d));
02691
02692 MSG("Recherche d'un sommet de l'enveloppe convexe de la face");
02693 vtx[0] = d;
02694 d = a1(a0(d));
02695 do {
02696 dist = ref_plane.pointDistance(*VTX(d));
02697 if (dist < best_dist) {
02698 best_dist = dist;
02699 vtx[0] = d;
02700 }
02701 d = a1(a0(d));
02702 }
02703 while (d != face[i]);
02704
02705 edge_vector = -vertexInsideVector(vtx[0], plane[i]);
02706 edge_plane.setPlane(plane[i].getNormal() * edge_vector, *VTX(vtx[0]));
02707
02708 MSG("Calcul des points d'intersection entre un vecteur et l'autre face");
02709 TInterPtCmp comp(FTools, edge_vector);
02710 TInterPtSet *inter_set;
02711 TInterPtSet::iterator it;
02712 inter_set = findIntersectionPoints(face[(i+1)%2], plane[(i+1)%2],
02713 edge_plane, edge_vector,
02714 APositiveMark, ANegativeMark,
02715 AFacesMark, comp);
02716
02717 MSG("Recherche du point d'intersection le plus proche du sommet");
02718 it = inter_set->begin();
02719 while (it != inter_set->end() &&
02720 (*VTX(vtx[0]) - (*it)->getPoint()).dot(edge_vector) > 0.0) ++it;
02721
02722 MSG("Recherche d'un sommet de l'autre face pour insérer une arête");
02723 vtx[1] = ((*it)->getPosition() == FP_Inside ?
02724 (*it)->getEnteringSector() : (*it)->getLeavingSector());
02725 if ((*it)->getCellDim() == 1) {
02726 CPlane clip_plane1(edgeInsideVector(vtx[1], plane[(i+1)%2]),
02727 (*it)->getPoint());
02728 CPlane clip_plane2(edge_vector, *VTX(vtx[0]));
02729 vtx[1] = findNearestFaceVertex(vtx[1], edge_plane,
02730 clip_plane1, clip_plane2);
02731 assert(vtx[1]);
02732 }
02733 MSG("Insertion de l'arête");
02734 vtx[1] = insertVertexInFace(vtx[1], *VTX(vtx[0]));
02735 AFictiveEdges->push_back(vtx[1]);
02736 addIntersectionPoint(vtx, i, AFacesMark, inter_mark, &inter_points);
02737 }
02738 }
02739
02740 MSG("Création des arêtes d'intersection");
02741 int orient_mark = FMap->getNewMark();
02742 list<CDart*>::iterator it;
02743
02744 for (it = inter_points.begin(); it != inter_points.end(); ++it) {
02745 CDart *d1, *d2;
02746
02747 vtx[0] = *it;
02748 vtx[1] = LINK(*it);
02749
02750 for (i = 0; i < 2; ++i) {
02751 MSG("Parcours des arêtes de la face " << i+1 << " autour du sommet "
02752 << *VTX(vtx[i]));
02753 FMap->halfMarkOrbit(vtx[i], ORBIT_VERTEX, orient_mark);
02754 for (CDynamicCoverageVertex dcv(FMap, vtx[i]); dcv.cont(); ++dcv)
02755 if (FMap->isMarked(*dcv, orient_mark)) {
02756 FMap->unsetMark(*dcv, orient_mark);
02757 if (FMap->isMarked(*dcv, inter_mark)) {
02758 FMap->unsetMark(*dcv, inter_mark);
02759 d = *dcv;
02760 do {
02761 if (!FMap->isMarked(d, FInterEdgeMark)) {
02762 MSG("L'arête courante n'est pas une arête d'intersection");
02763 assert(LINK(d));
02764 edge_vector = *VTX(a0(d)) - *VTX(d);
02765 d1 = findFaceSector(LINK(d), plane[(i+1)%2],
02766 AFacesMark, edge_vector);
02767 if (d1) {
02768 MSG("L'arête est à l'intérieur de l'autre face");
02769 d2 = LINK(a0(d));
02770 if (d2) {
02771 d2 = findFaceSector(d2, plane[(i+1)%2],
02772 AFacesMark, -edge_vector);
02773 assert(d2);
02774 d1 = splitFace(d1, d2);
02775 }
02776 else
02777 d1 = insertEdgeInFace(d1, *VTX(a0(d)));
02778 linkVertices(a1(a0(d)), a1(a0(d1)));
02779 if (FMap->isMarked(d, FFictiveEdgeMark))
02780 FMap->unmarkOrbit(d, ORBIT_EDGE, FFictiveEdgeMark);
02781 FMap->markOrbit(d, ORBIT_EDGE, FInterEdgeMark);
02782 FMap->markOrbit(d1, ORBIT_EDGE, FInterEdgeMark);
02783 if (i == 0) {
02784 FInterEdges.push_front(d1);
02785 FInterEdges.push_front(d);
02786 }
02787 else {
02788 FInterEdges.push_front(d);
02789 FInterEdges.push_front(d1);
02790 }
02791 }
02792 else
02793 FMap->setMark(a0(d), inter_mark);
02794 }
02795 d = a1(a0(d));
02796 }
02797 while (!FMap->isMarked(a1(d), inter_mark));
02798 FMap->unsetMark(a1(d), inter_mark);
02799 }
02800 }
02801 }
02802 }
02803 for (it = inter_points.begin(); it != inter_points.end(); ++it) {
02804 vtx[0] = *it;
02805 vtx[1] = LINK(*it);
02806 for (i = 0; i < 2; ++i)
02807 for (CDynamicCoverageVertex dcv(FMap, vtx[i]); dcv.cont(); ++dcv) {
02808 FMap->unsetMark(*dcv, inter_mark);
02809 if (FMap->isMarked(*dcv, FDoubleFaceMark) &&
02810 !FMap->isMarked(a1(*dcv), FDoubleFaceMark)) {
02811 FMap->markOrbit(*dcv, ORBIT_FACE, FDoubleFaceMark);
02812 FDoubleFaces.push_back(*dcv);
02813 }
02814 }
02815 }
02816
02817 freeMark(inter_mark);
02818 freeMark(orient_mark);
02819 }
02820
02821
02822
02823 void CCorefine3dFF::assignFacesPlaneInfo(int ADirectInfo, int ANegativeMark,
02824 TCorefFaceList * AList)
02825 {
02826 DEBUG_FUNCTION;
02827
02828 for (TCorefFaceList::iterator it = AList->begin(); it != AList->end(); ++it)
02829 for (CDynamicCoverage01 cov(FMap, it->face); cov.cont(); ++cov) {
02830 FMap->setDirectInfo(*cov, ADirectInfo, &it->plane);
02831 FMap->setDirectInfo(a3(*cov), ADirectInfo, &it->plane);
02832 FMap->setMark(a3(*cov), ANegativeMark);
02833 }
02834 }
02835
02836
02837
02838 void CCorefine3dFF::removeFacesPlaneInfo(int , int ANegativeMark,
02839 TCorefFaceList * AList)
02840 {
02841 DEBUG_FUNCTION;
02842
02843 for (TCorefFaceList::iterator it = AList->begin(); it != AList->end(); ++it)
02844 for (CDynamicCoverage01 cov(FMap, a3(it->face)); cov.cont(); ++cov)
02845 FMap->unsetMark(*cov, ANegativeMark);
02846 }
02847
02848
02849
02850 void CCorefine3dFF::sortFacesAroundEdges(int AFacePlaneDI, int ANegativeMark)
02851 {
02852 DEBUG_FUNCTION;
02853
02854 list<CDart*>::iterator it;
02855 TFaceSet *face_set;
02856 CDart *edge1, *edge2;
02857
02858 for (it = FInterEdges.begin(); it != FInterEdges.end();) {
02859 edge1 = *it++;
02860 edge2 = *it++;
02861 if (edge1 && edge2) {
02862 face_set = sortFacesAroundEdges(edge1, edge2,
02863 AFacePlaneDI, ANegativeMark);
02864 linkSortedFaces(face_set);
02865 delete face_set;
02866 }
02867 }
02868 }
02869
02870
02871 #define VECT(d) (FMap->isMarked(d, ANegativeMark) ?\
02872 -((CPlane*)FMap->getDirectInfo(d, AFacePlaneDI))->getNormal():\
02873 ((CPlane*)FMap->getDirectInfo(d, AFacePlaneDI))->getNormal())
02874
02875 TFaceSet * CCorefine3dFF::sortFacesAroundEdges(CDart * AEdge1, CDart * AEdge2,
02876 int AFacePlaneDI,
02877 int ANegativeMark)
02878 {
02879 DEBUG_FUNCTION;
02880
02881 CDart *d1, *d2;
02882 CVertex axis = *VTX(a0(AEdge1)) - *VTX(AEdge1);
02883 CAngularFaceComparator comp(FMap, FTools, axis, VECT(AEdge1),
02884 FVertexDI, AFacePlaneDI, ANegativeMark);
02885 TFaceSet *faces = new TFaceSet(comp);
02886
02887
02888 d1 = AEdge1;
02889 do {
02890 faces->insert(d1);
02891 d1 = a3(FTools->alpha2(d1));
02892 }
02893 while (d1 != AEdge1);
02894
02895
02896 if ((*VTX(a0(AEdge2)) - *VTX(AEdge2)).dot(axis) < 0.0)
02897 AEdge2 = a3(a0(AEdge2));
02898 d2 = AEdge2;
02899 do {
02900 faces->insert(d2);
02901 d2 = a3(FTools->alpha2(d2));
02902 }
02903 while (d2 != AEdge2);
02904
02905 return faces;
02906 }
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005 #undef VECT
03006
03007
03008 void CCorefine3dFF::linkSortedFaces(TFaceSet * AFaceSet)
03009 {
03010 DEBUG_FUNCTION;
03011
03012 CDart *d1, *d2;
03013 TFaceSet::iterator it;
03014
03015 for (it = AFaceSet->begin(); it != AFaceSet->end(); ) {
03016 d1 = *it++;
03017 d2 = (it != AFaceSet->end()) ? *it : *AFaceSet->begin();
03018
03019 if (a2(d1) != a3(d2)) {
03020 if (!FMap->isFree2(d1)) FMap->unsew2(d1);
03021 if (!FMap->isFree2(a3(d2))) FMap->unsew2(a3(d2));
03022 FMap->sew2(d1, a3(d2));
03023 FMap->pointDirectInfoToAttributeVertex(FVertexDI, d1);
03024 FMap->pointDirectInfoToAttributeVertex(FVertexDI, a0(d1));
03025 }
03026 }
03027 }
03028
03029
03030
03031 void CCorefine3dFF::spreadMarksAroundEdges(TFaceSet * AFaceSet,
03032 bitset<NB_MARKS> AMarks)
03033 {
03034 DEBUG_FUNCTION;
03035
03036 CDart *d1, *d2;
03037 TFaceSet::iterator it;
03038 int m;
03039
03040 for (it = AFaceSet->begin(); it != AFaceSet->end(); ) {
03041 d1 = *it++;
03042 d2 = (it != AFaceSet->end()) ? *it : *AFaceSet->begin();
03043
03044 for (m = 0; m < NB_MARKS; ++m)
03045 if (AMarks[m] && a2(d1) != a3(d2)) {
03046 if (FMap->isMarked(d1, m)) FMap->setMark(a3(d2), m);
03047 else if (FMap->isMarked(a3(d2), m)) FMap->setMark(d1, m);
03048 if (FMap->isMarked(a0(d1), m)) FMap->setMark(a0(a3(d2)), m);
03049 else if (FMap->isMarked(a0(a3(d2)), m)) FMap->setMark(a0(d1), m);
03050 }
03051 }
03052 }
03053
03054
03055
03056 bool CCorefine3dFF::isPointInFace(const CVertex & APoint, CDart * AFace,
03057 const CPlane & APlane)
03058 {
03059 CVertex line = *VTX(AFace) - APoint;
03060
03061 if (FTools->isVectorNull(line))
03062 return true;
03063
03064 TInterPtCmp comp(FTools, line);
03065 CPlane plane(APlane.getNormal() * line, *VTX(AFace));
03066 int face_mark = FMap->getNewMark();
03067 int positive_mark = FMap->getNewMark();
03068 int negative_mark = FMap->getNewMark();
03069 TInterPtSet *inter_set;
03070
03071 FMap->markOrbit(AFace, ORBIT_01, face_mark);
03072 classifyFaceVertices(AFace, plane, positive_mark, negative_mark,
03073 face_mark, false);
03074 inter_set = findIntersectionPoints(AFace, APlane, plane, line,
03075 positive_mark, negative_mark,
03076 face_mark, comp);
03077 assert(!inter_set->empty());
03078
03079 TInterPtSet::iterator it;
03080 TPositionInFace pos = FP_Outside;
03081 for (it = inter_set->begin(); it != inter_set->end(); ++it) {
03082 if (FTools->arePointsEqual((*it)->getPoint(), APoint)) {
03083 pos = FP_Inside;
03084 break;
03085 }
03086 else if ((APoint - (*it)->getPoint()).dot(line) > 0.0)
03087 pos = (*it)->getPosition();
03088 else
03089 break;
03090 }
03091
03092 for (it = inter_set->begin(); it != inter_set->end(); ++it)
03093 delete *it;
03094 delete inter_set;
03095
03096 return pos == FP_Inside;
03097 }
03098
03099