00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "corefine-2d-sweeping.hh"
00026 #include "g-map-vertex.hh"
00027 #include "geometry.hh"
00028 #include <cassert>
00029 using namespace GMap3d;
00030 using namespace std;
00031
00032 CCorefineSegmentsSweeping::CCorefineSegmentsSweeping(CGMapVertex* AMap) :
00033 FMap(AMap)
00034 {
00035 assert(FMap != NULL);
00036 }
00037
00038 CCorefineSegmentsSweeping::~CCorefineSegmentsSweeping()
00039 {
00040 }
00041
00042 #define GET_V(DART) FMap->getDirectInfoAsAttributeVertex((DART), directVertex)
00043
00044 #define IT_PRED(IT,SET) (((IT)==(SET).begin()) \
00045 ? NULL \
00046 : * (--(IT), (IT)++))
00047
00048 #define IT_SUCC(IT,SET) (++(IT), \
00049 ((IT)==(SET).end()) \
00050 ? (--(IT), (CDartVertex *) NULL) \
00051 : (*((IT)--)))
00052
00053 void CCorefineSegmentsSweeping::corefine(CDart* ADart1, CDart* ADart2,
00054 const CVertex& ANormalVector)
00055 {
00056 assert(ADart1 != NULL);
00057 assert(ADart2 != NULL);
00058 assert(FMap->isIFreeOrbit(ADart1, 3, ORBIT_CC));
00059 assert(FMap->isIFreeOrbit(ADart2, 3, ORBIT_CC));
00060 assert(!ANormalVector.isNull());
00061
00062 if (FMap->isSameOrbit(ADart1, ADart2, ORBIT_CC))
00063 return;
00064
00065
00066 int treated = FMap->getNewMark();
00067
00068 int directVertex = FMap->getNewDirectInfo();
00069 int mesh1 = FMap->getNewMark();
00070 int extremity1 = FMap->getNewMark();
00071
00072 CDart* dart;
00073
00074
00075 for (dart = ADart1; dart!=NULL; dart = dart==ADart1 ? ADart2 : NULL)
00076 {
00077 for (CDynamicCoverageCC cov(FMap, dart); cov.cont(); ++cov)
00078 if (FMap->isFree2(*cov))
00079 FMap->stopUp(*cov, 2);
00080 }
00081
00082
00083 FMap->pointDirectInfoToAttributeVertex(directVertex);
00084 FMap->markOrbit(ADart1, ORBIT_CC, mesh1);
00085
00086
00087 CDartLexicoCompare lexComparator(FMap, directVertex,
00088 extremity1, ANormalVector,
00089 true );
00090
00091 LEX_SET eventSet(lexComparator);
00092
00093 for (dart = ADart1; dart!=NULL; dart = dart==ADart1 ? ADart2 : NULL)
00094 {
00095 for (CDynamicCoverageCC cov(FMap, dart); cov.cont(); ++cov)
00096 if (! FMap->isMarked(*cov, treated))
00097 {
00098 FMap->markOrbit(*cov, ORBIT_02, treated);
00099
00100 if (! FMap->isFree0(*cov))
00101 {
00102 if (lexComparator((CDartVertex*) *cov,
00103 (CDartVertex*) FMap->alpha0(*cov)))
00104 FMap->setMark( *cov , extremity1);
00105 else
00106 FMap->setMark(FMap->alpha0(*cov), extremity1);
00107
00108 eventSet.insert((CDartVertex*) *cov );
00109 eventSet.insert((CDartVertex*) FMap->alpha0(*cov));
00110 }
00111 }
00112
00113 FMap->unmarkOrbit(dart, ORBIT_CC, treated);
00114 }
00115
00116
00117 LEX_SET eventTreatedSet(lexComparator);
00118
00119 CDartVertexerticalCompare
00120 vertComparator(FMap, directVertex, extremity1, ANormalVector);
00121
00122 VERT_SET sweepingSet(vertComparator);
00123
00124 while (eventSet.begin()!=eventSet.end())
00125 {
00126 CDartVertex* current = * eventSet.begin();
00127
00128 vertComparator.setCurrentPoint(* GET_V(current));
00129
00130 if (FMap->isMarked(current, extremity1))
00131 {
00132
00133
00134 VERT_IT currentPos = sweepingSet.insert((CDartVertex *) current);
00135 assert(sweepingSet.find((CDartVertex *) current) != sweepingSet.end());
00136
00137
00138 CDart * neighbors[2];
00139
00140 neighbors[0] = IT_PRED(currentPos, sweepingSet);
00141 neighbors[1] = IT_SUCC(currentPos, sweepingSet);
00142
00143
00144 for (int i=0; i<2; ++i)
00145 manageEdgesIntersection(current, neighbors[i], eventSet,
00146 lexComparator, sweepingSet, extremity1,
00147 mesh1, directVertex, ANormalVector);
00148 }
00149 else
00150 {
00151
00152 assert(lexComparator((CDartVertex*) FMap->alpha0(current),
00153 (CDartVertex*) current));
00154
00155 VERT_IT it =
00156 findElementInSweepingSet(sweepingSet, FMap->alpha0(current));
00157
00158
00159 CDart* neighbors[2];
00160
00161 neighbors[0] = IT_PRED(it, sweepingSet);
00162 neighbors[1] = IT_SUCC(it, sweepingSet);
00163
00164
00165 manageEdgesIntersection(neighbors[0], neighbors[1], eventSet,
00166 lexComparator, sweepingSet, extremity1,
00167 mesh1, directVertex, ANormalVector);
00168
00169
00170
00171 sweepingSet.erase(it);
00172 }
00173
00174
00175 eventTreatedSet.insert(current);
00176 eventSet.erase(current);
00177 }
00178
00179 eventTreatedSet.swap(eventSet);
00180
00181
00182 int exterior = FMap->getNewMark();
00183
00184 CDart* darts[2] = { ADart1, ADart2 };
00185
00186 for (int i=0; i<2; ++i)
00187 {
00188 if (CGeometry::getAngle(FMap->cellDimensionNormalVector(darts[i], 3),
00189 ANormalVector) > 90)
00190 {
00191 FMap->markOrbit (darts[i], ORBIT_CC, exterior);
00192 FMap->halfUnmarkOrbit(darts[i], ORBIT_CC, exterior);
00193 }
00194 else
00195 FMap->halfMarkOrbit(darts[i], ORBIT_CC, exterior);
00196 }
00197
00198
00199
00200 CDartLexicoCompare
00201 lexComparator2(FMap, directVertex,
00202 extremity1, ANormalVector,
00203 false );
00204
00205 LEX_SET eventSet2(lexComparator2);
00206 LEX_IT it;
00207
00208 for (it = eventSet.begin(); it!=eventSet.end(); ++it)
00209 eventSet2.insert(*it);
00210
00211
00212 CDartAngularCompare
00213 angComparator(FMap, directVertex, ANormalVector);
00214
00215 for (it = eventSet2.begin(); it!=eventSet2.end(); )
00216 {
00217 const CAttributeVertex & currentVertex = * GET_V(*it);
00218 bool uniqueTopoVertex = true;
00219
00220 LEX_IT first = it++;
00221
00222 while (it!=eventSet2.end() && * GET_V(*it) == currentVertex)
00223 {
00224 if (GET_V(*it) != ¤tVertex)
00225 uniqueTopoVertex = false;
00226
00227 ++it;
00228 }
00229
00230 if (!uniqueTopoVertex)
00231 {
00232 ANG_SET angSet(angComparator);
00233
00234
00235 for (LEX_IT local = first; local!=it; ++local)
00236 {
00237 CDart * current = *local;
00238
00239 assert(! FMap->isFree2(current));
00240
00241 if (! FMap->isMarked(current, exterior))
00242 current = FMap->alpha2(current);
00243
00244 assert(FMap->isMarked(current, exterior));
00245 assert(FMap->findVertex(current) == GET_V(current));
00246
00247 angSet.insert((CDartVertex*) current);
00248 }
00249
00250
00251 ANG_IT round = angSet.end();
00252 CDart* pred = *(--round);
00253
00254 for (round = angSet.begin(); round!=angSet.end(); ++round)
00255 {
00256 if (! FMap->isFree1(FMap->alpha2(pred)))
00257 FMap->unsew1(FMap->alpha2(pred));
00258
00259 if (! FMap->isFree1(*round))
00260 FMap->unsew1(*round);
00261
00262 assert(FMap->isMarked(FMap->alpha2(pred), exterior) !=
00263 FMap->isMarked(*round, exterior));
00264
00265 FMap->sew1(FMap->alpha2(pred), *round);
00266 pred = *round;
00267 }
00268
00269
00270 FMap->pointDirectInfoToAttributeVertex(directVertex, pred);
00271 }
00272 }
00273
00274
00275 int toDelete = FMap->getNewMark();
00276
00277 CDynamicCoverageAll itAll(FMap);
00278
00279 for (; itAll.cont(); ++itAll)
00280 if (! FMap->isMarked(*itAll, toDelete) &&
00281 ! FMap->isFree0(*itAll) && ! FMap->isFree1(*itAll) &&
00282 (GET_V(FMap->alpha0(*itAll)) == GET_V(FMap->alpha10(*itAll))))
00283 {
00284 if (FMap->alpha01(*itAll) != FMap->alpha10(*itAll))
00285 {
00286
00287 CDart* d0 = FMap->alpha0 (*itAll); FMap->unsew0(d0 );
00288 CDart* d10 = FMap->alpha10(*itAll); FMap->unsew0(d10);
00289
00290 FMap->sew0( *itAll , FMap->alpha2(d10));
00291 FMap->sew0(FMap->alpha1(*itAll), FMap->alpha2(d0 ));
00292 }
00293
00294 assert(FMap->alpha01(*itAll) == FMap->alpha10(*itAll));
00295
00296
00297 CDart* d2 = FMap->alpha2 (*itAll); FMap->unsew2(d2 );
00298 CDart* d12 = FMap->alpha12(*itAll); FMap->unsew2(d12);
00299
00300 FMap->sew2(d2, d12);
00301
00302 FMap->markOrbit(*itAll, ORBIT_FACE, toDelete);
00303 }
00304
00305
00306 for (itAll.reinit(); itAll.cont(); )
00307 {
00308 CDart * current = itAll++;
00309
00310 if (FMap->isMarked(current, toDelete))
00311 FMap->delMapDart(current);
00312 }
00313
00314 FMap->freeMark(toDelete);
00315
00316
00317 FMap->freeMark(treated);
00318 FMap->freeDirectInfo(directVertex);
00319
00320 FMap->unmarkAll(mesh1);
00321 FMap->freeMark(mesh1);
00322
00323 FMap->unmarkAll(exterior);
00324 FMap->freeMark(exterior);
00325
00326 FMap->unmarkAll(extremity1);
00327 FMap->freeMark(extremity1);
00328 }
00329
00330 #undef GET_V
00331 #undef IT_PRED
00332 #undef IT_SUCC
00333
00334 VERT_IT CCorefineSegmentsSweeping::
00335 findElementInSweepingSet(VERT_SET & ASweepingSet, CDart * AElement)
00336 {
00337 assert(AElement != NULL);
00338
00339 VERT_IT it = ASweepingSet.find((CDartVertex *) AElement);
00340
00341 if (it == ASweepingSet.end())
00342 {
00343 cout << "Élément introuvable: " << AElement << "!" << endl;
00344 it = ASweepingSet.begin();
00345 while (it != ASweepingSet.end() && *it != AElement)
00346 ++it;
00347
00348 if (it==ASweepingSet.end())
00349 {
00350 cout << * (CVertex*) FMap->findVertex( AElement ) << endl;
00351 cout << * (CVertex*) FMap->findVertex(FMap->alpha0(AElement)) << endl;
00352 }
00353
00354 assert(it != ASweepingSet.end());
00355 }
00356
00357 return it;
00358 }
00359
00360 #define GET_V(DART) FMap->getDirectInfoAsAttributeVertex((DART), ADirectVertex)
00361
00362 void CCorefineSegmentsSweeping::
00363 manageEdgesIntersection(CDart * ADart1, CDart * ADart2,
00364 LEX_SET & AEventSet,
00365 const CDartLexicoCompare& ALexComparator,
00366 VERT_SET & ,
00367 int AExtremity1, int AMesh1, int ADirectVertex,
00368 const CVertex & ANormalVector)
00369 {
00370 if (ADart1==NULL || ADart2==NULL)
00371 return;
00372
00373 if (FMap->isMarked(ADart1, AMesh1) == FMap->isMarked(ADart2, AMesh1))
00374 return;
00375
00376
00377 CAttributeVertex* A = GET_V( ADart1 );
00378 CAttributeVertex* B = GET_V(FMap->alpha0(ADart1));
00379
00380
00381 CAttributeVertex* C = GET_V( ADart2 );
00382 CAttributeVertex* D = GET_V(FMap->alpha0(ADart2));
00383
00384
00385 int cut[2];
00386 CDart* cutDart[2] = { ADart1, ADart2 };
00387 static CVertex intersections[2];
00388
00389 CGeometry::getSegmentsIntersection(*A,*B,*C,*D, ANormalVector,
00390 cut[0], intersections[0],
00391 cut[1], intersections[1]);
00392
00393 for (int i=1; i>=0; --i)
00394 if (cut[i]!=0)
00395 {
00396 CDart* toCut = cutDart[cut[i]-1];
00397
00398 assert(ALexComparator((CDartVertex*) toCut,
00399 (CDartVertex*) FMap->alpha0(toCut)));
00400
00401 FMap->CGMapGeneric::insertVertex(toCut);
00402 FMap->setVertex(FMap->alpha0(toCut), intersections[i]);
00403
00404 FMap->pointDirectInfoToAttributeVertex(ADirectVertex,
00405 FMap->alpha0(toCut));
00406
00407 FMap->setMark(FMap->alpha01(toCut), AExtremity1);
00408
00409 if (FMap->isMarked(toCut, AMesh1))
00410 FMap->markOrbit(FMap->alpha0(toCut), ORBIT_VERTEX, AMesh1);
00411
00412 AEventSet.insert((CDartVertex*) FMap->alpha0 (toCut));
00413 AEventSet.insert((CDartVertex*) FMap->alpha01(toCut));
00414
00415 assert(ALexComparator((CDartVertex*) toCut,
00416 (CDartVertex*) FMap->alpha0 (toCut)));
00417 assert(ALexComparator((CDartVertex*) FMap->alpha01 (toCut),
00418 (CDartVertex*) FMap->alpha010(toCut)));
00419 }
00420 }
00421
00422 #undef GET_V
00423