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 "g-map-generic.hh"
00026 using namespace GMap3d;
00027
00028
00029
00030
00031
00032
00033
00034
00035 int CGMapGeneric::getMergeDimension(CDart * ADart)
00036 {
00037 assert(ADart!=NULL);
00038
00039 if (!isFree3(ADart)) return 3;
00040 if (!isFree2(ADart)) return 2;
00041 if (!isFree1(ADart)) return 1;
00042 if (!isFree0(ADart)) return 0;
00043
00044 return -1;
00045 }
00046
00047 bool CGMapGeneric::canMerge(CDart * ADart1, CDart * ADart2, int ADim)
00048 {
00049 assert(ADart1!=NULL && ADart2!=NULL);
00050 assert(ADim>=1 || ADim<=3);
00051
00052
00053
00054
00055
00056 if (isSameOrbit(ADart1, ADart2, ORBIT_CELL[ADim-1]))
00057 {
00058 if (degree(ADart1, ADim-1) > 2)
00059 return false;
00060 }
00061 else
00062 {
00063 if (degree(ADart1, ADim-1) + degree(ADart2, ADim-1) > 2)
00064 return false;
00065 }
00066
00067
00068
00069 TOrbit halfCell = SUB_ORBIT(ORBIT_CC, ORBIT_I_IP1[ADim-1]);
00070
00071 CCoverage * cov1 = getDynamicCoverage(ADart1, halfCell);
00072 CCoverage * cov2 = getDynamicCoverage(ADart2, halfCell);
00073
00074 while (cov1->cont() && cov2->cont() &&
00075 cov1->prevOperationType()==cov2->prevOperationType())
00076 {
00077 ++(*cov1);
00078 ++(*cov2);
00079 }
00080
00081 bool ok = !cov1->cont() && !cov2->cont();
00082
00083 delete cov1;
00084 delete cov2;
00085
00086 return ok;
00087 }
00088
00089 void CGMapGeneric::merge(CDart * ADart1, CDart * ADart2, int ADim,
00090 bool ADeleteDarts)
00091 {
00092 assert(ADart1!=NULL && ADart2!=NULL);
00093 assert(ADim>=1 && ADim<=3);
00094 assert(canMerge(ADart1, ADart2, ADim));
00095
00096 TOrbit halfCell = SUB_ORBIT(ORBIT_CC, ORBIT_I_IP1[ADim-1]);
00097
00098 CCoverage * it1 = getStaticCoverage(ADart1, halfCell);
00099 CCoverage * it2 = getStaticCoverage(ADart2, halfCell);
00100
00101 for (; it1->cont(); ++(*it1), ++(*it2))
00102 {
00103 bool bothLinked = !isFree(**it1,ADim-1) && !isFree(**it2,ADim-1);
00104
00105 CDart * t1 = alpha(**it1, ADim-1);
00106 CDart * t2 = alpha(**it2, ADim-1);
00107
00108 if (!isFree(t1,ADim-1)) unsew(t1,ADim-1);
00109 if (!isFree(t2,ADim-1)) unsew(t2,ADim-1);
00110
00111 if (bothLinked)
00112 sew(t1,t2,ADim-1);
00113 }
00114
00115 if (ADeleteDarts)
00116 for (it1->reinit(), it2->reinit(); it1->cont(); )
00117 {
00118 delMapDart((*it1)++);
00119 delMapDart((*it2)++);
00120 }
00121
00122 delete it1;
00123 delete it2;
00124 }
00125
00126
00127 int CGMapGeneric::isolateMarkedCells(int AMarkNumber, int ADim,
00128 bool ADeleteDarts, bool AVerif,
00129 int AMarkTreated)
00130 {
00131 assert(ADim>=0 && ADim<=2);
00132 assert(AMarkTreated!=AMarkNumber);
00133
00134 int nbIsolated = 0;
00135 int treated = getNewMark();
00136 int toDelete = 0;
00137
00138 if (ADeleteDarts)
00139 toDelete = getNewMark();
00140
00141 if (AMarkTreated>=0)
00142 markCopy(AMarkTreated, treated);
00143
00144 CDynamicCoverageAll it(this);
00145
00146 for (; it.cont(); ++it)
00147 if (!isMarked(*it, treated))
00148 {
00149 if (isMarked(*it, AMarkNumber))
00150 {
00151 bool possible =
00152 !AVerif ||
00153 (!isFree(*it, ADim+1) && canMerge(*it, alpha(*it, ADim+1), ADim+1));
00154
00155 markOrbit(*it, ORBIT_CELL[ADim], treated);
00156
00157 if (possible)
00158 {
00159 if (ADeleteDarts)
00160 markOrbit(*it, ORBIT_CELL[ADim], toDelete);
00161
00162 if (AMarkTreated>=0)
00163 for (int i = 0; i<2; ++i)
00164 {
00165 CDart * dart = i==0 ? *it : alpha(*it, ADim+1);
00166
00167 CCoverage * cov =
00168 getDynamicCoverage(dart, ORBIT_CELL[ADim+1]);
00169
00170 for (; cov->cont(); ++(*cov))
00171 if (!isMarked(**cov, AMarkTreated))
00172 markOrbit(**cov, ORBIT_CELL[ADim], AMarkTreated);
00173
00174 delete cov;
00175 }
00176
00177 merge(*it, alpha(*it,ADim+1), ADim+1, false);
00178 ++nbIsolated;
00179 }
00180 }
00181 else
00182 setMark(*it, treated);
00183 }
00184
00185 negateMaskMark(treated);
00186 freeMark(treated);
00187
00188
00189 if (ADeleteDarts)
00190 {
00191 if (nbIsolated>0)
00192 for (it.reinit(); it.cont(); )
00193 {
00194 CDart * dart = it++;
00195
00196 if (isMarked(dart, toDelete))
00197 delMapDart(dart);
00198 }
00199
00200 freeMark(toDelete);
00201 }
00202
00203 return nbIsolated;
00204 }
00205
00206 int CGMapGeneric::isolateMarkedCells(int AMarkNumber, int ADim,
00207 bool ADeleteDarts)
00208 {
00209 assert(ADim>=0 && ADim<=2);
00210 return isolateMarkedCells(AMarkNumber, ADim, ADeleteDarts, true);
00211 }
00212
00213 int CGMapGeneric::intuitiveIsolateMarkedCells(int AMarkNumber,
00214 bool ADeleteDarts)
00215 {
00216 int treated = getNewMark();
00217 int nbIsolated = 0;
00218
00219 for (int dim=3; dim>=1; --dim)
00220 nbIsolated +=
00221 isolateMarkedCells(AMarkNumber, dim, ADeleteDarts, true, treated);
00222
00223 unmarkAll(treated);
00224 freeMark(treated);
00225
00226 return nbIsolated;
00227 }
00228
00229
00230 void CGMapGeneric::markCellsToBeIsolated(int AMarkSource, int ADim,
00231 int AMarkDestination, int AMarkTreated)
00232 {
00233 assert(ADim>=0 && ADim<=2);
00234
00235
00236
00237
00238
00239 TOrbit halfCell = SUB_ORBIT(ORBIT_CC, ORBIT_I_IP1[ADim]);
00240
00241 CDynamicCoverageAll it(this);
00242
00243
00244 markIncidentCells(halfCell, AMarkSource, AMarkDestination);
00245
00246
00247 for (; it.cont(); ++it)
00248 if (isMarked(*it, AMarkDestination) && isFree(*it, ADim+1))
00249 unsetMark(*it, AMarkDestination);
00250
00251
00252
00253
00254 int treated = getNewMark();
00255
00256 if (AMarkTreated>=0)
00257 markCopy(AMarkTreated, treated);
00258
00259 for (it.reinit(); it.cont(); ++it)
00260 if (!isMarked(*it, treated))
00261
00262
00263 if (isMarked( *it , AMarkDestination) &&
00264 isMarked(alpha(*it, ADim+1), AMarkDestination))
00265
00266
00267 for (int i=0; i<=1; ++i)
00268 {
00269
00270
00271 CCoverage * cov = getDynamicCoverage(i==0 ? *it : alpha(*it, ADim+1),
00272 ORBIT_CELL[ADim+1]);
00273 for (; cov->cont(); ++(*cov))
00274 {
00275
00276
00277 setMark(**cov, treated);
00278 if (!isFree(**cov, ADim+1) &&
00279 !isMarked(alpha(**cov, ADim+1), AMarkDestination))
00280 unsetMark(**cov, AMarkDestination);
00281
00282
00283
00284
00285
00286
00287 }
00288
00289 delete cov;
00290 }
00291
00292
00293
00294
00295
00296 if (AMarkTreated>=0)
00297 markCopy(AMarkTreated, treated);
00298 else
00299 unmarkAll(treated);
00300
00301 for (it.reinit(); it.cont(); ++it)
00302 if (isMarked(*it, AMarkDestination) && !isMarked(*it, treated))
00303 {
00304 markOrbit(*it, ORBIT_CELL[ADim], treated);
00305
00306 if (!canMerge(*it, alpha(*it,ADim+1), ADim+1))
00307 unmarkOrbit(*it, ORBIT_CELL[ADim], AMarkDestination);
00308 }
00309
00310
00311
00312
00313 if (ADim<2)
00314 {
00315 if (AMarkTreated>=0)
00316 markCopy(AMarkTreated, treated);
00317 else
00318 unmarkAll(treated);
00319
00320 for (it.reinit(); it.cont(); ++it)
00321 if (isMarked(*it, AMarkDestination) && !isMarked(*it, treated))
00322 {
00323 bool whole = isWholeCellMarked(*it, ORBIT_CELL[ADim+2],
00324 AMarkDestination);
00325
00326 CCoverage * cov = getDynamicCoverage(*it, ORBIT_CELL[ADim+2]);
00327
00328 for (; cov->cont(); ++(*cov))
00329 if (!isMarked(**cov, treated))
00330 {
00331 markOrbit(**cov, ORBIT_CELL[ADim], treated);
00332
00333 if (whole)
00334 unmarkOrbit(**cov, ORBIT_CELL[ADim], AMarkDestination);
00335
00336
00337
00338 }
00339
00340 delete cov;
00341 }
00342 }
00343
00344 unmarkAll(treated);
00345 freeMark(treated);
00346 }
00347
00348 int CGMapGeneric::mergeMarkedCells(int AMarkNumber, int ADim,
00349 bool ADeleteDarts)
00350 {
00351 assert(ADim>=1 && ADim<=3);
00352
00353
00354 int selected = getNewMark();
00355
00356 markCellsToBeIsolated(AMarkNumber, ADim-1, selected);
00357
00358
00359 int nbMerged = isolateMarkedCells(selected, ADim-1, ADeleteDarts, false);
00360
00361 unmarkAll(selected);
00362 freeMark(selected);
00363
00364 return nbMerged;
00365 }
00366
00367 int CGMapGeneric::intuitiveMergeMarkedCells(int AMarkNumber, bool ADeleteDarts)
00368 {
00369 int nbMerged = 0;
00370 int treated = getNewMark();
00371
00372 int selected = getNewMark();
00373
00374 for (int dim=3; dim>=1; --dim)
00375 {
00376
00377 markCellsToBeIsolated(AMarkNumber, dim-1, selected, treated);
00378
00379
00380 nbMerged +=
00381 isolateMarkedCells(selected, dim-1, ADeleteDarts, false, treated);
00382
00383 unmarkAll(selected);
00384 }
00385
00386 freeMark(selected);
00387
00388 unmarkAll(treated);
00389 freeMark(treated);
00390
00391 return nbMerged;
00392 }
00393