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 <cmath>
00025 #include "corefine-3d.hh"
00026 #include "time.hh"
00027
00028 #include INCLUDE_NON_INLINE("corefine-3d.icc")
00029
00030 using namespace std;
00031 using namespace GMap3d;
00032
00033
00034
00035 #define a0 FMap->alpha0
00036 #define a1 FMap->alpha1
00037 #define a2 FMap->alpha2
00038 #define a3 FMap->alpha3
00039
00040 #define VTX(d) (AVertexDI < 0 ? FMap->findVertex(d) : \
00041 (CAttributeVertex*)FMap->getDirectInfo(d, AVertexDI))
00042
00043
00044
00045
00046 #define MIN_GRID_RES 2
00047 #define MAX_GRID_RES 512
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define COREFINEMENT_VERSION "Co-raffinement v11"
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 #define WARNING_MESSAGES
00080 #include "message-macros.hh"
00081
00082
00083
00084 #ifdef SAVE_INTERSECTION_POINTS
00085
00086 FILE * point_file = NULL;
00087
00088 #define SAVE_POINT(p) (fprintf(point_file ? point_file : stdout, \
00089 "%.6f # %.6f # %.6f\n", \
00090 (p).getX()*10, (p).getY()*10, (p).getZ()*10))
00091
00092 #else // SAVE_INTERSECTION_POINTS
00093
00094 #define SAVE_POINT(p)
00095
00096 #endif // SAVE_INTERSECTION_POINTS
00097
00098
00099
00100 CCorefine3d::CCorefine3d(CGMapVertex * AMap, bool ACalculateOrientation,
00101 TCoordinate AEpsilon, int AVertexDI)
00102 : CCorefine(AMap, AEpsilon), FCalculateOrientation(ACalculateOrientation),
00103 FComputeOnlyFirstIntersection(false), FGridResolution(70),
00104 FTools(AMap, AEpsilon)
00105 {
00106 ENTER;
00107
00108 if (FEps > 0)
00109 CBoundingBox::setEpsilon(2*FEps);
00110
00111 if (AVertexDI < 0) {
00112 FVertexDI = FMap->getNewDirectInfo();
00113 FLocalVertexDirectInfo = true;
00114 }
00115 else {
00116 FVertexDI = AVertexDI;
00117 FLocalVertexDirectInfo = false;
00118 }
00119
00120 EXIT;
00121 }
00122
00123
00124
00125 CCorefine3d::~CCorefine3d()
00126 {
00127 ENTER;
00128
00129 if (FLocalVertexDirectInfo)
00130 FMap->freeDirectInfo(FVertexDI);
00131
00132 EXIT;
00133 }
00134
00135
00136
00137 void CCorefine3d::computeOnlyFirstIntersection(bool ABoolean)
00138 {
00139 FComputeOnlyFirstIntersection = ABoolean;
00140 }
00141
00142
00143
00144 void CCorefine3d::setGridResolution(int ARes)
00145 {
00146 FGridResolution = ARes;
00147 }
00148
00149
00150
00151 int CCorefine3d::corefine(CDart *& AMesh1, CDart *& AMesh2,
00152 bitset<NB_MARKS> ACopyMarks)
00153 {
00154 ENTER;
00155
00156 list<CDart*> vertex_list;
00157 CEdgeIntersection inter;
00158 unsigned long nb_faces;
00159 CDart *vertex=NULL, *edge=NULL, *tmp_edge=NULL, *tmp_face=NULL;
00160 int edge_mark = FMap->getNewMark();
00161 int vertex_mark = FMap->getNewMark();
00162 CVertex *pt1, *pt2, tmp_pt;
00163 CPlane plane;
00164 CTime start, end;
00165
00166 FFaceDI = FMap->getNewDirectInfo();
00167 FAlpha2DI = FMap->getNewDirectInfo();
00168
00169 FOrientMark = FMap->getNewMark();
00170 FFictiveMark = FMap->getNewMark();
00171 FIntersectionMark = FMap->getNewMark();
00172
00173 FCopyMarks = ACopyMarks;
00174
00175 FNumberOfIntersectionLines = 0;
00176 FNumberOfIntersectionEdges = 0;
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 #ifdef COREFINEMENT_VERSION
00190 cout << COREFINEMENT_VERSION << endl;
00191 #endif
00192
00193 #ifdef SAVE_INTERSECTION_POINTS
00194 point_file = fopen("intersections.dat", "w");
00195 #endif
00196
00197 cout << "Initialisation des maillages" << endl;
00198 start.updateTime();
00199
00200 nb_faces = initMesh(AMesh1);
00201 cout << "Nombre de faces sur le premier maillage : " << nb_faces << endl;
00202
00203 nb_faces = initMesh(AMesh2);
00204 cout << "Nombre de faces sur le second maillage : " << nb_faces << endl;
00205
00206 end.updateTime();
00207 FInitialisationTime = end - start;
00208 cout << "Durée de l'initialisation : " << FInitialisationTime << endl;
00209
00210 cout << "Orientation des maillages" << endl;
00211 start.updateTime();
00212
00213
00214 if (FCalculateOrientation) {
00215 AMesh1 = FTools.findWellOrientedDart(AMesh1, FVertexDI);
00216 AMesh2 = FTools.findWellOrientedDart(AMesh2, FVertexDI);
00217 }
00218
00219
00220 FMap->halfMarkOrbit(AMesh1, ORBIT_CC, FOrientMark);
00221 FMap->halfMarkOrbit(AMesh2, ORBIT_CC, FOrientMark);
00222
00223 end.updateTime();
00224 cout << "Durée de l'orientation : " << end - start << endl;
00225
00226 cout << "Création de la grille régulière pour l'optimisation" << endl;
00227 start.updateTime();
00228
00229 createGrid(AMesh2, nb_faces);
00230
00231
00232
00233
00234
00235
00236 end.updateTime();
00237 FGridCreationTime = end - start;
00238 cout << "Durée de la création : " << FGridCreationTime << endl;
00239
00240 FLineCreationTime.setTime(0);
00241
00242 cout << "Traitement de la première intersection" << endl;
00243 start.updateTime();
00244
00245
00246 int tmp_dim;
00247 tmp_pt = *getVertex(AMesh1);
00248 tmp_face = findFirstIntersectionInGrid(tmp_pt, &tmp_dim);
00249
00250 if (tmp_face != NULL) {
00251 switch (tmp_dim) {
00252 case 0:
00253 *getVertex(AMesh1) = *getVertex(tmp_face);
00254 break;
00255
00256 case 1:
00257 tmp_face = splitEdge(tmp_face, tmp_pt);
00258 break;
00259
00260 case 2:
00261 tmp_face = insertVertexInFace(tmp_face, tmp_pt);
00262 break;
00263 }
00264
00265 followIntersection(AMesh1, tmp_face, vertex_mark);
00266 }
00267
00268 cout << "Parcours des maillages et création des intersections" << endl;
00269
00270
00271 vertex_list.push_back(AMesh1);
00272
00273
00274 while(!vertex_list.empty()) {
00275
00276
00277 vertex = vertex_list.front(), vertex_list.pop_front();
00278
00279
00280 for (CStaticCoverageVertex dcv(FMap, vertex); dcv.cont(); ++dcv) {
00281 edge = *dcv;
00282
00283 if (!FMap->isMarked(edge, edge_mark) &&
00284 FMap->isMarked(edge, FOrientMark)) {
00285 pt1 = getVertex(edge);
00286 pt2 = getVertex(a0(edge));
00287
00288 MSG("Arête parcourue = [" << *pt1 << "," << *pt2 << "]");
00289
00290 if (!FMap->isMarked(edge, FFictiveMark))
00291 inter = findNearestIntersectionInGrid(*pt1, *pt2);
00292 else
00293 inter.setCell(NULL);
00294
00295 if (inter.getCell() != NULL &&
00296
00297 ((*pt2 - inter.getPoint()).norm() > 2.0 * FEps ||
00298 !FMap->isMarked(a0(edge), vertex_mark))) {
00299
00300 assert(inter.getPosition() != EP_OnFirstVertex);
00301
00302
00303
00304
00305
00306
00307
00308 switch (inter.getPosition()) {
00309 case EP_OnFirstVertex:
00310 tmp_edge = edge;
00311 *pt1 = inter.getPoint();
00312 break;
00313
00314 case EP_OnSecondVertex:
00315 tmp_edge = a3(a0(edge));
00316 *pt2 = inter.getPoint();
00317 break;
00318
00319 case EP_OnEdge:
00320 tmp_edge = splitEdge(edge, inter.getPoint());
00321 break;
00322
00323 default:
00324 break;
00325 }
00326
00327 switch (inter.getCellDimension()) {
00328 case 0:
00329 tmp_face = inter.getCell();
00330 *getVertex(inter.getCell()) = inter.getPoint();
00331 break;
00332
00333 case 1:
00334 tmp_face = splitEdge(inter.getCell(), inter.getPoint());
00335 break;
00336
00337 case 2:
00338 tmp_face = insertVertexInFace(inter.getCell(), inter.getPoint());
00339 break;
00340
00341 default:
00342 tmp_face = NULL;
00343 break;
00344 }
00345
00346 followIntersection(tmp_edge, tmp_face, vertex_mark);
00347 }
00348 else {
00349 tmp_edge = a3(a0(edge));
00350 }
00351
00352 if (!FMap->isMarked(tmp_edge, vertex_mark) ||
00353 !FComputeOnlyFirstIntersection)
00354 vertex_list.push_back(tmp_edge);
00355
00356 FMap->markOrbit(edge, ORBIT_EDGE, edge_mark);
00357 }
00358 }
00359 }
00360
00361 FMap->unmarkOrbit(AMesh1, ORBIT_CC, edge_mark);
00362 FMap->unmarkOrbit(AMesh1, ORBIT_CC, vertex_mark);
00363
00364 if (FNumberOfIntersectionEdges == 0)
00365 FMap->unmarkOrbit(AMesh2, ORBIT_CC, vertex_mark);
00366
00367 FMap->freeMark(edge_mark);
00368 FMap->freeMark(vertex_mark);
00369
00370 end.updateTime();
00371 FResearchTime = end - start;
00372 cout << "Durée de la recherche des intersections : "
00373 << FResearchTime << endl;
00374
00375 FResearchTime -= FLineCreationTime;
00376
00377 cout << "Assemblage des maillages" << endl;
00378 start.updateTime();
00379
00380 applyModifications(AMesh1);
00381
00382 end.updateTime();
00383 FUpdateTime = end - start;
00384 cout << "Durée de l'assemblage : " << FUpdateTime << endl;
00385
00386 #ifdef EXTRACT_LINES
00387 cout << "Extraction des lignes de coupes" << endl;
00388 extractIntersectionLines(AMesh1);
00389 FMap->unmarkOrbit(AMesh1, ORBIT_CC, FIntersectionMark);
00390 #endif // EXTRACT_LINES
00391
00392 cout << "Destruction de la grille" << endl;
00393 start.updateTime();
00394
00395 destroyGrid();
00396
00397 end.updateTime();
00398 cout << "Durée de la destruction : " << end - start << endl;
00399
00400 cout << "Nettoyage des maillages" << endl;
00401 start.updateTime();
00402
00403 cleanMesh(AMesh1);
00404
00405 if (FNumberOfIntersectionEdges == 0)
00406 cleanMesh(AMesh2);
00407
00408 end.updateTime();
00409 cout << "Durée du nettoyage : " << end - start << endl;
00410
00411 cout << "Il y a eu " << FNumberOfIntersectionLines << " ligne(s) de coupe et "
00412 << FNumberOfIntersectionEdges << " arête(s) d'intersection" << endl;
00413
00414 #ifdef SAVE_INTERSECTION_POINTS
00415 if (point_file != NULL) {
00416 fclose(point_file);
00417 point_file = NULL;
00418 }
00419 #endif
00420
00421 FMap->freeDirectInfo(FFaceDI);
00422 FMap->freeDirectInfo(FAlpha2DI);
00423
00424 FMap->freeMark(FOrientMark);
00425 FMap->freeMark(FFictiveMark);
00426 FMap->freeMark(FIntersectionMark);
00427
00428 EXIT;
00429
00430 return FNumberOfIntersectionLines;
00431 }
00432
00433
00434
00435 unsigned long CCorefine3d::initMesh(CDart * AMesh)
00436 {
00437 ENTER;
00438
00439 int mark = FMap->getNewMark();
00440 unsigned long int nb_faces = 0;
00441
00442 MSG("mark = " << mark);
00443
00444
00445 for (CStaticCoverageCC scc(FMap, AMesh); scc.cont(); ++scc) {
00446 if (FMap->isFree1(*scc))
00447 cerr << "<initMesh> Le brin " << *scc
00448 << " n'est pas lié par alpha1 !!!" << endl;
00449
00450 if (FMap->isFree3(*scc))
00451 FMap->stopUp(*scc, 3);
00452 }
00453
00454
00455
00456
00457
00458
00459
00460 CDynamicCoverageCC dcc(FMap, AMesh);
00461
00462
00463
00464 for (dcc.reinit(); dcc.cont(); ++dcc) {
00465 if (!FMap->isMarked(*dcc, mark)) {
00466 FMap->markOrbit(*dcc, ORBIT_VERTEX, mark);
00467 updateVertexLinks(*dcc);
00468 }
00469 }
00470
00471
00472
00473
00474
00475
00476
00477 for (dcc.reinit(); dcc.cont(); ++dcc) {
00478 FMap->setDirectInfo(*dcc, FAlpha2DI, NULL);
00479
00480 if (FMap->isMarked(*dcc, mark)) {
00481 nb_faces++;
00482 FMap->unmarkOrbit(*dcc, ORBIT_FACE, mark);
00483 updateFaceLinks(*dcc);
00484 }
00485 }
00486
00487 FMap->freeMark(mark);
00488
00489 EXIT;
00490
00491 return nb_faces;
00492 }
00493
00494
00495
00496 void CCorefine3d::cleanMesh(CDart * )
00497 {
00498 ENTER;
00499
00500 int delete_mark = FMap->getNewMark();
00501
00502 MSG("delete_mark = " << delete_mark);
00503
00504 for (CDynamicCoverageAll dca(FMap); dca.cont(); ++dca) {
00505 if (FMap->isMarked(*dca, FOrientMark)) {
00506 FMap->unmarkOrbit(*dca, ORBIT_EDGE, FOrientMark);
00507
00508 if (FMap->isMarked(*dca, FFictiveMark)) {
00509 if (getFace(*dca) != getFace(a2(*dca))) {
00510 removeEdge(*dca, delete_mark);
00511 }
00512 else
00513 FMap->unmarkOrbit(*dca, ORBIT_EDGE, FFictiveMark);
00514 }
00515 }
00516 }
00517 FMap->deleteMarkedDarts(delete_mark);
00518 FMap->freeMark(delete_mark);
00519
00520 EXIT;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
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 void CCorefine3d::createGrid(CDart * AMesh, unsigned long ANbFaces)
00588 {
00589 ENTER;
00590
00591 int face_mark = FMap->getNewMark();
00592 CBoundingBox bb = FTools.orbitBoundingBox(AMesh, ORBIT_CC, FVertexDI);
00593 CVertex size = bb.getEpsMaxBound() - bb.getEpsMinBound();
00594 unsigned int size_i, size_j, size_k;
00595
00596 MSG("face_mark = " << face_mark);
00597
00598
00599 if (FGridResolution > 0)
00600 getGridResolution(normalizeGridSize(size), 1, FGridResolution,
00601 &size_i, &size_j, &size_k);
00602 else
00603 computeGridResolution(normalizeGridSize(size),
00604 ANbFaces, 0.05,
00605 &size_i, &size_j, &size_k,
00606 MIN_GRID_RES, MAX_GRID_RES);
00607
00608 cout << "Résolution de la grille = "
00609 << size_i << "x" << size_j << "x" << size_k << endl;
00610
00611 FGrid = new TFaceGrid(size_i, size_j, size_k, bb);
00612 for (TFaceGridIter gi(*FGrid); gi.cont(); ++gi)
00613 FGrid->setCell(gi, new list<CDart*>);
00614
00615 for (CDynamicCoverageCC dcc(FMap, AMesh); dcc.cont(); ++dcc) {
00616 if (!FMap->isMarked(*dcc, face_mark) &&
00617 FMap->isMarked(*dcc, FOrientMark)) {
00618 FMap->markOrbit(*dcc, ORBIT_FACE, face_mark);
00619 addFaceToGrid(FGrid, *dcc);
00620 }
00621 }
00622
00623 FMap->unmarkOrbit(AMesh, ORBIT_CC, face_mark);
00624 FMap->freeMark(face_mark);
00625
00626
00627
00628
00629 EXIT;
00630 }
00631
00632
00633
00634 void CCorefine3d::destroyGrid()
00635 {
00636 ENTER;
00637
00638 for (TFaceGridIter gi(*FGrid); gi.cont(); ++gi)
00639 delete *gi;
00640 delete FGrid;
00641
00642 EXIT;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 unsigned int CCorefine3d::getMaxVerticesDegree(list<CDart*> * AList)
00693 {
00694 ENTER;
00695
00696 list<CDart*>::iterator it;
00697 unsigned int max_deg = 0, current_deg;
00698
00699 for (it = AList->begin(); it != AList->end(); it++) {
00700 for (CDynamicCoverage01 dcf(FMap, *it); dcf.cont(); dcf++) {
00701 if (FMap->isMarked(*dcf, FOrientMark)) {
00702 current_deg = 0;
00703
00704 for (CDynamicCoverageVertex dcv(FMap, *dcf); dcv.cont(); dcv++)
00705 current_deg++;
00706
00707 if (current_deg > max_deg)
00708 max_deg = current_deg;
00709 }
00710 }
00711 }
00712
00713 EXIT;
00714
00715 return max_deg / 4;
00716 }
00717
00718
00719
00720 CVertex CCorefine3d::normalizeGridSize(const CVertex & AGridSize)
00721 {
00722 TCoordinate max;
00723
00724 max = (AGridSize.getX() > AGridSize.getY() ?
00725 (AGridSize.getX() > AGridSize.getZ() ?
00726 AGridSize.getX() : AGridSize.getZ()) :
00727 (AGridSize.getY() > AGridSize.getZ() ?
00728 AGridSize.getY() : AGridSize.getZ()));
00729
00730 return AGridSize / max;
00731 }
00732
00733
00734
00735 void CCorefine3d::getGridResolution(const CVertex & AGridSize,
00736 unsigned int AMinRes,
00737 unsigned int AMaxRes,
00738 unsigned int * AResX,
00739 unsigned int * AResY,
00740 unsigned int * AResZ)
00741 {
00742 assert(AGridSize.getX() >= 0.0 && AGridSize.getX() <= 1.0 &&
00743 AGridSize.getY() >= 0.0 && AGridSize.getY() <= 1.0 &&
00744 AGridSize.getZ() >= 0.0 && AGridSize.getZ() <= 1.0);
00745
00746 *AResX = (int)(AGridSize.getX() * AMaxRes + 0.5);
00747 *AResY = (int)(AGridSize.getY() * AMaxRes + 0.5);
00748 *AResZ = (int)(AGridSize.getZ() * AMaxRes + 0.5);
00749 if (*AResX < AMinRes) *AResX = AMinRes;
00750 if (*AResY < AMinRes) *AResY = AMinRes;
00751 if (*AResZ < AMinRes) *AResZ = AMinRes;
00752 }
00753
00754
00755
00756 void CCorefine3d::computeGridResolution(const CVertex & AGridSize,
00757 unsigned long ANbFaces,
00758 TCoordinate ANbFacesPerCell,
00759 unsigned int * AResX,
00760 unsigned int * AResY,
00761 unsigned int * AResZ,
00762 unsigned int AMinRes,
00763 unsigned int )
00764 {
00765 assert(AGridSize.getX() >= 0.0 && AGridSize.getX() <= 1.0 &&
00766 AGridSize.getY() >= 0.0 && AGridSize.getY() <= 1.0 &&
00767 AGridSize.getZ() >= 0.0 && AGridSize.getZ() <= 1.0);
00768
00769 double res = pow((double)ANbFaces /
00770 (double)(ANbFacesPerCell * AGridSize.getX() *
00771 AGridSize.getY() * AGridSize.getZ()),
00772 1.0/3.0);
00773
00774 getGridResolution(AGridSize, AMinRes, (int)(res+0.5), AResX, AResY, AResZ);
00775 }
00776
00777
00778
00779 unsigned int CCorefine3d::refineGrid(unsigned int AMaxSubDiv,
00780 unsigned int AMaxNumberOfFaces)
00781 {
00782 ENTER;
00783
00784 list<CDart*> *l;
00785 list<CDart*>::iterator it;
00786 TFaceGrid *sub_grid;
00787 unsigned int max_deg, size, result = 0;
00788 unsigned int div_x, div_y, div_z;
00789
00790 for (TFaceGridIter gi(*FGrid); gi.cont(); ++gi) {
00791 l = *gi;
00792 size = l->size();
00793
00794 if (size > AMaxNumberOfFaces) {
00795 max_deg = getMaxVerticesDegree(l);
00796
00797 if (max_deg <= AMaxNumberOfFaces || size > 2 * max_deg) {
00798 result++;
00799
00800 #ifdef FIXED_SUB_GRID_RES
00801 div_x = div_y = div_z = FIXED_SUB_GRID_RES;
00802 #else
00803 computeGridResolution(CVertex(1.0, 1.0, 1.0),
00804 size, 0.05,
00805 &div_x, &div_y, &div_z,
00806 MIN_GRID_RES, AMaxSubDiv);
00807 #endif
00808
00809
00810
00811
00812 sub_grid = FGrid->splitCellInGrid(gi, div_x, div_y, div_z);
00813
00814 for (TFaceGridIter gi2(*sub_grid); gi2.cont(); ++gi2)
00815 sub_grid->setCell(gi2, new list<CDart*>);
00816
00817 for (it = l->begin(); it != l->end(); ++it)
00818 addFaceToGrid(sub_grid, *it);
00819
00820 delete l;
00821 }
00822 }
00823 }
00824
00825 EXIT;
00826
00827 return result;
00828 }
00829
00830
00831
00832 void CCorefine3d::addFaceToGrid(TFaceGrid * AGrid, CDart * AFace)
00833 {
00834 ENTER;
00835
00836 assert(AGrid != NULL);
00837 assert(AFace != NULL);
00838
00839 CBoundingBox bb = FTools.orbitBoundingBox(AFace, ORBIT_01, FVertexDI);
00840
00841 for (TFaceGridIter gi(*AGrid, bb); gi.cont(); ++gi)
00842 (*gi)->push_back(getFace(AFace));
00843
00844 EXIT;
00845 }
00846
00847
00848
00849 void CCorefine3d::removeFaceFromGrid(TFaceGrid * AGrid,
00850 CDart * AFace)
00851 {
00852 ENTER;
00853
00854 AFace = getFace(AFace);
00855
00856 CBoundingBox bb = FTools.orbitBoundingBox(AFace, ORBIT_01, FVertexDI);
00857 list<CDart*> *dart_list;
00858 list<CDart*>::iterator li, old_li;
00859
00860 for (TFaceGridIter gi(*AGrid, bb); gi.cont(); ++gi) {
00861 dart_list = *gi;
00862
00863 for (li = dart_list->begin(); li != dart_list->end(); ) {
00864 old_li = li;
00865 ++li;
00866 if (*old_li == AFace)
00867 dart_list->erase(old_li);
00868 }
00869 }
00870
00871 EXIT;
00872 }
00873
00874
00875
00876 void CCorefine3d::updateVertexLinks(CDart * ADart, CAttributeVertex * AVertex)
00877 {
00878 ENTER;
00879
00880 for (CDynamicCoverageVertex dcv(FMap, ADart); dcv.cont(); ++dcv) {
00881 FMap->setDirectInfo(*dcv, FVertexDI, AVertex);
00882 }
00883
00884 EXIT;
00885 }
00886
00887
00888
00889 void CCorefine3d::updateVertexLinks(CDart * ADart)
00890 {
00891 ENTER;
00892
00893 CAttributeVertex * att = FMap->findVertex(ADart);
00894
00895 for (CDynamicCoverageVertex dcv(FMap, ADart); dcv.cont(); ++dcv) {
00896 FMap->setDirectInfo(*dcv, FVertexDI, att);
00897 }
00898
00899 EXIT;
00900 }
00901
00902
00903
00904 void CCorefine3d::updateFaceLinks(CDart * AFace)
00905 {
00906 ENTER;
00907
00908 for (CDynamicCoverageFace dcf(FMap, AFace); dcf.cont(); ++dcf) {
00909 FMap->setDirectInfo(*dcf, FFaceDI, AFace);
00910 }
00911
00912 EXIT;
00913 }
00914
00915
00916
00917 CDart * CCorefine3d::createEdge()
00918 {
00919 ENTER;
00920
00921 CDart *d[8];
00922
00923 for (int i=0; i<8; ++i) {
00924 d[i] = FMap->addMapDart();
00925 FMap->setDirectInfo(d[i], FAlpha2DI, NULL);
00926 }
00927
00928 FMap->linkAlpha0(d[0], d[1]);
00929 FMap->linkAlpha0(d[2], d[3]);
00930 FMap->linkAlpha0(d[4], d[5]);
00931 FMap->linkAlpha0(d[6], d[7]);
00932
00933 FMap->linkAlpha2(d[0], d[2]);
00934 FMap->linkAlpha2(d[1], d[3]);
00935 FMap->linkAlpha2(d[4], d[6]);
00936 FMap->linkAlpha2(d[5], d[7]);
00937
00938 FMap->linkAlpha3(d[0], d[4]);
00939 FMap->linkAlpha3(d[1], d[5]);
00940 FMap->linkAlpha3(d[2], d[6]);
00941 FMap->linkAlpha3(d[3], d[7]);
00942
00943 FMap->halfMarkOrbit(d[0], ORBIT_EDGE, FOrientMark);
00944
00945
00946
00947
00948
00949
00950 EXIT;
00951
00952 return d[0];
00953 }
00954
00955
00956
00957 CDart * CCorefine3d::insertVertexInFace(CDart * AFace, const CVertex & APoint)
00958 {
00959 ENTER;
00960
00961 assert(FMap->isMarked(AFace, FOrientMark));
00962
00963 CDart *vertex = a1(a0(insertEdgeInFace(AFace, APoint)));
00964
00965 FMap->markOrbit(vertex, ORBIT_EDGE, FFictiveMark);
00966
00967 EXIT;
00968
00969 return vertex;
00970 }
00971
00972
00973
00974 CDart * CCorefine3d::insertEdgeInFace(CDart * AVertex1,
00975 const CVertex & AVertex2)
00976 {
00977 ENTER;
00978
00979 assert(FMap->isMarked(AVertex1, FOrientMark));
00980
00981 CDart *edge;
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 CDart *old_a1, *face = getFace(AVertex1);
00999
01000 CPlane plane = FTools.facePlane(AVertex1, FVertexDI);
01001
01002 assert(FTools.isPointOnPlane(AVertex2, plane));
01003
01004 if (FTools.isVectorNull(plane.getNormal())) {
01005 cout << "\033[1;34m";
01006 FTools.displayFaceVertices(AVertex1, FVertexDI);
01007 cout << "<insertEdgeInFace> La normale à la face est nulle : "
01008 << plane.getNormal() << "\033[0m\n";
01009 }
01010
01011
01012
01013 AVertex1 = FTools.findSectorOfVector(AVertex2 - *getVertex(AVertex1),
01014 AVertex1, plane, FVertexDI);
01015
01016 AVertex1 = a1(AVertex1);
01017
01018 edge = createEdge();
01019
01020 assert(!FMap->isFree1(AVertex1));
01021
01022 old_a1 = a1(AVertex1);
01023 FMap->unsew1(AVertex1);
01024
01025 FMap->sew1(AVertex1, edge);
01026 FMap->sew1(old_a1, a2(edge));
01027 FMap->sew1(a0(edge), a0(a2(edge)));
01028
01029 updateVertexLinks(AVertex1);
01030
01031 FMap->setVertex(a0(edge), AVertex2);
01032
01033 for (CDynamicCoverage23 dc(FMap, edge); dc.cont(); ++dc) {
01034 FMap->setDirectInfo(*dc, FFaceDI, face);
01035 FMap->setDirectInfo(a0(*dc), FFaceDI, face);
01036
01037 for (int m = 0; m < NB_MARKS; m++)
01038 if (FCopyMarks[m] && FMap->isMarked(a1(*dc), m)) {
01039 FMap->setMark(*dc, m);
01040 FMap->setMark(a0(*dc), m);
01041 }
01042 }
01043
01044 updateVertexLinks(a0(edge));
01045
01046
01047 EXIT;
01048
01049 return edge;
01050 }
01051
01052
01053
01054 CDart * CCorefine3d::splitFace(CDart * AVertex1, CDart * AVertex2)
01055 {
01056 ENTER;
01057
01058 assert(AVertex1 != AVertex2);
01059 assert(FMap->isMarked(AVertex1, FOrientMark));
01060 assert(FMap->isMarked(AVertex2, FOrientMark));
01061
01062 CDart *edge = NULL;
01063
01064
01065 for (CDynamicCoverage12 dc1(FMap, AVertex1); dc1.cont() && !edge; ++dc1)
01066 for (CDynamicCoverage12 dc2(FMap, AVertex2); dc2.cont() && !edge; ++dc2)
01067 if (a0(*dc1) == *dc2) {
01068 if (FMap->isMarked(*dc1, FOrientMark))
01069 edge = *dc1;
01070 else
01071 edge = a3(*dc1);
01072
01073 if (FMap->isMarked(edge, FFictiveMark))
01074 FMap->unmarkOrbit(edge, ORBIT_EDGE, FFictiveMark);
01075 }
01076
01077
01078 if (edge == NULL) {
01079 CVertex v = *getVertex(AVertex2) - *getVertex(AVertex1);
01080
01081 MSG("Création d'une arête entre " << *getVertex(AVertex1)
01082 << " et " << *getVertex(AVertex2));
01083
01084 CPlane plane = FTools.facePlane(AVertex1, FVertexDI);
01085
01086 if (FTools.isVectorNull(plane.getNormal())) {
01087 cout << "\033[1;34m";
01088 FTools.displayFaceVertices(AVertex1, FVertexDI);
01089 cout << "<splitFace> La normale à la face est nulle : "
01090 << plane.getNormal() << "\033[0m\n";
01091 }
01092
01093 AVertex1 = FTools.findSectorOfVector(v, AVertex1, plane, FVertexDI);
01094 AVertex2 = FTools.findSectorOfVector(-v, AVertex2, plane, FVertexDI);
01095
01096 CDart *old_a1[2], *face = getFace(AVertex1);
01097
01098 edge = createEdge();
01099
01100
01101
01102 AVertex1 = a1(AVertex1);
01103
01104 old_a1[0] = a1(AVertex1);
01105 old_a1[1] = a1(AVertex2);
01106
01107 assert(!FMap->isFree1(AVertex1));
01108 FMap->unsew1(AVertex1);
01109
01110 assert(!FMap->isFree1(AVertex2));
01111 FMap->unsew1(AVertex2);
01112
01113 FMap->sew1(AVertex1, edge);
01114 FMap->sew1(old_a1[0], a2(edge));
01115
01116 FMap->sew1(AVertex2, a0(edge));
01117 FMap->sew1(old_a1[1], a2(a0(edge)));
01118
01119 updateVertexLinks(edge);
01120 updateVertexLinks(a0(edge));
01121
01122 if (!FMap->isSameOrbit(edge, a2(edge), ORBIT_01)) {
01123 updateFaceLinks(edge);
01124 updateFaceLinks(a2(edge));
01125 }
01126 else {
01127 for (CDynamicCoverageEdge dce(FMap, edge); dce.cont(); ++dce)
01128 FMap->setDirectInfo(*dce, FFaceDI, face);
01129 }
01130
01131
01132
01133
01134 }
01135
01136 for (CDynamicCoverageEdge dce(FMap, edge); dce.cont(); ++dce) {
01137 for (int m = 0; m < NB_MARKS; m++)
01138 if (FCopyMarks[m] && FMap->isMarked(a1(*dce), m)) {
01139 FMap->setMark(*dce, m);
01140 }
01141 }
01142
01143 EXIT;
01144
01145 return edge;
01146 }
01147
01148
01149
01150 CDart * CCorefine3d::splitEdge(CDart * AVertex, const CVertex & APoint)
01151 {
01152 ENTER;
01153
01154 assert(FMap->isMarked(AVertex, FOrientMark));
01155
01156
01157
01158 MSG("Arête [" << *getVertex(AVertex) << "," << *getVertex(a0(AVertex))
01159 << "] éclatée en " << APoint);
01160
01161 CDart *d, *face = getFace(AVertex);
01162
01163 FMap->CGMapGeneric::insertVertex(AVertex);
01164
01165 d = a1(a0(AVertex));
01166
01167 FMap->halfMarkOrbit(d, ORBIT_VERTEX, FOrientMark);
01168
01169 if (FMap->isMarked(AVertex, FFictiveMark))
01170 FMap->markOrbit(d, ORBIT_VERTEX, FFictiveMark);
01171
01172 FMap->setVertex(d, APoint);
01173 updateVertexLinks(d);
01174
01175 for (CDynamicCoverageVertex dcv(FMap, d); dcv.cont(); ++dcv) {
01176 FMap->setDirectInfo(*dcv, FFaceDI, face);
01177 FMap->setDirectInfo(*dcv, FAlpha2DI, NULL);
01178
01179 for (int m = 0; m < NB_MARKS; m++)
01180 if (FCopyMarks[m] && FMap->isMarked(a0(*dcv), m)) {
01181 FMap->setMark(*dcv, m);
01182 }
01183 }
01184
01185 EXIT;
01186
01187 return d;
01188 }
01189
01190
01191
01192 CDart * CCorefine3d::removeEdge(CDart * AEdge, int ADeleteMark)
01193 {
01194 CDart *d1 = a1(AEdge);
01195 CDart *d2 = a1(a0(AEdge));
01196
01197 if (ADeleteMark < 0)
01198 FMap->merge(AEdge, a2(AEdge), 2, true);
01199 else {
01200 FMap->markOrbit(AEdge, ORBIT_EDGE, ADeleteMark);
01201 FMap->merge(AEdge, a2(AEdge), 2, false);
01202 }
01203
01204 updateVertexLinks(d1);
01205 updateVertexLinks(d2);
01206
01207 return d1;
01208 }
01209
01210
01211
01212 CVertex CCorefine3d::getProjectionOnPlane(CDart * AVertex,
01213 const CPlane & APlane)
01214 {
01215 ENTER;
01216
01217 CVertex pt, v1, v2;
01218 TCoordinate t=0;
01219
01220 pt = *getVertex(AVertex);
01221 v1 = *getVertex(a0(AVertex)) - pt;
01222 v2 = *getVertex(a0(a1(AVertex))) - pt;
01223
01224 APlane.getLineIntersection(pt, v1, &t);
01225
01226 if (t > 0)
01227 return pt + t * v1;
01228
01229 APlane.getLineIntersection(pt, v2, &t);
01230
01231 EXIT;
01232
01233 return pt + t * v2;
01234 }
01235
01236
01237
01238 bool CCorefine3d::isSameEdge_Naive(CDart * AEdge1, CDart * AEdge2)
01239 {
01240 ENTER;
01241
01242 assert(FMap->isMarked(AEdge1, FOrientMark));
01243 assert(FMap->isMarked(AEdge2, FOrientMark));
01244
01245 bool found = false;
01246
01247 for (CDynamicCoverage23 dc1(FMap, AEdge1); dc1.cont() && !found; ++dc1)
01248 for (CDynamicCoverage23 dc2(FMap, AEdge2); dc2.cont() && !found; ++dc2)
01249 found = (FMap->getDirectInfo(*dc1, FAlpha2DI) == *dc2);
01250
01251 EXIT;
01252
01253 return found;
01254 }
01255
01256
01257
01258 bool CCorefine3d::isSameEdge_Optimized(CDart * AEdge1, CDart * AEdge2)
01259 {
01260 ENTER;
01261
01262 assert(FMap->isMarked(AEdge1, FOrientMark));
01263 assert(FMap->isMarked(AEdge2, FOrientMark));
01264
01265 CDart *d = AEdge1;
01266 bool same_edge = false;
01267
01268 do {
01269 if (FMap->getDirectInfo(d, FAlpha2DI) != NULL)
01270 d = a3((CDart*)FMap->getDirectInfo(d, FAlpha2DI));
01271 else
01272 d = a3(FTools.alpha2(d));
01273
01274 same_edge = (d == AEdge2) || (d == a3(a0(AEdge2)));
01275 }
01276 while (d != AEdge1 && !same_edge);
01277
01278 EXIT;
01279
01280 return same_edge;
01281 }
01282
01283
01284 #define isSameEdge isSameEdge_Optimized
01285
01286 bool CCorefine3d::areFacesLinked(CDart * AFace1, CDart * AFace2)
01287 {
01288 assert(FMap->isMarked(AFace1, FOrientMark));
01289 assert(FMap->isMarked(AFace2, FOrientMark));
01290
01291 return (isSameEdge(AFace1, AFace2) ||
01292 isSameEdge(AFace1, a3(a1(AFace2))) ||
01293 isSameEdge(a3(a1(AFace1)), AFace2) ||
01294 isSameEdge(a3(a1(AFace1)), a3(a1(AFace2))));
01295 }
01296
01297
01298
01299 CEdgeIntersection
01300 CCorefine3d::findNearestIntersectionInGrid(const CVertex & AVertex1,
01301 const CVertex & AVertex2)
01302 {
01303 ENTER;
01304
01305 CEdgeIntersection inter;
01306 TPositionOnEdge pos;
01307 TCoordinate t1 = 0.0, t2 = 0.0;
01308 CVertex *pt1, *pt2, pt;
01309 CPlane plane;
01310 CBoundingBox line_bb(AVertex1, AVertex2);
01311 CDart *face;
01312 int mark = FMap->getNewMark();
01313 int edge_mark = FMap->getNewMark();
01314 int face_mark = FMap->getNewMark();
01315
01316 MSG("mark = " << mark);
01317 MSG("edge_mark = " << edge_mark);
01318 MSG("face_mark = " << face_mark);
01319
01320 TFaceGridIter gi(*FGrid, line_bb);
01321 list<CDart*>::iterator li;
01322
01323 inter.setCell(NULL);
01324 inter.setPosition(EP_OutOfEdge);
01325 inter.setParameter(1.0);
01326
01327 MSG("Recherche d'une éventuelle intersection avec les sommets");
01328
01329 for (gi.reinit(); gi.cont(); ++gi) {
01330 for (li = (*gi)->begin(); li != (*gi)->end(); ++li) {
01331 for (CDynamicCoverageFace dcf(FMap, *li); dcf.cont(); ++dcf) {
01332 if (!FMap->isMarked(*dcf, mark) && FMap->isMarked(*dcf, FOrientMark)) {
01333
01334 FMap->markOrbit(*dcf, ORBIT_VERTEX, mark);
01335
01336 pt = *getVertex(*dcf);
01337
01338 if (line_bb.isInBox(pt)) {
01339 pos = FTools.localizePointOnEdge(pt, AVertex1, AVertex2, &t2);
01340
01341 if ((pos == EP_OnEdge && t2 < inter.getParameter()) ||
01342 (pos == EP_OnSecondVertex && t2 <= inter.getParameter())) {
01343 MSG("Une intersection trouvée avec le sommet " << pt);
01344
01345 inter.setCell(*dcf);
01346 inter.setCellDimension(0);
01347 inter.setPosition(pos);
01348 inter.setPoint(pt);
01349 inter.setParameter(t2);
01350 }
01351
01352 if (pos != EP_OutOfEdge) {
01353 for (CDynamicCoverageVertex dcv(FMap, *dcf); dcv.cont(); ++dcv) {
01354
01355 if (!FMap->isMarked(*dcv, edge_mark))
01356 FMap->markOrbit(*dcv, ORBIT_EDGE, edge_mark);
01357
01358
01359 if (!FMap->isMarked(*dcv, face_mark))
01360 FMap->markOrbit(*dcv, ORBIT_FACE, face_mark);
01361 }
01362 }
01363 }
01364 }
01365 }
01366 }
01367 }
01368
01369 MSG("Recherche d'une éventuelle intersection avec les arêtes");
01370
01371 for (gi.reinit(); gi.cont(); ++gi) {
01372 for (li = (*gi)->begin(); li != (*gi)->end(); ++li) {
01373 for (CDynamicCoverageFace dcf(FMap, *li); dcf.cont(); ++dcf) {
01374 if (FMap->isMarked(*dcf, edge_mark)) {
01375 FMap->unmarkOrbit(*dcf, ORBIT_EDGE, edge_mark);
01376 FMap->unmarkOrbit(*dcf, ORBIT_EDGE, mark);
01377 }
01378 else if (FMap->isMarked(*dcf, mark) &&
01379
01380 FMap->isMarked(*dcf, FOrientMark)) {
01381 FMap->unmarkOrbit(*dcf, ORBIT_EDGE, mark);
01382
01383 pt1 = getVertex(*dcf);
01384 pt2 = getVertex(a0(*dcf));
01385
01386 if (CBoundingBox(*pt1, *pt2) * line_bb) {
01387 pos = FTools.localizeEdgesIntersection(*pt1, *pt2,
01388 AVertex1, AVertex2,
01389 &t1, &t2);
01390
01391 pt = *pt1 + t1 * (*pt2 - *pt1);
01392
01393 if (
01394
01395
01396 (t1 >= 0.0 && t1 <= 1.0)) {
01397 if ((pos == EP_OnEdge && t2 < inter.getParameter()) ||
01398 (pos == EP_OnSecondVertex && t2 <= inter.getParameter())) {
01399 MSG("Une intersection trouvée avec l'arête "
01400 << "[" << *pt1 << "," << *pt2 << "]");
01401
01402 inter.setCell(*dcf);
01403 inter.setCellDimension(1);
01404 inter.setPosition(pos);
01405 inter.setPoint(pt);
01406 inter.setParameter(t2);
01407 }
01408
01409 if (pos != EP_OutOfEdge) {
01410 for (CDynamicCoverageEdge dce(FMap, *dcf); dce.cont(); ++dce) {
01411
01412 if (!FMap->isMarked(*dce, face_mark))
01413 FMap->markOrbit(*dce, ORBIT_FACE, face_mark);
01414 }
01415 }
01416 }
01417 }
01418 }
01419 }
01420 }
01421 }
01422
01423 MSG("Recherche d'une éventuelle intersection avec les faces");
01424
01425 for (gi.reinit(); gi.cont(); ++gi) {
01426 for (li = (*gi)->begin(); li != (*gi)->end(); ++li) {
01427 if (FMap->isMarked(*li, face_mark)) {
01428 FMap->unmarkOrbit(*li, ORBIT_FACE, face_mark);
01429 FMap->markOrbit(*li, ORBIT_FACE, mark);
01430 }
01431 else if (!FMap->isMarked(*li, mark)) {
01432 face = (FMap->isMarked(*li, FOrientMark)) ? *li : a3(*li);
01433 FMap->markOrbit(face, ORBIT_FACE, mark);
01434
01435
01436 plane = FTools.facePlane(face, FVertexDI);
01437
01438 pos = FTools.localizeEdgeAndPlaneIntersection(AVertex1, AVertex2,
01439 plane, &t2);
01440
01441 pt = AVertex1 + t2 * (AVertex2 - AVertex1);
01442
01443 if (
01444
01445
01446 FTools.isPointInFace(pt, face, &plane, FVertexDI) &&
01447 ((pos == EP_OnEdge && t2 < inter.getParameter()) ||
01448 (pos == EP_OnSecondVertex && t2 <= inter.getParameter()))) {
01449 MSG("Une intersection avec une face trouvée");
01450
01451 inter.setCell(face);
01452 inter.setCellDimension(2);
01453 inter.setPosition(pos);
01454 inter.setPoint(pt);
01455 inter.setParameter(t2);
01456 }
01457
01458 }
01459 }
01460 }
01461
01462 MSG("Démarquage des faces");
01463
01464 for (gi.reinit(); gi.cont(); ++gi)
01465 for (li = (*gi)->begin(); li != (*gi)->end(); ++li)
01466 for (CDynamicCoverageFace dcf(FMap, *li); dcf.cont(); ++dcf)
01467 if (FMap->isMarked(*dcf, mark))
01468 FMap->unmarkOrbit(*dcf, ORBIT_VERTEX, mark);
01469
01470 FMap->freeMark(mark);
01471 FMap->freeMark(edge_mark);
01472 FMap->freeMark(face_mark);
01473
01474 EXIT;
01475
01476 return inter;
01477 }
01478
01479
01480
01481 CDart *
01482 CCorefine3d::findFirstIntersectionInGrid(const CVertex & AVertex, int * ADim)
01483 {
01484 ENTER;
01485
01486 CVertex pt1, pt2, pt;
01487 CDart *face, *result = NULL;
01488 CPlane plane;
01489 TCoordinate t;
01490 int mark = FMap->getNewMark();
01491
01492 MSG("mark = " << mark);
01493
01494 TFaceGridIter gi(*FGrid, CBoundingBox(AVertex));
01495 list<CDart*>::iterator li;
01496
01497
01498 for (gi.reinit(); gi.cont() && !result; ++gi)
01499 for (li = (*gi)->begin(); li != (*gi)->end() && !result; ++li)
01500 for (CDynamicCoverageFace dcf(FMap, *li); dcf.cont() && !result; ++dcf)
01501 if (!FMap->isMarked(*dcf, mark) && FMap->isMarked(*dcf, FOrientMark)) {
01502
01503 FMap->markOrbit(*dcf, ORBIT_VERTEX, mark);
01504
01505 pt = *getVertex(*dcf);
01506
01507 if (FTools.arePointsEqual(AVertex, pt)) {
01508 MSG("Une intersection trouvée avec le sommet " << pt);
01509 result = *dcf;
01510 *ADim = 0;
01511 }
01512 }
01513
01514
01515 for (gi.reinit(); gi.cont() && !result; ++gi)
01516 for (li = (*gi)->begin(); li != (*gi)->end() && !result; ++li)
01517 for (CDynamicCoverageFace dcf(FMap, *li); dcf.cont() && !result; ++dcf)
01518 if (FMap->isMarked(*dcf, mark) && FMap->isMarked(*dcf, FOrientMark)) {
01519 FMap->unmarkOrbit(*dcf, ORBIT_EDGE, mark);
01520
01521 pt1 = *getVertex(*dcf);
01522 pt2 = *getVertex(a0(*dcf));
01523
01524 if (FTools.isPointOnLine(AVertex, pt1, pt2)) {
01525 t = FTools.pointParameterOnLine(AVertex, pt1, pt2);
01526
01527 if (t >= 0.0 && t <= 1.0) {
01528 MSG("Une intersection trouvée avec l'arête "
01529 << "[" << pt1 << "," << pt2 << "]");
01530 result = *dcf;
01531 *ADim = 1;
01532 }
01533 }
01534 }
01535
01536
01537 for (gi.reinit(); gi.cont() && !result; ++gi)
01538 for (li = (*gi)->begin(); li != (*gi)->end() && !result; ++li)
01539 if (!FMap->isMarked(*li, mark)) {
01540 face = (FMap->isMarked(*li, FOrientMark)) ? *li : a3(*li);
01541 FMap->markOrbit(face, ORBIT_FACE, mark);
01542
01543 plane = FTools.facePlane(face, FVertexDI);
01544
01545 if (FTools.isPointOnPlane(AVertex, plane) &&
01546 FTools.isPointInFace(AVertex, face, &plane, FVertexDI)) {
01547 MSG("Une intersection avec une face trouvée");
01548 result = face;
01549 *ADim = 2;
01550 }
01551 }
01552
01553 for (gi.reinit(); gi.cont(); ++gi)
01554 for (li = (*gi)->begin(); li != (*gi)->end(); ++li)
01555 for (CDynamicCoverageFace dcf(FMap, *li); dcf.cont(); ++dcf)
01556 if (FMap->isMarked(*dcf, mark))
01557 FMap->unmarkOrbit(*dcf, ORBIT_VERTEX, mark);
01558
01559 FMap->freeMark(mark);
01560
01561 EXIT;
01562
01563 return result;
01564 }
01565
01566
01567
01568 void CCorefine3d::followIntersection(CDart * AVertex1, CDart * AVertex2,
01569 int AMark)
01570 {
01571 ENTER;
01572
01573
01574
01575
01576
01577
01578
01579 assert(FMap->isMarked(AVertex1, FOrientMark));
01580 assert(FMap->isMarked(AVertex2, FOrientMark));
01581
01582 list<CDart*> inter_list;
01583 CDart *d1, *d2, *current, *first, *last;
01584 bool ok;
01585 int mark = FMap->getNewMark();
01586 CTime start, end;
01587 int nb_vertices = 0;
01588 CPlane plane1, plane2;
01589
01590 MSG("mark = " << mark);
01591
01592 FNumberOfIntersectionLines++;
01593
01594 cout << "--> Suivi d'une ligne de coupe" << endl;
01595 start.updateTime();
01596
01597 SAVE_POINT(*getVertex(AVertex1));
01598
01599 inter_list.push_back(AVertex1);
01600 inter_list.push_back(AVertex2);
01601 while (!inter_list.empty()) {
01602 d1 = inter_list.front(), inter_list.pop_front();
01603 d2 = inter_list.front(), inter_list.pop_front();
01604
01605 nb_vertices++;
01606
01607 for (CStaticCoverageVertex dcv1(FMap, d1); dcv1.cont(); ++dcv1)
01608 if (!FMap->isMarked(*dcv1, mark) &&
01609 FMap->isMarked(*dcv1, FOrientMark)) {
01610 FMap->markOrbit(*dcv1, ORBIT_13, mark);
01611
01612 first = *dcv1;
01613 last = FTools.alpha2(a1(*dcv1));
01614
01615 for (CStaticCoverageVertex dcv2(FMap, d2); dcv2.cont(); ++dcv2)
01616 if (!FMap->isMarked(*dcv2, mark) &&
01617 FMap->isMarked(*dcv2, FOrientMark)) {
01618 FMap->markOrbit(*dcv2, ORBIT_13, mark);
01619
01620
01621
01622
01623
01624 ok = false;
01625 current = first;
01626 do {
01627 plane1 = FTools.facePlane(current, FVertexDI);
01628 plane2 = FTools.facePlane(*dcv2, FVertexDI);
01629
01630 if (!areFacesLinked(current, *dcv2)) {
01631 if ((plane1.getNormal() * plane2.getNormal()).norm() > FEps) {
01632 ok = manageFacesIntersection(current, plane1,
01633 *dcv2, plane2,
01634 AMark, &inter_list);
01635 }
01636 else {
01637 WARN_BB("<followIntersection> Faces coplanaires !");
01638 }
01639 }
01640
01641 current = FTools.alpha2(a1(current));
01642 }
01643 while (current != last && !ok);
01644 }
01645
01646 FMap->unmarkOrbit(d2, ORBIT_VERTEX, mark);
01647 }
01648
01649 FMap->markOrbit(d1, ORBIT_VERTEX, AMark);
01650 FMap->unmarkOrbit(d1, ORBIT_VERTEX, mark);
01651 }
01652
01653 FMap->freeMark(mark);
01654
01655 end.updateTime();
01656
01657 cout << " Durée du suivi : " << end - start << endl;
01658 FLineCreationTime += end - start;
01659
01660
01661
01662
01663
01664
01665
01666
01667 EXIT;
01668 }
01669
01670
01671
01672 bool CCorefine3d::manageFacesIntersection(CDart * AFace1,
01673 const CPlane & APlane1,
01674 CDart * AFace2,
01675 const CPlane & APlane2,
01676 int AMark,
01677 list<CDart*> * AList)
01678 {
01679 ENTER;
01680
01681 assert(FMap->isMarked(AFace1, FOrientMark));
01682 assert(FMap->isMarked(AFace2, FOrientMark));
01683
01684 CEdgeIntersection inter1, inter2;
01685 CVertex pt, dir;
01686 bool result = false;
01687
01688 #ifdef DEBUG_MESSAGES
01689 FTools.displayFaceVertices(AFace1, FVertexDI);
01690 FTools.displayFaceVertices(AFace2, FVertexDI);
01691 #endif
01692
01693 if (FTools.isVectorNull(APlane1.getNormal())) {
01694 cout << "\033[1;34m";
01695 FTools.displayFaceVertices(AFace1, FVertexDI);
01696 cout << "<manageFacesIntersection> La normale à la face 1 est nulle : "
01697 << APlane1.getNormal() << "\033[0m\n";
01698 }
01699 if (FTools.isVectorNull(APlane2.getNormal())) {
01700 cout << "\033[1;34m";
01701 FTools.displayFaceVertices(AFace2, FVertexDI);
01702 cout << "<manageFacesIntersection> La normale à la face 2 est nulle : "
01703 << APlane2.getNormal() << "\033[0m\n";
01704 }
01705
01706 pt = *getVertex(AFace1);
01707
01708
01709 dir = APlane1.getNormal() * APlane2.getNormal();
01710
01711
01712
01713 if (!FTools.isVectorInSector(dir, AFace1, APlane1, true, FVertexDI) ||
01714 !FTools.isVectorInSector(dir, AFace2, APlane2, true, FVertexDI))
01715 dir = -dir;
01716
01717 if (FTools.isVectorInSector(dir, AFace1, APlane1, true, FVertexDI) &&
01718 FTools.isVectorInSector(dir, AFace2, APlane2, true, FVertexDI)) {
01719 MSG("Ligne de coupe = (" << pt << "," << pt + dir << ")");
01720
01721
01722 inter1 = FTools.findNearestIntersectionInFace(pt, dir, AFace1, APlane1,
01723 true, FVertexDI);
01724 inter2 = FTools.findNearestIntersectionInFace(pt, dir, AFace2, APlane2,
01725 true, FVertexDI);
01726
01727 if (inter1.getCell() != AFace1 && inter2.getCell() != AFace2) {
01728 if (inter1.getCell() != NULL && inter2.getCell() != NULL) {
01729 createIntersectionEdge(AFace1, AFace2, APlane1, APlane2,
01730 inter1, inter2, AMark, AList);
01731 result = true;
01732 }
01733 }
01734 else {
01735 WARN_BB("<manageFacesIntersection> Intersections trouvées invalides !");
01736 }
01737 }
01738
01739 EXIT;
01740
01741 return result;
01742 }
01743
01744
01745 #define sortFacesAroundEdges sortFacesAroundEdges_SuperNaive
01746
01747 void CCorefine3d::createIntersectionEdge(CDart * AFace1, CDart * AFace2,
01748 const CPlane & APlane1,
01749 const CPlane & APlane2,
01750 const CEdgeIntersection & AInter1,
01751 const CEdgeIntersection & AInter2,
01752 int AMark, list<CDart*> * AList)
01753 {
01754 ENTER;
01755
01756 CDart *d1, *d2, *edge1, *edge2;
01757 bool add_to_list = true;
01758 CVertex pt;
01759
01760 removeFaceFromGrid(FGrid, AFace2);
01761
01762
01763 if (FTools.arePointsEqual(AInter1.getPoint(), AInter2.getPoint())) {
01764 MSG("L'intersection sur chaque face se trouve à égale distance");
01765
01766 pt = (AInter1.getPoint() + AInter2.getPoint()) / 2.0;
01767
01768 if (AInter1.getCellDimension() == 0) {
01769 d1 = AInter1.getCell();
01770 *getVertex(AInter1.getCell()) = pt;
01771 }
01772 else
01773 d1 = splitEdge(AInter1.getCell(), pt);
01774
01775 if (AInter2.getCellDimension() == 0) {
01776 d2 = AInter2.getCell();
01777 *getVertex(AInter2.getCell()) = pt;
01778 }
01779 else
01780 d2 = splitEdge(AInter2.getCell(), pt);
01781
01782 if (FMap->isMarked(d1, AMark))
01783 add_to_list = false;
01784
01785 edge1 = splitFace(AFace1, d1);
01786 edge2 = splitFace(AFace2, d2);
01787
01788
01789
01790
01791
01792
01793
01794
01795 SAVE_POINT(pt);
01796 }
01797
01798 else if (AInter1.getParameter() < AInter2.getParameter()) {
01799 MSG("L'intersection la plus proche se trouve sur la même face");
01800
01801 if (AInter1.getCellDimension() == 0)
01802 d1 = AInter1.getCell();
01803 else
01804 d1 = splitEdge(AInter1.getCell(), AInter1.getPoint());
01805
01806 pt = getProjectionOnPlane(d1, APlane2);
01807 *getVertex(d1) = pt;
01808
01809 if (FMap->isMarked(d1, AMark))
01810 add_to_list = false;
01811
01812 edge1 = splitFace(AFace1, d1);
01813 edge2 = insertEdgeInFace(AFace2, pt);
01814
01815 d2 = a1(a0(edge2));
01816
01817
01818
01819
01820
01821
01822
01823
01824 SAVE_POINT(pt);
01825 }
01826
01827 else {
01828 MSG("L'intersection la plus proche se trouve sur l'autre face");
01829
01830 if (AInter2.getCellDimension() == 0)
01831 d2 = AInter2.getCell();
01832 else
01833 d2 = splitEdge(AInter2.getCell(), AInter2.getPoint());
01834
01835 pt = getProjectionOnPlane(d2, APlane1);
01836 *getVertex(d2) = pt;
01837
01838 edge1 = insertEdgeInFace(AFace1, pt);
01839 edge2 = splitFace(AFace2, d2);
01840
01841 d1 = a1(a0(edge1));
01842
01843
01844
01845
01846
01847
01848 SAVE_POINT(pt);
01849 }
01850
01851 FMap->markOrbit(a0(edge1), ORBIT_VERTEX, AMark);
01852
01853 assert(FMap->isMarked(edge1, FOrientMark));
01854 assert(FMap->isMarked(edge2, FOrientMark));
01855
01856 if (!isSameEdge(edge1, edge2)) {
01857 FNumberOfIntersectionEdges++;
01858
01859 MSG("Tri des faces autour de l'arête d'intersection n°"
01860 << FNumberOfIntersectionEdges);
01861
01862 FTools.sortFacesAroundEdges(edge1, edge2, FAlpha2DI, FVertexDI);
01863
01864 #ifdef EXTRACT_LINES //---------------------------------------------------------
01865 FMap->markOrbit(edge1, ORBIT_EDGE, FIntersectionMark);
01866 FMap->markOrbit(edge2, ORBIT_EDGE, FIntersectionMark);
01867 #endif // EXTRACT_LINES --------------------------------------------------------
01868 }
01869
01870 if (getFace(edge2) == getFace(a2(edge2))) {
01871 addFaceToGrid(FGrid, edge2);
01872 }
01873 else {
01874 addFaceToGrid(FGrid, edge2);
01875 addFaceToGrid(FGrid, a2(edge2));
01876 }
01877
01878 if (add_to_list) {
01879 AList->push_back(d1);
01880 AList->push_back(d2);
01881 }
01882
01883 #ifdef FOLLOW_DEBUG_MODE //-----------------------------------------------------
01884 CGMapVertex * tmp_map = new CGMapVertex;
01885 char file_name[1024] = "\0";
01886
01887 sprintf(file_name, "edge%04u.map", FNumberOfIntersectionEdges);
01888
01889 d1 = tmp_map->addMapDart();
01890 d2 = tmp_map->addMapDart();
01891
01892 tmp_map->linkAlpha0(d1, d2);
01893
01894 tmp_map->setVertex(d1, *getVertex(edge1));
01895 tmp_map->setVertex(d2, *getVertex(a0(edge1)));
01896
01897 tmp_map->save(file_name, AsciiFormat);
01898
01899 delete tmp_map;
01900 #endif // FOLLOW_DEBUG_MODE ----------------------------------------------------
01901
01902 EXIT;
01903 }
01904
01905 #undef sortFacesAroundEdges
01906
01907
01908 void CCorefine3d::applyModifications(CDart * AMesh)
01909 {
01910 ENTER;
01911
01912 CDart *d;
01913
01914 for (CStaticCoverageCC scc(FMap, AMesh); scc.cont(); ++scc) {
01915 d = (CDart*)FMap->getDirectInfo(*scc, FAlpha2DI);
01916
01917 if (d != NULL) {
01918 if (!FMap->isFree2(*scc))
01919 FMap->unsew2(*scc);
01920 if (!FMap->isFree2(d))
01921 FMap->unsew2(d);
01922
01923 FMap->sew2(*scc, d);
01924
01925 FMap->setDirectInfo(*scc, FAlpha2DI, NULL);
01926 FMap->setDirectInfo(a0(*scc), FAlpha2DI, NULL);
01927 FMap->setDirectInfo(d, FAlpha2DI, NULL);
01928 FMap->setDirectInfo(a0(d), FAlpha2DI, NULL);
01929 }
01930 }
01931
01932 EXIT;
01933 }
01934
01935
01936 #define COPY(d) ((CDart*)FMap->getDirectInfo(d, copy_direct_info))
01937
01938 void CCorefine3d::extractIntersectionLines(CDart * AMesh)
01939 {
01940 ENTER;
01941
01942 int copy_direct_info = FMap->getNewDirectInfo();
01943 CDart *d;
01944 CDynamicCoverageCC dcc(FMap, AMesh);
01945
01946
01947 for (dcc.reinit(); dcc.cont(); ++dcc) {
01948 if (FMap->isMarked(*dcc, FIntersectionMark)) {
01949 FMap->setDirectInfo(*dcc, copy_direct_info, FMap->addMapDart());
01950 FMap->setMark(COPY(*dcc), FIntersectionMark);
01951
01952 }
01953 }
01954
01955
01956 for (dcc.reinit(); dcc.cont(); ++dcc) {
01957 if (FMap->isMarked(*dcc, FIntersectionMark)) {
01958 if (FMap->canSew0(COPY(*dcc), COPY(a0(*dcc))))
01959 FMap->sew0(COPY(*dcc), COPY(a0(*dcc)));
01960
01961 d = a1(*dcc);
01962 while (!FMap->isMarked(d, FIntersectionMark))
01963 d = a1(a2(d));
01964
01965 if (FMap->canSew1(COPY(*dcc), COPY(d)))
01966 FMap->sew1(COPY(*dcc), COPY(d));
01967 }
01968 }
01969
01970
01971 for (dcc.reinit(); dcc.cont(); ++dcc) {
01972 if (FMap->isMarked(*dcc, FIntersectionMark)) {
01973 if (FMap->canSew2(COPY(*dcc), COPY(a2(*dcc))))
01974 FMap->sew2(COPY(*dcc), COPY(a2(*dcc)));
01975 if (FMap->canSew3(COPY(*dcc), COPY(a3(*dcc))))
01976 FMap->sew3(COPY(*dcc), COPY(a3(*dcc)));
01977 }
01978 }
01979
01980
01981 for (dcc.reinit(); dcc.cont(); ++dcc) {
01982 if (FMap->isMarked(COPY(*dcc), FIntersectionMark)&&
01983 FMap->isMarked(COPY(*dcc), FIntersectionMark)) {
01984 FMap->unmarkOrbit(COPY(*dcc), ORBIT_VERTEX, FIntersectionMark);
01985 FMap->setVertex(COPY(*dcc), *FMap->findVertex(*dcc));
01986 }
01987 }
01988
01989 FMap->freeDirectInfo(copy_direct_info);
01990
01991 EXIT;
01992 }
01993
01994 #undef COPY
01995
01996
01997 #undef a0
01998 #undef a1
01999 #undef a2
02000 #undef a3
02001
02002