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 bool CGMapGeneric::canExtrudeHalfCell(CDart* ADart, int ADim,
00029 int AMarkToExtrude)
00030 {
00031 assert(ADart!=NULL);
00032 assert(ADim>=0 && ADim<=2);
00033
00034
00035
00036
00037 switch (ADim)
00038 {
00039 case 0:
00040 return
00041 isFree0(ADart) ||
00042 (AMarkToExtrude>=0 && isMarked(alpha0(ADart), AMarkToExtrude));
00043
00044 case 1:
00045 return
00046 (isFree1(ADart) ||
00047 (AMarkToExtrude>=0 && isMarked(alpha1 (ADart), AMarkToExtrude))) &&
00048 (isFree1(alpha0(ADart)) ||
00049 (AMarkToExtrude>=0 && isMarked(alpha01(ADart), AMarkToExtrude))) ;
00050
00051 case 2:
00052 for (CDynamicCoverage01 it(this, ADart); it.cont(); ++it)
00053 if (!isFree2(*it) &&
00054 (AMarkToExtrude<0 || !isMarked(alpha2(*it), AMarkToExtrude)))
00055 return false;
00056
00057 return true;
00058 }
00059
00060 return false;
00061 }
00062
00063 bool CGMapGeneric::canExtrudeCell(CDart* ADart, int ADim)
00064 {
00065 assert(ADart!=NULL);
00066 assert(ADim>=0 && ADim<=2);
00067
00068 return isFree(ADart, ADim+1) || canExtrudeHalfCell(ADart, ADim);
00069 }
00070
00071 int CGMapGeneric::getExtrusionDimension(CDart* ADart)
00072 {
00073 assert(ADart!=NULL);
00074
00075 for (int dim=0; dim<=2; ++dim)
00076 if (canExtrudeHalfCell(ADart, dim))
00077 return dim;
00078
00079 if (canExtrudeCell(ADart, 2))
00080 return 2;
00081
00082 return 3;
00083 }
00084
00085 CDart* CGMapGeneric::topoExtrude(CDart* ADart, int ADim,
00086 bool AExtrusionWithAdjacentSews,
00087 int AMarkExtruded, int ADirectInfoIndex)
00088 {
00089 assert(ADart!=NULL);
00090 assert(ADim>=0 && ADim<=2);
00091 assert(canExtrudeCell(ADart, ADim));
00092
00093 CDart* initial = ADart;
00094 CDart* halfCell;
00095 CDart* opposite=NULL;
00096
00097
00098 if (canExtrudeHalfCell(ADart, ADim))
00099 halfCell = ADart;
00100 else
00101 {
00102 switch (ADim)
00103 {
00104 case 0:
00105 {
00106 CDynamicCoverage3 it(this, ADart);
00107
00108
00109 for (; it.cont(); ++it)
00110 linkAlpha1(*it, addMapDart());
00111
00112 for (it.reinit(); it.cont(); ++it)
00113 {
00114 if (!isFree3(*it) && isFree3(alpha1(*it)))
00115 linkAlpha3(alpha1(*it), alpha31(*it));
00116 }
00117 }
00118 break;
00119
00120 case 1:
00121 {
00122 CDynamicCoverage0 it(this, ADart);
00123
00124
00125 for (; it.cont(); ++it)
00126 linkAlpha2(*it, addMapDart());
00127
00128 for (it.reinit(); it.cont(); ++it)
00129 {
00130 if (!isFree0(*it) && isFree0(alpha2(*it)))
00131 linkAlpha0(alpha2(*it), alpha02(*it));
00132 }
00133 }
00134 break;
00135
00136 case 2:
00137 {
00138 CDynamicCoverage01 it(this, ADart);
00139
00140
00141 for (; it.cont(); ++it)
00142 linkAlpha3(*it, addMapDart());
00143
00144 for (it.reinit(); it.cont(); ++it)
00145 {
00146 if (!isFree0(*it) && isFree0(alpha3(*it)))
00147 linkAlpha0(alpha3(*it), alpha03(*it));
00148
00149 if (!isFree1(*it) && isFree1(alpha3(*it)))
00150 linkAlpha1(alpha3(*it), alpha13(*it));
00151 }
00152 }
00153 break;
00154 }
00155
00156 halfCell = alpha(ADart, ADim+1);
00157 }
00158
00159
00160 assert(canExtrudeHalfCell(halfCell, ADim));
00161
00162 switch (ADim)
00163 {
00164 case 0:
00165 {
00166 CDynamicCoverage3 it(this, halfCell);
00167
00168
00169 for (; it.cont(); ++it)
00170 linkAlpha0(*it, addMapDart());
00171
00172 for (it.reinit(); it.cont(); ++it)
00173 if (!isFree3(*it) && isFree3(alpha0(*it)))
00174 linkAlpha3(alpha0(*it), alpha30(*it));
00175
00176 opposite = alpha0(halfCell);
00177 }
00178 break;
00179
00180 case 1:
00181 {
00182
00183 for (CDynamicCoverage0 it(this, halfCell); it.cont(); ++it)
00184 {
00185 CDart* d1 = addMapDart();
00186 CDart* d2 = addMapDart();
00187 CDart* opposite = addMapDart();
00188
00189 linkAlpha0(d1, d2);
00190 linkAlpha1(*it, d1);
00191 linkAlpha1(d2, opposite);
00192
00193 if (it.prevOperationType()!=OP_NONE)
00194 linkAlpha0(opposite, alpha0101(*it));
00195 }
00196
00197 opposite = alpha101(halfCell);
00198 }
00199 break;
00200
00201 case 2:
00202 {
00203
00204 for (CDynamicCoverage01 it(this, halfCell); it.cont(); ++it)
00205 {
00206 CDart* d0 = addMapDart();
00207 CDart* d1 = addMapDart();
00208 CDart* d2 = addMapDart();
00209 CDart* d3 = addMapDart();
00210 CDart* opposite = addMapDart();
00211
00212 linkAlpha0(d1, d2);
00213 linkAlpha1(d1, d0); linkAlpha2(d0, *it);
00214 linkAlpha1(d2, d3); linkAlpha2(d3, opposite);
00215
00216 if (!isFree0(*it) && !isFree2(alpha0(*it)))
00217 {
00218 linkAlpha0(d0, alpha02(*it));
00219 linkAlpha0(d3, alpha02101(*it));
00220 linkAlpha0(opposite, alpha02(d3));
00221 }
00222
00223 if (!isFree1(*it) && !isFree2(alpha1(*it)))
00224 {
00225 linkAlpha2(d1, alpha121(*it));
00226 linkAlpha2(d2, alpha20(d1));
00227 linkAlpha1(opposite, alpha212(d2));
00228 }
00229 }
00230
00231 opposite = alpha21012(halfCell);
00232 }
00233 break;
00234 }
00235
00236 if (AExtrusionWithAdjacentSews && ADim>0 && AMarkExtruded>=0)
00237 {
00238
00239 CCoverage * cov = getDynamicCoverage(initial, ORBIT_INF[ADim]);
00240
00241 for (; cov->cont(); ++(*cov))
00242 {
00243 CDart* first = **cov;
00244 CDart* semiFirst = initial==halfCell ? first : alpha(first, ADim+1);
00245
00246 if (isFree(alpha(semiFirst, ADim), ADim+1))
00247 {
00248 CDart* second =
00249 ADirectInfoIndex < 0
00250 ? alpha(**cov, ADim)
00251 : (CDart*) getDirectInfo(**cov, ADirectInfoIndex);
00252
00253
00254 bool finished = first==second;
00255
00256 while (!finished && !isMarked(second, AMarkExtruded))
00257 {
00258 if (isFree(second, ADim+1))
00259 finished = true;
00260 else
00261 {
00262 second = alpha(second, ADim+1);
00263
00264 CDart* next =
00265 ADirectInfoIndex < 0
00266 ? alpha(second, ADim)
00267 : (CDart*) getDirectInfo(second, ADirectInfoIndex);
00268
00269 if (next==second)
00270 finished = true;
00271 else
00272 second = next;
00273 }
00274 }
00275
00276
00277 if (!finished)
00278 {
00279 CDart* semiSecond =
00280 initial==halfCell ? second : alpha(second, ADim+1);
00281
00282 assert(!isFree(semiSecond, ADim));
00283 sew(alpha(semiFirst, ADim), alpha(semiSecond, ADim), ADim+1);
00284 }
00285 }
00286 }
00287
00288 delete cov;
00289
00290
00291 markOrbit(initial, ORBIT_INF[ADim], AMarkExtruded);
00292 }
00293
00294 return opposite;
00295 }
00296
00297 CDart* CGMapGeneric::extrudeByNormal(CDart* ADart, int ADim,
00298 bool AExtrusionWithAdjacentSews,
00299 TCoordinate ,
00300 int , int AMarkExtruded)
00301 {
00302 return topoExtrude(ADart, ADim, AExtrusionWithAdjacentSews, AMarkExtruded);
00303 }
00304
00305 int CGMapGeneric::extrudeByNormalMarkedCells(int AMarkNumber, int ADim,
00306 bool AExtrusionWithAdjacentSews,
00307 TCoordinate AExtrusionCoef)
00308 {
00309 int selected = getNewMark();
00310
00311 markCellsToBeExtrudedByNormal(ADim, AMarkNumber, selected);
00312
00313 int nb = extrudeByNormalMarkedCells(selected, ADim, -1,
00314 AExtrusionWithAdjacentSews,
00315 AExtrusionCoef);
00316
00317 unmarkAll(selected);
00318 freeMark(selected);
00319
00320 return nb;
00321 }
00322
00323 int CGMapGeneric::
00324 intuitiveExtrudeByNormalMarkedCells(int AMarkNumber,
00325 bool AExtrusionWithAdjacentSews,
00326 TCoordinate AExtrusionCoef)
00327 {
00328 int nb = 0;
00329 int treated = getNewMark();
00330 int selected = getNewMark();
00331
00332
00333 markCellsToBeExtrudedByNormal(2, AMarkNumber, selected);
00334
00335 nb+= extrudeByNormalMarkedCells(selected, 0, treated,
00336 AExtrusionWithAdjacentSews,
00337 AExtrusionCoef);
00338 nb+= extrudeByNormalMarkedCells(selected, 1, treated,
00339 AExtrusionWithAdjacentSews,
00340 AExtrusionCoef);
00341 nb+= extrudeByNormalMarkedCells(selected, 2, treated,
00342 AExtrusionWithAdjacentSews,
00343 AExtrusionCoef);
00344
00345 unmarkAll(treated);
00346 freeMark(treated);
00347
00348 unmarkAll(selected);
00349 freeMark(selected);
00350
00351 return nb;
00352 }
00353
00354
00355 void CGMapGeneric::markCellsToBeExtrudedByNormal(int ADim,
00356 int AMarkNumberSrce,
00357 int AMarkNumberDest)
00358 {
00359 markIncidentCells(ORBIT_INF[ADim], AMarkNumberSrce, AMarkNumberDest);
00360 }
00361
00362
00363 int CGMapGeneric::extrudeByNormalMarkedCells(int AMarkNumber, int ADim,
00364 int AMarkTreated,
00365 bool AExtrusionWithAdjacentSews,
00366 TCoordinate AExtrusionCoef)
00367 {
00368 int nbExtruded = 0;
00369 int treated = getNewMark();
00370 int extruded = getNewMark();
00371
00372 for (CDynamicCoverageAll it(this); it.cont(); ++it)
00373 if (!isMarked(*it, treated))
00374 {
00375 if (isMarked(*it, AMarkNumber) &&
00376 (AMarkTreated<0 || !isMarked(*it, AMarkTreated)))
00377 {
00378 if ((AMarkTreated<0 && canExtrudeCell(*it, ADim)) ||
00379 (AMarkTreated>=0 &&
00380 (canExtrudeHalfCell(*it, ADim) ||
00381 (ADim==2 && canExtrudeCell(*it, ADim)))))
00382 {
00383 bool free = isFree(*it, ADim+1);
00384
00385 extrudeByNormal(*it, ADim,
00386 AExtrusionWithAdjacentSews,
00387 AExtrusionCoef,
00388 AMarkNumber, extruded);
00389 ++nbExtruded;
00390
00391 if (free && !isFree(*it, ADim+1))
00392 {
00393 markOrbit(*it, ORBIT_INF[ADim], treated);
00394 markOrbit(alpha(*it, ADim+1), ORBIT_CELL[ADim+1], treated);
00395
00396 if (AMarkTreated>=0)
00397 markOrbit(alpha(*it, ADim+1),
00398 ORBIT_CELL[ADim+1], AMarkTreated);
00399 }
00400 else
00401 {
00402 markOrbit(*it, ORBIT_CELL[ADim+1], treated);
00403
00404 if (AMarkTreated>=0)
00405 markOrbit(*it, ORBIT_CELL[ADim+1], AMarkTreated);
00406 }
00407 }
00408 else
00409 markOrbit(*it, ORBIT_CELL[ADim], treated);
00410 }
00411 else
00412 setMark(*it, treated);
00413 }
00414
00415 unmarkAll(extruded);
00416 freeMark(extruded);
00417
00418 negateMaskMark(treated);
00419 freeMark(treated);
00420
00421 return nbExtruded;
00422 }
00423
00424 bool CGMapGeneric::canExtrudeByPath(CDart* ADart, int ADim, CDart* APath)
00425 {
00426 assert(ADart!=NULL);
00427 assert(1<=ADim && ADim<=2);
00428 assert(APath!=NULL);
00429
00430 bool extremity = isFree0(APath) || isFree1(APath) || isFree0(alpha1(APath));
00431
00432
00433 if (extremity)
00434 return canExtrudeCell(ADart, ADim);
00435
00436
00437 return isFree(ADart, ADim+1);
00438 }
00439
00440 CDart* CGMapGeneric::extrudeByPath(CDart* ADart, int ADim, CDart* APath,
00441 bool AExtrusionWithAdjacentSews,
00442 int AMarkExtruded, int ADirectInfoIndex)
00443 {
00444 assert(canExtrudeByPath(ADart, ADim, APath));
00445
00446 CDart* current = ADart;
00447 bool jumped = isFree0(APath) || isFree1(APath) || isFree0(alpha1(APath));
00448
00449
00450
00451 if (!jumped)
00452 {
00453 CCoverage * cov = getDynamicCoverage(ADart, ORBIT_INF[ADim]);
00454
00455 for (; cov->cont(); ++(*cov))
00456 if (!isFree(**cov, ADim))
00457 unsew(**cov, ADim);
00458
00459 delete cov;
00460 }
00461
00462
00463 CDynamicCoverage01 path(this, APath);
00464
00465 if (isFree0(*path))
00466 ++path;
00467
00468 if (path.cont())
00469 ++path;
00470
00471 while (path.cont())
00472 {
00473
00474 assert(!isFree0(*path));
00475 current = topoExtrude(current, ADim, AExtrusionWithAdjacentSews,
00476 AMarkExtruded,
00477 current==ADart ? ADirectInfoIndex : -1);
00478
00479
00480 ++path; if (!path.cont()) break;
00481
00482 if (isFree0(*path))
00483 { ++path; if (!path.cont()) break; }
00484
00485 if (path.prevOperationType()==OP_JUMP)
00486 {
00487 current = ADart;
00488 jumped = true;
00489 }
00490
00491 ++path;
00492 }
00493
00494
00495 if (!jumped)
00496 topoSew(current, ADart, ADim+1);
00497
00498 return current;
00499 }
00500
00501 int CGMapGeneric::extrudeByPathMarkedCells(int AMarkNumber, int ADim,
00502 CDart* APath,
00503 bool AExtrusionWithAdjacentSews)
00504 {
00505 assert(APath!=NULL);
00506 assert(1<=ADim && ADim<=2);
00507
00508 int nbExtruded = 0;
00509 int treated = getNewMark();
00510 int toExtrude = getNewMark();
00511 int extruded = getNewMark();
00512
00513 int directInfoIndex = getNewDirectInfo();
00514
00515 CDynamicCoverageAll it(this);
00516
00517 for (; it.cont(); ++it)
00518 setDirectInfo(*it, directInfoIndex, alpha(*it, ADim));
00519
00520 markIncidentCells(ORBIT_CELL[ADim], AMarkNumber, toExtrude);
00521
00522 for (it.reinit(); it.cont(); ++it)
00523 if (!isMarked(*it, treated) && isMarked(*it, AMarkNumber))
00524 {
00525 markOrbit(*it, ORBIT_CELL[ADim], treated);
00526
00527 if (canExtrudeByPath(*it, ADim, APath))
00528 {
00529 extrudeByPath(*it, ADim, APath, AExtrusionWithAdjacentSews,
00530 extruded, directInfoIndex);
00531 ++nbExtruded;
00532 }
00533 }
00534
00535 freeDirectInfo(directInfoIndex);
00536
00537 unmarkAll(treated);
00538 freeMark(treated);
00539
00540 unmarkAll(toExtrude);
00541 freeMark(toExtrude);
00542
00543 unmarkAll(extruded);
00544 freeMark(extruded);
00545
00546 return nbExtruded;
00547 }
00548
00549 bool CGMapGeneric::canExtrudeByRevolution(CDart* ADart, int ADim, bool AClosed)
00550 {
00551 assert(ADart!=NULL);
00552 assert(1<=ADim && ADim<=2);
00553
00554
00555 if (!AClosed)
00556 return canExtrudeCell(ADart, ADim);
00557
00558
00559 return isFree(ADart, ADim+1);
00560 }
00561
00562 CDart* CGMapGeneric::createRevolutionPath(bool AClosed, int ANbEdges)
00563 {
00564 assert(ANbEdges>=3);
00565
00566 CDart* extremity = createTopoPolygon(ANbEdges);
00567
00568 if (!AClosed)
00569 topoUnsew1(extremity);
00570
00571 return extremity;
00572 }
00573
00574 void CGMapGeneric::destroyRevolutionPath(CDart* ADart)
00575 {
00576 assert(ADart!=NULL);
00577 assert(isIsolatedPolyline(ADart));
00578
00579 for (CStaticCoverage01 cov(this, ADart); cov.cont(); ++cov)
00580 delMapDart(*cov);
00581 }
00582
00583 CDart* CGMapGeneric::extrudeByRevolution(CDart* ADart, int ADim,
00584 bool AClosed, int ANbEdges,
00585 bool AExtrusionWithAdjacentSews,
00586 int AMarkExtruded ,
00587 int ADirectInfoIndex )
00588 {
00589 assert(canExtrudeByRevolution(ADart, ADim, AClosed));
00590 assert(ANbEdges>=3);
00591
00592
00593 CDart* path = CGMapGeneric::createRevolutionPath(AClosed, ANbEdges);
00594
00595
00596 CDart* result = CGMapGeneric::extrudeByPath(ADart, ADim, path,
00597 AExtrusionWithAdjacentSews,
00598 AMarkExtruded, ADirectInfoIndex);
00599
00600
00601 destroyRevolutionPath(path);
00602
00603 return result;
00604 }
00605
00606 int CGMapGeneric::extrudeByRevolutionMarkedCells(int AMarkNumber, int ADim,
00607 bool AClosed, int ANbEdges,
00608 bool AExtrusionWithAdjacentSews)
00609 {
00610 assert(1<=ADim && ADim<=2);
00611 assert(ANbEdges>=3);
00612
00613
00614 CDart* path = CGMapGeneric::createRevolutionPath(AClosed, ANbEdges);
00615
00616
00617 int nbExtruded = extrudeByPathMarkedCells(AMarkNumber, ADim, path,
00618 AExtrusionWithAdjacentSews);
00619
00620
00621 destroyRevolutionPath(path);
00622
00623 return nbExtruded;
00624 }
00625