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 "rounding-vertex.hh"
00026 #include "g-map-vertex.hh"
00027 #include "geometry.hh"
00028 #include <cstdlib>
00029 #include <cassert>
00030 using namespace GMap3d;
00031
00032 CRoundingVertex::CRoundingVertex(CGMapVertex* AMap) :
00033 CRoundingGeneric(AMap),
00034 FMap(AMap)
00035 {
00036 assert(FMap != NULL);
00037
00038 FCoefs[0] = FMap->getNewDirectInfo();
00039 FCoefs[1] = FMap->getNewDirectInfo();
00040 }
00041
00042 CRoundingVertex::~CRoundingVertex()
00043 {
00044 FMap->freeDirectInfo(FCoefs[0]);
00045 FMap->freeDirectInfo(FCoefs[1]);
00046 }
00047
00048 #define GET_KV(DART) ((FMap->isMarked((DART), AMarkNumber)) \
00049 ? getDartRoundingCoef((DART), 0) \
00050 : 0.0 )
00051
00052 int CRoundingVertex::roundMarkedVertices(int AMarkNumber, bool ADig)
00053 {
00054 int nbRounded = 0;
00055
00056 int directIndex = FMap->getNewDirectInfo();
00057
00058 int treated = FMap->getNewMark();
00059 int original = FMap->getNewMark();
00060 int newdarts = FMap->getNewMark(); FMap->negateMaskMark(newdarts);
00061
00062 CDynamicCoverageAll it(FMap);
00063
00064
00065 FMap->negateMaskMark(original);
00066
00067
00068
00069
00070 FMap->pointDirectInfoToAttributeVertex(directIndex);
00071
00072
00073 for (; it.cont(); ++it)
00074 if (!FMap->isMarked(*it, treated))
00075 {
00076 if (FMap->isMarked(*it, AMarkNumber))
00077 {
00078 FMap->markOrbit(*it, ORBIT_VERTEX, treated);
00079
00080
00081
00082
00083 CAttributeVertex* oldVertex = FMap->removeVertex(*it);
00084
00085 CStaticCoverageVertex cov(FMap, *it);
00086
00087
00088
00089
00090
00091
00092 int roundingDim = getVertexRoundingDimension(*it, 0);
00093 int closureLevel = getEdgeRoundingDimension(*it, 0);
00094
00095
00096 if (!ADig)
00097 chamferVertex(*it, closureLevel);
00098 else if (roundingDim==3)
00099 chamferVertex(*it, 2);
00100 else
00101 chamferVertex(*it, roundingDim);
00102
00103
00104
00105
00106 if (!ADig && closureLevel==3)
00107 {
00108 bool stop = false;
00109
00110 for (CDynamicCoverageVolume cov(FMap, FMap->alpha123(*it));
00111 !stop && cov.cont(); ++cov)
00112 if (FMap->isFree2(*cov))
00113 {
00114 FMap->stopUp(*cov, 2);
00115 stop = true;
00116 }
00117 }
00118
00119
00120 for ( ; cov.cont(); ++cov)
00121
00122 if (!FMap->isMarked(FMap->alpha1(*cov), treated))
00123 {
00124 CDart* d0 = FMap->alpha0(*cov);
00125
00126 CAttributeVertex* vertex0;
00127
00128 if (FMap->isMarked(d0, original))
00129 vertex0 =
00130 FMap->getDirectInfoAsAttributeVertex(d0, directIndex);
00131 else
00132
00133 vertex0 = FMap->findVertex(d0);
00134
00135
00136 TCoordinate u = GET_KV(*cov);
00137 FMap->setVertex(*cov, (1-u) * *oldVertex + u * *vertex0);
00138
00139
00140 FMap->markOrbit(*cov, ORBIT_VERTEX, treated);
00141 }
00142
00143
00144
00145
00146 ++nbRounded;
00147 }
00148 else
00149 FMap->setMark(*it, treated);
00150 }
00151
00152
00153 for (it.reinit(); it.cont(); ++it)
00154 if (!FMap->isMarked(*it, treated))
00155 {
00156 delete FMap->getDirectInfoAsAttributeVertex(*it, directIndex);
00157 FMap->setMark(*it, treated);
00158 }
00159
00160
00161 FMap->negateMaskMark(treated);
00162 FMap->freeMark(treated);
00163
00164 FMap->unmarkAll(original);
00165 FMap->freeMark(original);
00166
00167 FMap->freeDirectInfo(directIndex);
00168
00169 FMap->negateMaskMark(newdarts);
00170 FMap->markIncidentCells(ORBIT_EDGE , newdarts);
00171 FMap->markIncidentCells(ORBIT_VERTEX, newdarts);
00172
00173 FMap->deleteMarkedNullLengthEdges(newdarts);
00174 FMap->deleteMarkedFlatFaces (newdarts);
00175 FMap->deleteMarkedFlatVolumes (newdarts);
00176
00177 FMap->unmarkAll(newdarts);
00178 FMap->freeMark(newdarts);
00179
00180 return nbRounded;
00181 }
00182
00183 #undef GET_KV
00184
00185 int CRoundingVertex::roundMarkedEdges(int AMarkNumber,
00186 bool A3D, bool ADig, bool ASetback)
00187 {
00188 assert(!ADig || A3D);
00189
00190 int nbRounded = 0;
00191
00192 int selected = FMap->getNewMark();
00193 int treated = FMap->getNewMark();
00194 int initial = FMap->getNewMark();
00195 int newdarts = FMap->getNewMark(); FMap->negateMaskMark(newdarts);
00196
00197 int vertexToDestroy = FMap->getNewMark();
00198
00199 int directOldVertex = FMap->getNewDirectInfo();
00200 int directNewVertex = FMap->getNewDirectInfo();
00201
00202 CDynamicCoverageAll it(FMap);
00203
00204
00205
00206
00207 FMap->pointDirectInfoToAttributeVertex(directOldVertex);
00208
00209
00210
00211
00212 doListExtension(AMarkNumber, initial, selected, treated,
00213 vertexToDestroy, &it);
00214
00215
00216
00217
00218
00219
00220
00221
00222 int max = FMap->getNewMark();
00223
00224 doMinMaxCalcul(FCoefs[1], selected, treated, initial, max, A3D, &it);
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 doNewVerticesCalcul(selected, treated, initial, max, directOldVertex,
00235 directNewVertex, ASetback, A3D, &it);
00236
00237 nbRounded = doEdgeChamferingInRounding(treated, initial, ADig, A3D, &it);
00238
00239 doVerticesChamferingInRounding(treated, initial, ADig, A3D, &it);
00240
00241
00242 for (it.reinit(); it.cont(); ++it)
00243 if (!FMap->isMarked(*it, treated))
00244 {
00245 if (FMap->isMarked(*it, selected))
00246 {
00247 CDart* d101 = FMap->alpha101(*it);
00248
00249 FMap->setMark(FMap->alpha3(*it ), treated);
00250 FMap->setMark( d101 , treated);
00251 FMap->setMark(FMap->alpha3(d101), treated);
00252
00253 if ((*it!=d101) && FMap->isMarked(*it, max) &&
00254 FMap->isMarked(d101, max) &&
00255 !FMap->isMarked(FMap->alpha1(*it), selected))
00256 {
00257 removeEdge(FMap->alpha1(*it));
00258
00259 }
00260 }
00261
00262 FMap->setMark(*it, treated);
00263 }
00264
00265 FMap->negateMaskMark(treated);
00266
00267
00268 for (it.reinit(); it.cont(); ++it)
00269 if (!FMap->isMarked(*it, treated))
00270 {
00271 if (FMap->isMarked(*it, selected))
00272 {
00273 assert(FMap->findVertex(*it) == NULL);
00274
00275
00276 CAttributeVertex* vertex =
00277 FMap->getDirectInfoAsAttributeVertex(*it, directNewVertex);
00278 FMap->setVertex(*it, vertex);
00279
00280 FMap->unsetMark(*it, selected);
00281
00282
00283
00284
00285 for (CDynamicCoverageVertex cov(FMap, *it); cov.cont(); ++cov)
00286 if (FMap->isMarked(*cov, selected))
00287 {
00288 FMap->unsetMark(*it, selected);
00289 delete FMap->getDirectInfoAsAttributeVertex(*cov,
00290 directNewVertex);
00291 }
00292
00293 FMap->markOrbit(*it, ORBIT_VERTEX, treated);
00294 }
00295 else
00296 FMap->setMark(*it, treated);
00297 }
00298
00299 FMap->negateMaskMark(treated);
00300
00301
00302 for (it.reinit(); it.cont(); ++it)
00303 if (FMap->isMarked(*it, vertexToDestroy))
00304 {
00305 delete FMap->getDirectInfoAsAttributeVertex(*it, directOldVertex);
00306 FMap->unsetMark(*it, vertexToDestroy);
00307 }
00308
00309
00310 FMap->unmarkAll(max);
00311 FMap->freeMark(max);
00312
00313 FMap->unmarkAll(initial);
00314 FMap->freeMark(initial);
00315
00316 FMap->unmarkAll(selected);
00317 FMap->freeMark(selected);
00318
00319 FMap->freeMark(treated);
00320
00321 FMap->freeMark(vertexToDestroy);
00322 FMap->freeDirectInfo(directOldVertex);
00323 FMap->freeDirectInfo(directNewVertex);
00324
00325 FMap->negateMaskMark(newdarts);
00326 FMap->markIncidentCells(ORBIT_EDGE , newdarts);
00327 FMap->markIncidentCells(ORBIT_VERTEX, newdarts);
00328
00329 FMap->deleteMarkedNullLengthEdges(newdarts);
00330 FMap->deleteMarkedFlatFaces (newdarts);
00331 FMap->deleteMarkedFlatVolumes (newdarts);
00332
00333 FMap->unmarkAll(newdarts);
00334 FMap->freeMark(newdarts);
00335
00336 return nbRounded;
00337 }
00338
00339 void CRoundingVertex::doListExtension(int AMarkNumber, int AMarkInitial,
00340 int AMarkSelected, int AMarkTreated,
00341 int AMarkVertexToDestroy, CCoverage* ACov)
00342 {
00343 FMap->markIncidentCells(ORBIT_EDGE, AMarkNumber, AMarkInitial );
00344 FMap->markIncidentCells(ORBIT_EDGE, AMarkNumber, AMarkSelected);
00345
00346 for ( ; ACov->cont(); ++(*ACov))
00347 if (!FMap->isMarked(**ACov, AMarkTreated))
00348 {
00349 if (FMap->isMarked(**ACov, AMarkSelected))
00350 {
00351 for (CDynamicCoverageVertex cov(FMap, **ACov); cov.cont(); ++cov)
00352 {
00353 if (FMap->getVertex(*cov) != NULL)
00354 {
00355 FMap->removeVertex(*cov);
00356 FMap->setMark(*cov, AMarkVertexToDestroy);
00357 }
00358
00359 FMap->setMark(*cov, AMarkSelected);
00360 FMap->setMark(*cov, AMarkTreated );
00361 }
00362 }
00363 else
00364 FMap->setMark(**ACov, AMarkTreated);
00365 }
00366
00367 FMap->negateMaskMark(AMarkTreated);
00368 }
00369
00370 #define GET_KE(DART) ((FMap->isMarked((DART), AMarkInitial)) \
00371 ? (getDartRoundingCoef((DART), 1)) \
00372 : 0.0 )
00373
00374 void CRoundingVertex::doMinMaxCalcul(int ,
00375 int AMarkSelected, int AMarkTreated,
00376 int AMarkInitial, int AMarkMax,
00377 bool A3D, CCoverage* ACov)
00378 {
00379 if (!A3D)
00380 {
00381 for (ACov->reinit(); ACov->cont(); ++(*ACov))
00382 if (!FMap->isMarked(**ACov, AMarkTreated))
00383 {
00384 if (FMap->isMarked(**ACov, AMarkSelected))
00385 {
00386 CDartVertex* d = (CDartVertex*) **ACov ;
00387 CDartVertex* d121 = (CDartVertex*) FMap->alpha121(**ACov);
00388
00389
00390
00391
00392
00393 TCoordinate val = GET_KE(d );
00394 TCoordinate val121 = GET_KE(d121);
00395
00396 if (isPositive(val-val121)) FMap->setMark(d , AMarkMax);
00397 if (isPositive(val121-val)) FMap->setMark(d121, AMarkMax);
00398
00399 FMap->setMark(d121, AMarkTreated);
00400 }
00401
00402 FMap->setMark(**ACov, AMarkTreated);
00403 }
00404 }
00405 else
00406 {
00407 TCoordinate maxVal;
00408
00409 for (ACov->reinit(); ACov->cont(); ++(*ACov))
00410 if (!FMap->isMarked(**ACov, AMarkTreated))
00411 {
00412 if (FMap->isMarked(**ACov, AMarkSelected))
00413 {
00414 maxVal = 0;
00415
00416
00417 for (CDynamicCoverage23 cov1(FMap, FMap->alpha1(**ACov));
00418 cov1.cont(); ++cov1)
00419 {
00420 TCoordinate cVal = GET_KE(FMap->alpha1(*cov1));
00421
00422 if (isPositive(cVal-maxVal))
00423 maxVal = cVal;
00424 }
00425
00426
00427 for (CDynamicCoverage23 cov2(FMap, FMap->alpha1(**ACov));
00428 cov2.cont(); ++cov2)
00429 {
00430 if (isPositive(GET_KE(FMap->alpha1(*cov2)) - maxVal))
00431 FMap->setMark(FMap->alpha1(*cov2), AMarkMax);
00432
00433 FMap->setMark(FMap->alpha1(*cov2), AMarkTreated);
00434 }
00435 }
00436
00437 FMap->setMark(**ACov, AMarkTreated);
00438 }
00439 }
00440
00441 FMap->negateMaskMark(AMarkTreated);
00442 }
00443
00444 #undef GET_KE
00445
00446 #define GET_KV(DART) (getDartRoundingCoef((DART), 0))
00447 #define GET_KE(DART) ((FMap->isMarked(DART, AMarkInitial)) \
00448 ? (getDartRoundingCoef((DART), 1)) \
00449 : 0.0)
00450
00451 void CRoundingVertex::
00452 doNewVerticesCalcul(int AMarkSelected, int AMarkTreated,
00453 int AMarkInitial, int AMarkMax,
00454 int ADirectIndexOld, int ADirectIndexNew,
00455 bool ASetback, bool A3D, CCoverage* ACov)
00456 {
00457 for (ACov->reinit(); ACov->cont(); ++(*ACov))
00458 if (!FMap->isMarked(**ACov,AMarkTreated))
00459 {
00460 if (FMap->isMarked(**ACov, AMarkSelected))
00461 {
00462 CDartVertex* d = (CDartVertex*) **ACov ;
00463 CDartVertex* d0 = (CDartVertex*) FMap->alpha0 (d );
00464 CDartVertex* d1 = (CDartVertex*) FMap->alpha1 (d );
00465 CDartVertex* d10 = (CDartVertex*) FMap->alpha10(d );
00466 CDartVertex* d010 = (CDartVertex*) FMap->alpha10(d0 );
00467 CDartVertex* d1010 = (CDartVertex*) FMap->alpha10(d10);
00468
00469 #define GET_V(DART) (* FMap-> \
00470 getDirectInfoAsAttributeVertex((DART), ADirectIndexOld))
00471 CAttributeVertex& V1 = GET_V(d );
00472 CAttributeVertex& V2 = GET_V(d10 );
00473 CAttributeVertex& V3 = GET_V(d0 );
00474 CAttributeVertex& V4 = GET_V(d1010);
00475 CAttributeVertex& V5 = GET_V(d010 );
00476 #undef GET_V
00477
00478
00479 TCoordinate u = GET_KE(d );
00480 TCoordinate u0 = GET_KE(d0 );
00481 TCoordinate u10 = GET_KE(d10);
00482 TCoordinate u1 = GET_KE(d1 );
00483
00484
00485 TCoordinate usb = GET_KV(d);
00486
00487 CVertex V6 = (1-u )*V1 + u *V2;
00488 CVertex V7 = (1-u0)*V3 + u0*V5;
00489
00490 CVertex V8,V9;
00491
00492 if (FMap->isMarked(d1, AMarkMax))
00493 {
00494 if (ASetback && isPositive(usb-u1) && !areEqual(usb,u1))
00495 {
00496
00497
00498
00499
00500 FMap->unsetMark(d1, AMarkMax);
00501
00502 V8 = (1-usb )*V1 + usb*V3;
00503 V9 = (1-(u10+usb-u1))*V2 + (u10+usb-u1)*V4;
00504 }
00505 else
00506 {
00507 V8 = (1-u1 )*V1 + u1 *V3;
00508 V9 = (1-u10)*V2 + u10*V4;
00509 }
00510 }
00511 else
00512 {
00513 TCoordinate u2;
00514
00515 if (A3D)
00516 {
00517 CDynamicCoverage23 cov2(FMap, d);
00518
00519 while (cov2.cont() &&
00520 ! FMap->isMarked(FMap->alpha1(*cov2), AMarkMax))
00521 ++cov2;
00522
00523 u2 = GET_KE(FMap->alpha1(*cov2));
00524 }
00525 else
00526 {
00527 u2 = GET_KE(FMap->alpha21(d));
00528 }
00529
00530 TCoordinate ui = u10 + u2 - u1;
00531
00532 if (ASetback && isPositive(usb-u2) && !areEqual(usb,u2))
00533 {
00534
00535 V8 = (1-usb)*V1 + usb*V3;
00536 V9 = (1-(u10+usb-u2))*V2 + (u10+usb-u2)*V4;
00537 }
00538 else
00539 {
00540 V8 = (1-u2)*V1 + u2*V3;
00541 V9 = (1-ui)*V2 + ui*V4;
00542 }
00543 }
00544
00545 CVertex newVertex = CGeometry::getLinesIntersection(V6,V7, V8,V9);
00546
00547 FMap->setDirectInfo(d, ADirectIndexNew,
00548 new CAttributeVertex(newVertex));
00549
00550 if (FMap->isMarked(d1, AMarkMax) && FMap->isMarked(d,AMarkMax))
00551 {
00552 FMap->setDirectInfo(d1, ADirectIndexNew,
00553 new CAttributeVertex(newVertex));
00554
00555 }
00556 }
00557
00558 FMap->setMark(**ACov,AMarkTreated);
00559 }
00560
00561 FMap->negateMaskMark(AMarkTreated);
00562 }
00563
00564 #undef GET_V
00565 #undef GET_K
00566 #undef GET_KV
00567
00568 int CRoundingVertex::
00569 doEdgeChamferingInRounding(int AMarkTreated, int AMarkInitial,
00570 bool ADig, bool A3D, CCoverage* ACov)
00571 {
00572 int nbRounded = 0;
00573 int closureLevel;
00574
00575
00576 for (ACov->reinit(); ACov->cont(); ++(*ACov))
00577 if (! FMap->isMarked(**ACov, AMarkTreated))
00578 {
00579 if (FMap->isMarked(**ACov, AMarkInitial))
00580 {
00581 CDartVertex* d = (CDartVertex*) **ACov;
00582
00583
00584 FMap->markOrbit(**ACov, ORBIT_EDGE, AMarkTreated);
00585
00586 FMap->negateMaskMark(AMarkTreated);
00587
00588
00589
00590
00591 closureLevel = getEdgeRoundingDimension(d,1);
00592
00593
00594 if (!ADig)
00595 chamferEdge(d, closureLevel);
00596 else
00597 {
00598 if (getVertexRoundingDimension(d, 1) == 3)
00599 chamferEdge(d, 2);
00600 else
00601 chamferEdge(d, getVertexRoundingDimension(d, 1));
00602 }
00603
00604
00605
00606
00607 if (A3D && !ADig && closureLevel==3)
00608 {
00609 bool stop = false;
00610
00611 for (CDynamicCoverageVolume cov(FMap, FMap->alpha23(d));
00612 !stop && cov.cont(); ++cov)
00613 if (FMap->isFree2(*cov))
00614 {
00615 FMap->stopUp(*cov, 2);
00616 stop = true;
00617 }
00618 }
00619
00620 FMap->negateMaskMark(AMarkTreated);
00621 ++nbRounded;
00622 }
00623
00624 FMap->setMark(**ACov, AMarkTreated);
00625 }
00626
00627 FMap->negateMaskMark(AMarkTreated);
00628
00629 return nbRounded;
00630 }
00631
00632 void CRoundingVertex::doVerticesChamferingInRounding(int AMarkTreated,
00633 int AMarkInitial,
00634 bool ADig, bool A3D,
00635 CCoverage* ACov)
00636 {
00637 int closureLevel;
00638
00639
00640 for (ACov->reinit(); ACov->cont(); ++(*ACov))
00641 if (!FMap->isMarked(**ACov, AMarkTreated))
00642 {
00643 if (FMap->isMarked(**ACov, AMarkInitial))
00644 {
00645
00646 FMap->markOrbit(**ACov, ORBIT_VERTEX, AMarkTreated);
00647
00648 closureLevel = getEdgeRoundingDimension(**ACov,0);
00649
00650
00651 FMap->negateMaskMark(AMarkTreated);
00652
00653 if (!ADig)
00654 chamferVertex(**ACov, closureLevel);
00655 else if (getVertexRoundingDimension(**ACov, 0)==3)
00656 chamferVertex(**ACov, 2);
00657 else
00658 chamferVertex(**ACov, getVertexRoundingDimension(**ACov, 0));
00659
00660
00661 if (A3D && !ADig && closureLevel==3)
00662 {
00663 bool stop = false;
00664
00665 for (CDynamicCoverageVolume cov(FMap, FMap->alpha123(**ACov));
00666 !stop && cov.cont(); ++cov)
00667 if (FMap->isFree2(*cov))
00668 {
00669 FMap->stopUp(*cov, 2);
00670 stop = true;
00671 }
00672 }
00673
00674 else if (!ADig && closureLevel==2)
00675 {
00676 bool stop = false;
00677
00678 for (CDynamicCoverageVolume cov(FMap, FMap->alpha123(**ACov));
00679 !stop && cov.cont(); ++cov)
00680 if (FMap->isFree1(*cov))
00681 {
00682 FMap->stopUp(*cov, 1);
00683 stop = true;
00684 }
00685 }
00686
00687 FMap->negateMaskMark(AMarkTreated);
00688 }
00689
00690 FMap->setMark(**ACov, AMarkTreated);
00691 }
00692
00693 FMap->negateMaskMark(AMarkTreated);
00694 }
00695
00696 TCoordinate CRoundingVertex::getDartRoundingCoef(CDart* ADart,
00697 int ADimension) const
00698 {
00699 assert(ADimension == 0 || ADimension == 1);
00700 return ((int) (ADart->getDirectInfo(FCoefs[ADimension]))) / 1000.0;
00701 }
00702
00703 void CRoundingVertex::setDartRoundingCoef(CDart* ADart, int ADimension,
00704 TCoordinate AValue) const
00705 {
00706 assert(ADimension == 0 || ADimension == 1);
00707 ADart->setDirectInfo(FCoefs[ADimension], (void*) (int) (1000 * AValue));
00708 }
00709