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 "corefine-2d-propagation.hh"
00025 #include "time.hh"
00026
00027
00028 #include "message-macros.hh"
00029
00030 #include INCLUDE_NON_INLINE("corefine-2d-propagation.icc")
00031
00032 using namespace std;
00033 using namespace GMap3d;
00034
00035
00036
00037 #define INFO_MESSAGES
00038
00039 #ifdef INFO_MESSAGES
00040 #define INFO(s) (cout << s << endl)
00041 #else // INFO_MESSAGES
00042 #define INFO(s)
00043 #endif // INFO_MESSAGES
00044
00045
00046
00047 #define a0 FMap->alpha0
00048 #define a1 FMap->alpha1
00049 #define a2 FMap->alpha2
00050 #define a3 FMap->alpha3
00051
00052 #define b1(d) ((CDart*)FMap->getDirectInfo(d, FAlpha1DI))
00053
00054
00055
00056 CCorefine2dPropagation::CCorefine2dPropagation(CGMapVertex * AMap,
00057 const CPlane & APlane,
00058 bool ACalculateOrientation,
00059 TCoordinate AEpsilon,
00060 int AVertexDI)
00061 : CCorefine(AMap, AEpsilon), FPlane(APlane), FTools(AMap, AEpsilon),
00062 FCalculateOrientation(ACalculateOrientation), FNumberOfIntersections(0)
00063 {
00064 ENTER;
00065
00066 FBestProj = FPlane.getBestProjection();
00067
00068 if (AVertexDI < 0) {
00069 FVertexDI = FMap->getNewDirectInfo();
00070 MSG("FVertexDI = FMap->getNewDirectInfo() = " << FVertexDI);
00071 FLocalVertexDirectInfo = true;
00072 }
00073 else {
00074 FVertexDI = AVertexDI;
00075 FLocalVertexDirectInfo = false;
00076 }
00077
00078 FAlpha1DI = FMap->getNewDirectInfo();
00079 MSG("FAlpha1DI = FMap->getNewDirectInfo() = " << FAlpha1DI);
00080
00081 EXIT;
00082 }
00083
00084
00085
00086 CCorefine2dPropagation::~CCorefine2dPropagation()
00087 {
00088 ENTER;
00089
00090 if (FLocalVertexDirectInfo) {
00091 MSG("FMap->freeDirectInfo(FVertexDI = " << FVertexDI << ")");
00092 FMap->freeDirectInfo(FVertexDI);
00093 }
00094
00095 MSG("FMap->freeDirectInfo(FAlpha1DI = " << FAlpha1DI << ")");
00096 FMap->freeDirectInfo(FAlpha1DI);
00097
00098 EXIT;
00099 }
00100
00101
00102
00103 int CCorefine2dPropagation::corefine(CDart *& AMesh1, CDart *& AMesh2,
00104 bitset<NB_MARKS> ACopyMarks)
00105 {
00106 TCoordinate t;
00107 list<CDart*> vertex_list;
00108 CEdgeIntersection inter;
00109 CDart *vertex, *edge, *face, *tmp_edge, *tmp_face;
00110 int edge_mark = FMap->getNewMark();
00111 int vertex_mark = FMap->getNewMark();
00112 CVertex *pt1, *pt2, tmp_pt;
00113 CTime start, end;
00114
00115 FCopyMarks = ACopyMarks;
00116
00117 ENTER;
00118
00119 INFO("Initialisation des maillages");
00120 start.updateTime();
00121
00122 initMesh(AMesh1);
00123 initMesh(AMesh2);
00124
00125 end.updateTime();
00126 FInitialisationTime = end - start;
00127 INFO("Durée de l'initialisation : " << FInitialisationTime);
00128
00129 INFO("Orientation des maillages");
00130 start.updateTime();
00131
00132 if (FCalculateOrientation) {
00133 AMesh1 = FTools.findWellOrientedDart(AMesh1, FVertexDI);
00134 AMesh2 = FTools.findWellOrientedDart(AMesh2, FVertexDI);
00135 }
00136
00137 vertex = AMesh1;
00138 face = AMesh2;
00139
00140 end.updateTime();
00141 FOrientationTime = end - start;
00142 INFO("Durée de l'orientation : " << FOrientationTime);
00143
00144
00145
00146
00147
00148
00149 INFO("Localisation de la première face");
00150 start.updateTime();
00151
00152
00153
00154 face = FTools.localizePointInMesh(*getVertex(vertex), face, FVertexDI);
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 end.updateTime();
00165 FLocalizationTime = end - start;
00166 INFO("Durée de la localisation : " << FLocalizationTime);
00167
00168 pt1 = getVertex(face);
00169 pt2 = getVertex(a0(face));
00170 tmp_pt = *getVertex(vertex);
00171
00172
00173 switch(FTools.localizePointOnEdge(tmp_pt, *pt1, *pt2, &t)) {
00174 case EP_OnEdge:
00175 face = splitEdge(face, tmp_pt);
00176 weldVertices(vertex, face);
00177 FMap->markOrbit(vertex, ORBIT_VERTEX, vertex_mark);
00178 break;
00179
00180 case EP_OnSecondVertex:
00181 face = a2(a0(face));
00182 case EP_OnFirstVertex:
00183 modifyVertex(face, tmp_pt);
00184 weldVertices(vertex, face);
00185 FMap->markOrbit(vertex, ORBIT_VERTEX, vertex_mark);
00186 break;
00187
00188 default:
00189 break;
00190 }
00191
00192 INFO("Parcours des maillages et création des intersections");
00193 start.updateTime();
00194
00195
00196 vertex_list.push_back(vertex);
00197 vertex_list.push_back(face);
00198
00199
00200 while(!vertex_list.empty()) {
00201
00202
00203 vertex = vertex_list.front(), vertex_list.pop_front();
00204 face = vertex_list.front(), vertex_list.pop_front();
00205
00206 edge = vertex;
00207
00208 MSG("Parcours du sommet : " << *getVertex(vertex));
00209
00210
00211 do {
00212 if (!FMap->isMarked(edge, edge_mark)) {
00213
00214 pt1 = getVertex(edge);
00215 pt2 = getVertex(a0(edge));
00216
00217 #ifdef DEBUG_MESSAGES
00218 cout << "Parcours de l'arête : ";
00219 FTools.displayEdgeVertices(edge, FVertexDI);
00220 #endif // DEBUG_MESSAGES
00221
00222
00223
00224
00225
00226 if (FMap->isMarked(edge, vertex_mark)) {
00227
00228
00229
00230
00231
00232 tmp_face = a2(edge);
00233 while (b1(tmp_face) == NULL)
00234 tmp_face = a2(a1(tmp_face));
00235 tmp_face = b1(tmp_face);
00236
00237 inter = FTools.findNearestIntersection(*pt1, *pt2, tmp_face, true,
00238 FVertexDI);
00239 }
00240 else {
00241 tmp_face = face;
00242
00243 inter = FTools.findNearestIntersection(*pt1, *pt2, tmp_face, false,
00244 FVertexDI);
00245 }
00246
00247 #ifdef DEBUG_MESSAGES
00248 cout << "Recherche d'une intersection dans la face :" << endl;
00249 FTools.displayFaceVertices(tmp_face, FVertexDI);
00250 #endif
00251
00252 if (inter.getCell() != NULL &&
00253 (inter.getPosition() != EP_OnSecondVertex ||
00254 !FMap->isMarked(a2(a0(edge)), vertex_mark))) {
00255 #ifdef DEBUG_MESSAGES
00256 cout << "Une intersection trouvée dans la face avec l'arête :\n";
00257 FTools.displayEdgeVertices(inter.getCell(), FVertexDI);
00258 cout << "Première arête : ";
00259 #endif
00260
00261 if (inter.getPosition() == EP_OnEdge) {
00262 MSG("Intersection franche");
00263 tmp_edge = splitEdge(edge, inter.getPoint());
00264 tmp_pt = inter.getPoint();
00265 }
00266 else if (inter.getPosition() == EP_OnFirstVertex) {
00267 cout << "\033[0;31m"
00268 << "Intersection avec le sommet d'origine de l'arête "
00269 << *pt1 << " et ";
00270 if (inter.getCellDimension() == 0)
00271 cout << "le sommet " << *getVertex(inter.getCell());
00272 else
00273 cout << "l'arête [" << *getVertex(inter.getCell())
00274 << "," << *getVertex(a0(inter.getCell())) << "]";
00275 cout << "\033[0m\n";
00276
00277 tmp_edge = edge;
00278 tmp_pt = *pt1;
00279 }
00280 else {
00281 MSG("Intersection avec le sommet extrémité de l'arête");
00282 tmp_edge = a2(a0(edge));
00283 tmp_pt = *pt2;
00284 }
00285
00286 MSG("Deuxième arête : ");
00287
00288 if (inter.getCellDimension() == 1) {
00289 MSG("Intersection franche");
00290 tmp_face = splitEdge(inter.getCell(), tmp_pt);
00291 }
00292 else {
00293 MSG("Intersection avec un sommet");
00294 tmp_face = inter.getCell();
00295 modifyVertex(inter.getCell(), tmp_pt);
00296 }
00297
00298 if (inter.getPosition() != EP_OnFirstVertex ||
00299 !FMap->isMarked(edge, vertex_mark)) {
00300 weldVertices(tmp_edge, tmp_face);
00301 }
00302 else {
00303 cout << "\033[1;31m"
00304 << "Interclassement de plus de deux sommets " << *pt1
00305 << "\033[0m\n";
00306
00307
00308
00309
00310
00311
00312
00313 }
00314
00315 FMap->markOrbit(tmp_edge, ORBIT_VERTEX, vertex_mark);
00316 }
00317 else {
00318 tmp_edge = a2(a0(edge));
00319 }
00320
00321 vertex_list.push_back(tmp_edge);
00322 vertex_list.push_back(tmp_face);
00323
00324 FMap->markOrbit(edge, ORBIT_EDGE, edge_mark);
00325 }
00326
00327
00328 edge = a2(a1(edge));
00329 }
00330 while (edge != vertex);
00331 }
00332
00333 FMap->unmarkOrbit(AMesh1, ORBIT_CC, edge_mark);
00334 FMap->unmarkOrbit(AMesh1, ORBIT_CC, vertex_mark);
00335
00336 FMap->freeMark(edge_mark);
00337 FMap->freeMark(vertex_mark);
00338
00339 end.updateTime();
00340 FPropagationTime = end - start;
00341 INFO("Durée de la recherche des intersections : " << FPropagationTime);
00342
00343 if (FNumberOfIntersections != 0) {
00344 INFO("Assemblage final des maillages");
00345 start.updateTime();
00346 applyModifications(AMesh1);
00347 end.updateTime();
00348 FAssemblyTime = end - start;
00349 }
00350 else {
00351 INFO("Aucune intersection entre les maillages "
00352 << "==> insertion d'une arête fictive");
00353 start.updateTime();
00354 tmp_face = FTools.localizePointInMesh(*getVertex(face), AMesh1, FVertexDI);
00355 FMap->insertEdge(tmp_face, a1(face));
00356 end.updateTime();
00357 FAssemblyTime = end - start;
00358 }
00359 INFO("Durée de l'assemblage : " << FAssemblyTime);
00360
00361 INFO("Nettoyage des maillages");
00362 start.updateTime();
00363
00364 cleanMesh(AMesh1);
00365
00366 if (FNumberOfIntersections == 0)
00367 cleanMesh(AMesh2);
00368
00369 end.updateTime();
00370 FCleaningTime = end - start;
00371 INFO("Durée du nettoyage : " << FCleaningTime);
00372
00373 if (FNumberOfIntersections != 0) {
00374 INFO("Suppression des arêtes doubles");
00375 start.updateTime();
00376
00377 FTools.removeDoubleEdges(AMesh1, AMesh2, FCopyMarks);
00378
00379 end.updateTime();
00380 FDoubleEdgesCleaningTime = end - start;
00381 INFO("Durée de la suppression : " << FDoubleEdgesCleaningTime);
00382
00383 INFO("Nombre d'intersections réalisées : "
00384 << FNumberOfIntersections);
00385 }
00386 else FDoubleEdgesCleaningTime.setTime(0, 0);
00387
00388 EXIT;
00389
00390 return FNumberOfIntersections;
00391 }
00392
00393
00394
00395 const CTime & CCorefine2dPropagation::getInitialisationTime() const
00396 {
00397 return FInitialisationTime;
00398 }
00399
00400
00401
00402 const CTime & CCorefine2dPropagation::getOrientationTime() const
00403 {
00404 return FOrientationTime;
00405 }
00406
00407
00408
00409 const CTime & CCorefine2dPropagation::getLocalizationTime() const
00410 {
00411 return FLocalizationTime;
00412 }
00413
00414
00415
00416 const CTime & CCorefine2dPropagation::getPropagationTime() const
00417 {
00418 return FPropagationTime;
00419 }
00420
00421
00422
00423 const CTime & CCorefine2dPropagation::getAssemblyTime() const
00424 {
00425 return FAssemblyTime;
00426 }
00427
00428
00429
00430 const CTime & CCorefine2dPropagation::getCleaningTime() const
00431 {
00432 return FCleaningTime;
00433 }
00434
00435
00436
00437 const CTime & CCorefine2dPropagation::getDoubleEdgesCleaningTime() const
00438 {
00439 return FDoubleEdgesCleaningTime;
00440 }
00441
00442
00443
00444 void CCorefine2dPropagation::initMesh(CDart * AMesh)
00445 {
00446 ENTER;
00447
00448 int vert_mark = FMap->getNewMark();
00449 CAttributeVertex *vert;
00450
00451 for (CStaticCoverageCC scc2(FMap, AMesh); scc2.cont(); ++scc2)
00452 if (FMap->isFree2(*scc2))
00453 FMap->stopUp(*scc2, 2);
00454
00455 for (CStaticCoverageCC scc1(FMap, AMesh); scc1.cont(); ++scc1)
00456 if (FMap->isFree1(*scc1))
00457 FMap->linkAlpha1(*scc1, a2(*scc1));
00458
00459 for (CDynamicCoverageCC dcc(FMap, AMesh); dcc.cont(); ++dcc) {
00460 FMap->setDirectInfo(*dcc, FAlpha1DI, NULL);
00461
00462 if (!FMap->isMarked(*dcc, vert_mark)) {
00463 vert = FMap->findVertex(*dcc);
00464
00465 *(CVertex*)vert = FPlane.projectPoint(*vert, FBestProj);
00466
00467
00468 for (CDynamicCoverageVertex dcv(FMap, *dcc) ; dcv.cont() ; dcv++) {
00469 FMap->setMark(*dcv, vert_mark);
00470 FMap->setDirectInfo(*dcv, FVertexDI, vert);
00471 }
00472
00473
00474
00475
00476 }
00477 }
00478
00479 FMap->unmarkOrbit(AMesh, ORBIT_CC, vert_mark);
00480 FMap->freeMark(vert_mark);
00481
00482 EXIT;
00483 }
00484
00485
00486
00487 void CCorefine2dPropagation::cleanMesh(CDart * AMesh)
00488 {
00489 ENTER;
00490
00491 int vert_mark = FMap->getNewMark();
00492 CAttributeVertex *vert;
00493
00494 for (CDynamicCoverageCC dcc(FMap, AMesh) ; dcc.cont() ; dcc++) {
00495 FMap->setDirectInfo(*dcc, FAlpha1DI, NULL);
00496
00497 if (!FMap->isMarked(*dcc, vert_mark)) {
00498 FMap->markOrbit(*dcc, ORBIT_VERTEX, vert_mark);
00499 vert = FMap->findVertex(*dcc);
00500
00501 *(CVertex*)vert = FPlane.unprojectPoint(*vert, FBestProj);
00502 }
00503 }
00504
00505 FMap->unmarkOrbit(AMesh, ORBIT_CC, vert_mark);
00506 FMap->freeMark(vert_mark);
00507
00508 EXIT;
00509 }
00510
00511
00512
00513 CDart * CCorefine2dPropagation::splitEdge(CDart * AEdge,
00514 const CVertex & AVertex)
00515 {
00516 ENTER;
00517
00518 CDart *d = a1(FMap->CGMapGeneric::insertVertex(AEdge));
00519
00520 CAttributeVertex *att = new CAttributeVertex(AVertex);
00521
00522 FMap->setVertex(d, att);
00523
00524 for (CDynamicCoverageVertex dcv(FMap, d) ; dcv.cont() ; dcv++) {
00525 FMap->setDirectInfo(*dcv, FVertexDI, att);
00526 FMap->setDirectInfo(*dcv, FAlpha1DI, NULL);
00527
00528 for (int i = 0; i < NB_MARKS; i++)
00529 if (FCopyMarks[i] && FMap->isMarked(a0(*dcv), i))
00530 FMap->setMark(*dcv, i);
00531 }
00532
00533 EXIT;
00534
00535 return d;
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 class CAngularEdgeComparator
00589 {
00590 public:
00591 CAngularEdgeComparator(CGMapVertex * AMap, const CVertex & ACenter,
00592 int AVertexDI)
00593 : FMap(AMap), FCenter(ACenter), FVertexDI(AVertexDI) {}
00594
00595 bool operator () (CDart * AEdge1, CDart * AEdge2)
00596 {
00597 CVertex v1 = *getVertex(a0(AEdge1)) - FCenter;
00598 CVertex v2 = *getVertex(a0(AEdge2)) - FCenter;
00599 return (v1 * v2).getZ() > 0.0;
00600 }
00601
00602 private:
00603
00604 CAttributeVertex * getVertex(CDart * ADart) const
00605 { return (CAttributeVertex*)FMap->getDirectInfo(ADart, FVertexDI); }
00606
00607 private:
00608 CGMapVertex *FMap;
00609 CVertex FCenter;
00610 int FVertexDI;
00611 };
00612
00613 void CCorefine2dPropagation::weldVertices(CDart * AVertex1, CDart * AVertex2)
00614 {
00615 CAngularEdgeComparator comp(FMap, *getVertex(AVertex1), FVertexDI);
00616 multiset<CDart*, CAngularEdgeComparator> edges(comp);
00617 multiset<CDart*, CAngularEdgeComparator>::iterator it, tmp_it;
00618 CDart *d1, *d2;
00619
00620
00621 d1 = AVertex1;
00622 do {
00623 edges.insert(d1);
00624 d1 = a2(FTools.alpha1(d1));
00625 }
00626 while (d1 != AVertex1);
00627
00628
00629 d2 = AVertex2;
00630 do {
00631 edges.insert(d2);
00632 d2 = a2(FTools.alpha1(d2));
00633 }
00634 while (d2 != AVertex2);
00635
00636 for (it = edges.begin(); it != edges.end(); ) {
00637 tmp_it = it++;
00638
00639 d1 = *tmp_it;
00640 d2 = (it != edges.end()) ? *it : *edges.begin();
00641
00642 if (a1(d1) != a2(d2)) {
00643 FMap->setDirectInfo(d1, FAlpha1DI, a2(d2));
00644 FMap->setDirectInfo(a2(d2), FAlpha1DI, d1);
00645 }
00646 }
00647
00648 ++FNumberOfIntersections;
00649 }
00650
00651
00652
00653 void CCorefine2dPropagation::weldMultipleVertices(CDart * AVertex1,
00654 CDart * AVertex2)
00655 {
00656 list<CDart*> vertices;
00657 list<CDart*>::iterator it;
00658 CDart *d1, *d2;
00659 int mark = FMap->getNewMark();
00660
00661 FMap->markOrbit(AVertex1, ORBIT_VERTEX, mark);
00662
00663
00664 d1 = AVertex1;
00665 do {
00666 d2 = b1(d1);
00667
00668 if (d2 != NULL && !FMap->isMarked(d2, mark)) {
00669 vertices.push_back(d2);
00670 FMap->markOrbit(d2, ORBIT_VERTEX, mark);
00671 }
00672
00673 d1 = a2(a1(d1));
00674 }
00675 while (d1 != AVertex1);
00676
00677
00678 if (!FMap->isMarked(AVertex2, mark)) {
00679 vertices.push_back(AVertex2);
00680 FMap->markOrbit(AVertex2, ORBIT_VERTEX, mark);
00681 }
00682
00683
00684 d1 = AVertex2;
00685 do {
00686 d2 = b1(d1);
00687
00688 if (d2 != NULL && !FMap->isMarked(d2, mark)) {
00689 vertices.push_back(d2);
00690 FMap->markOrbit(d2, ORBIT_VERTEX, mark);
00691 }
00692
00693 d1 = a2(a1(d1));
00694 }
00695 while (d1 != AVertex2);
00696
00697
00698 for (it = vertices.begin() ; it != vertices.end() ; it++)
00699 FMap->unmarkOrbit(*it, ORBIT_VERTEX, mark);
00700 FMap->freeMark(mark);
00701
00702 list<CDart*> * l = FTools.sortMultipleVerticesEdges(AVertex1, vertices,
00703 FVertexDI);
00704
00705 if (l == NULL) {
00706 cout << "\033[1;33m"
00707 << "Erreur lors du tri angulaire => fusion des sommets impossible !"
00708 << "\033[0m\n";
00709
00710 return;
00711 }
00712
00713 it = l->begin();
00714 d2 = *it;
00715
00716 do {
00717 d1 = d2;
00718 it++;
00719
00720 if (it != l->end())
00721 d2 = *it;
00722 else
00723 d2 = *l->begin();
00724
00725 if (a1(d1) != a2(d2)) {
00726 FMap->setDirectInfo(d1, FAlpha1DI, a2(d2));
00727 FMap->setDirectInfo(a2(d2), FAlpha1DI, d1);
00728 }
00729 else {
00730 FMap->setDirectInfo(d1, FAlpha1DI, NULL);
00731 FMap->setDirectInfo(a2(d2), FAlpha1DI, NULL);
00732 }
00733 }
00734 while (it != l->end());
00735
00736 delete l;
00737
00738 FNumberOfIntersections++;
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 void CCorefine2dPropagation::applyModifications(CDart * AMesh)
00784 {
00785 ENTER;
00786
00787 CDart *d1, *d2;
00788
00789 for (CStaticCoverageCC scc(FMap, AMesh) ; scc.cont() ; scc++) {
00790 d1 = *scc;
00791 d2 = b1(d1);
00792
00793 if (d2 != NULL) {
00794 if (!FMap->isFree1(d1))
00795 FMap->dartUnsew1(d1);
00796
00797 if (!FMap->isFree1(d2))
00798 FMap->dartUnsew1(d2);
00799
00800 FMap->dartSew1(d1, d2);
00801 }
00802 }
00803
00804 EXIT;
00805 }
00806
00807
00808
00809 #undef a0
00810 #undef a1
00811 #undef a2
00812 #undef b1
00813
00814