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-vertex.hh"
00026 #include "geometry.hh"
00027 using namespace GMap3d;
00028
00029 CDart* CGMapVertex::extrudeByNormal(CDart* ADart, int ADim,
00030 bool AExtrusionWithAdjacentSews,
00031 TCoordinate AExtrusionCoef,
00032 int AMarkToExtrude, int AMarkExtruded)
00033 {
00034 assert(canExtrudeCell(ADart, ADim));
00035
00036 TOrbit orbitPieceOfVertex = AND_ORBIT(ORBIT_VERTEX, ORBIT_INF[ADim]);
00037 CVertex normal = AExtrusionCoef * faceNormalVector(ADart);
00038
00039
00040 CDart* newDart = CGMapGeneric::extrudeByNormal(ADart, ADim,
00041 AExtrusionWithAdjacentSews,
00042 AMarkToExtrude,
00043 AMarkExtruded);
00044
00045
00046 int treated = getNewMark();
00047
00048 CCoverage * cov1 = getDynamicCoverage(ADart , ORBIT_INF[ADim]);
00049 CCoverage * cov2 = getDynamicCoverage(newDart, ORBIT_INF[ADim]);
00050
00051 for (; cov1->cont(); ++(*cov1), ++(*cov2))
00052 if (!isMarked(**cov1, treated))
00053 {
00054 markOrbit(**cov1, orbitPieceOfVertex, treated);
00055
00056 if (findVertex(**cov2)==NULL)
00057 {
00058 CVertex vector;
00059
00060 if (AExtrusionWithAdjacentSews && ADim==2)
00061 vector = AExtrusionCoef *
00062 regionNormalVector(**cov1, 0, AMarkToExtrude);
00063 else
00064 vector = normal;
00065
00066 setVertex(**cov2, *findVertex(**cov1) + vector);
00067 }
00068 }
00069
00070 delete cov1;
00071 delete cov2;
00072
00073 unmarkOrbit(ADart, ORBIT_INF[ADim], treated);
00074 freeMark(treated);
00075
00076 return newDart;
00077 }
00078
00079
00080 void CGMapVertex::markCellsToBeExtrudedByNormal(int ADim,
00081 int AMarkNumberSrce,
00082 int AMarkNumberDest)
00083 {
00084 halfMarkIncidentCells(ORBIT_INF[ADim], AMarkNumberSrce, AMarkNumberDest);
00085
00086
00087 if (ADim>0)
00088 {
00089 int treated = getNewMark();
00090
00091 for (CDynamicCoverageAll it(this); it.cont(); ++it)
00092 if (!isMarked(*it, treated))
00093 {
00094 if (isMarked(*it, AMarkNumberDest) && !isFree0(*it) &&
00095 isMarked(alpha0(*it), AMarkNumberDest))
00096 {
00097 markOrbit(*it, ORBIT_INF[ADim], treated);
00098 unmarkOrbit(*it, ORBIT_INF[ADim], AMarkNumberDest);
00099 }
00100 else
00101 setMark(*it, treated);
00102 }
00103
00104 negateMaskMark(treated);
00105 freeMark(treated);
00106 }
00107 }
00108
00109 CDart* CGMapVertex::extrudeByPath(CDart* ADart,
00110 int ADim,
00111 CDart* APath,
00112 bool AExtrusionWithAdjacentSews,
00113 bool ARotateExtrudedCells,
00114 bool AScaleExtrudedCells,
00115 CDart* APonderationPath,
00116 int AMarkExtruded,
00117 int ADirectInfoIndex)
00118 {
00119 assert(canExtrudeByPath(ADart, ADim, APath));
00120 assert(APonderationPath==NULL || !isClosedPolyline(APonderationPath));
00121
00122 int treated = getNewMark();
00123
00124 bool change =
00125 !canExtrudeHalfCell(ADart, ADim) &&
00126 (isFree0(APath) || isFree1(APath) || isFree0(alpha1(APath)));
00127
00128
00129 CDart* returned =
00130 CGMapGeneric::extrudeByPath(ADart, ADim, APath,
00131 AExtrusionWithAdjacentSews,
00132 AMarkExtruded, ADirectInfoIndex);
00133
00134 CDart* current = change ? alpha(ADart, ADim+1) : ADart;
00135
00136
00137 int pathNbVertices = getNbPolylineVertices(APath);
00138 int pathInitialPos = 0;
00139
00140 if (!isClosedPolyline(APath))
00141 {
00142 CDart* current = APath;
00143
00144 while (!isFree1(current) && !isFree0(alpha1(current)))
00145 {
00146 current = alpha10(current);
00147 ++pathInitialPos;
00148 }
00149 }
00150
00151 TCoordinate * pathCoefs = new TCoordinate[pathNbVertices];
00152
00153 if (APonderationPath!=NULL)
00154 {
00155 int ponderationNbVertices = getNbPolylineVertices(APonderationPath);
00156
00157
00158 while (!isFree1(APonderationPath) && !isFree0(alpha1(APonderationPath)))
00159 APonderationPath = alpha10(APonderationPath);
00160
00161 TCoordinate * ponderationCoefs = new TCoordinate[ponderationNbVertices];
00162
00163
00164 {
00165 int i = 0;
00166 for (CDynamicCoverage01 cov(this, APonderationPath); cov.cont(); ++cov)
00167 if (!isMarked(*cov, treated))
00168 {
00169 ponderationCoefs[i++] = findVertex(*cov)->getY();
00170 markOrbit(*cov, ORBIT_1, treated);
00171 }
00172
00173 assert(i==ponderationNbVertices);
00174 unmarkOrbit(APonderationPath, ORBIT_01, treated);
00175 }
00176
00177
00178 for (int pathI=0; pathI<pathNbVertices; ++pathI)
00179 if (ponderationNbVertices==1)
00180 pathCoefs[pathI] = ponderationCoefs[0];
00181 else
00182 {
00183 float t = ((float) pathI*ponderationNbVertices)/pathNbVertices;
00184
00185 int i = (int) t;
00186
00187 pathCoefs[pathI] = ponderationCoefs[i];
00188
00189 if (!isZero(t-i))
00190 pathCoefs[pathI] +=
00191 (t-i)*(ponderationCoefs[i+1]-ponderationCoefs[i]);
00192 }
00193
00194 delete [] ponderationCoefs;
00195 }
00196
00197
00198 CDynamicCoverage01 path(this, APath);
00199
00200
00201 if (isFree0(*path))
00202 ++path;
00203
00204 if (path.cont())
00205 ++path;
00206
00207 int pathIndex = pathInitialPos;
00208 int pathDirection = +1;
00209
00210 while (path.cont())
00211 {
00212 current = ADim==1 ? alpha1012(current) : alpha210123(current);
00213
00214
00215 if (alpha1(*path)!=APath)
00216 {
00217 assert(!isFree0(*path));
00218
00219
00220 CVertex & vertex1 = * findVertex(alpha0(*path));
00221 CVertex & vertex2 = * findVertex(*path);
00222
00223 CVertex vertex0, vertex3 ;
00224
00225 if (isFree1(alpha0(*path)) || isFree0(alpha01(*path)))
00226 vertex0 = vertex1 - (vertex2 - vertex1);
00227 else
00228 vertex0 = * findVertex(alpha010(*path));
00229
00230 if (isFree1(*path) || isFree0(alpha1(*path)))
00231 vertex3 = vertex2 + (vertex2 - vertex1);
00232 else
00233 vertex3 = * findVertex(alpha10(*path));
00234
00235 CVertex vector0 = vertex1 - vertex0;
00236 CVertex vector1 = vertex2 - vertex1;
00237 CVertex vector2 = vertex3 - vertex2;
00238
00239 CVertex axis0 = vector0 * vector1;
00240 CVertex axis1 = vector1 * vector2;
00241
00242 if (axis0.isNull()) axis0 = OZ;
00243 if (axis1.isNull()) axis1 = OZ;
00244
00245 TCoordinate angle0 = CGeometry::getAngle(vector0, vector1);
00246 TCoordinate angle1 = CGeometry::getAngle(vector1, vector2);
00247
00248 CTransformationMatrix matrix;
00249
00250 if (AScaleExtrudedCells)
00251 {
00252 TCoordinate cos0 = dCos(angle0/2);
00253
00254 if (isZero(cos0))
00255 cos0 = 1;
00256
00257 matrix.axialScale(vertex1, axis0, cos0);
00258 }
00259
00260 if (ARotateExtrudedCells)
00261 matrix.rotate(vertex1, axis0, angle0/2);
00262
00263 matrix.translate(vector1);
00264
00265 if (ARotateExtrudedCells)
00266 matrix.rotate(vertex2, axis1, angle1/2);
00267
00268 if (AScaleExtrudedCells)
00269 {
00270 TCoordinate cos1 = dCos(angle1/2);
00271
00272 if (isZero(cos1))
00273 cos1 = 1;
00274
00275 matrix.axialScale(vertex2, axis1, 1/cos1);
00276 }
00277
00278
00279 if (APonderationPath!=NULL)
00280 {
00281 TCoordinate coef = 1;
00282
00283 if (!isZero(pathCoefs[pathIndex]))
00284 coef /= pathCoefs[pathIndex];
00285
00286 pathIndex += pathDirection;
00287 coef *= pathCoefs[pathIndex];
00288 matrix.scale(vertex2, coef);
00289 }
00290
00291
00292 CCoverage * cov = getDynamicCoverage(current, ORBIT_INF[ADim]);
00293
00294 for (; cov->cont(); ++(*cov))
00295 if (!isMarked(**cov, treated))
00296 {
00297 markOrbit(**cov, AND_ORBIT(ORBIT_VERTEX, ORBIT_INF[ADim]),
00298 treated);
00299
00300 if (findVertex(**cov)==NULL)
00301 {
00302 CVertex result;
00303 CDart* prev =
00304 ADim==1 ? alpha2101(**cov) : alpha321012(**cov);
00305
00306 matrix.applyOn(* findVertex(prev), result);
00307
00308 setVertex(**cov, result);
00309 }
00310 }
00311
00312 delete cov;
00313
00314 unmarkOrbit(current, ORBIT_INF[ADim], treated);
00315 }
00316
00317
00318 ++path; if (!path.cont()) break;
00319
00320 if (isFree0(*path))
00321 { ++path; if (!path.cont()) break; }
00322
00323 if (path.prevOperationType()==OP_JUMP)
00324 {
00325 current = alpha(ADart, ADim+1);
00326
00327 pathIndex = pathInitialPos;
00328 pathDirection = - pathDirection;
00329 }
00330
00331 ++path;
00332 }
00333
00334 freeMark(treated);
00335 delete [] pathCoefs;
00336
00337 return returned;
00338 }
00339
00340 int CGMapVertex::extrudeByPathMarkedCells(int AMarkNumber, int ADim,
00341 CDart* APath,
00342 bool AExtrusionWithAdjacentSews,
00343 int AInitialTranslateExtrudedCells,
00344 int AInitialRotateExtrudedCells,
00345 bool ARotateExtrudedCells,
00346 bool AScaleExtrudedCells,
00347 CDart* APonderationPath)
00348 {
00349 assert(APath!=NULL);
00350 assert(1<=ADim && ADim<=2);
00351 assert(0<=AInitialTranslateExtrudedCells
00352 && AInitialTranslateExtrudedCells<=2);
00353 assert(0<=AInitialRotateExtrudedCells
00354 && AInitialRotateExtrudedCells<=2);
00355
00356
00357 CVertex pathOrigin , pathDirection ;
00358 CVertex cellsOrigin, cellsDirection;
00359
00360 int treated = getNewMark();
00361 int toExtrude = getNewMark();
00362 int nbExtruded = 0;
00363
00364 if (isFree0(APath))
00365 {
00366 if (isFree1(APath))
00367 return 0;
00368
00369 APath = alpha1(APath);
00370 }
00371
00372 CDynamicCoverageAll it(this);
00373
00374
00375 if (AInitialRotateExtrudedCells==0)
00376 markIncidentCells(ORBIT_INF[ADim], AMarkNumber, toExtrude);
00377 else
00378 {
00379 halfMarkIncidentCells(ORBIT_INF[ADim], AMarkNumber, toExtrude);
00380
00381 for (it.reinit(); it.cont(); ++it)
00382 if (!isMarked(*it, treated))
00383 {
00384 if (isMarked(*it, toExtrude) && !isFree0(*it) &&
00385 isMarked(alpha0(*it), toExtrude))
00386 {
00387 markOrbit(*it, ORBIT_INF[ADim], treated);
00388 unmarkOrbit(*it, ORBIT_INF[ADim], toExtrude);
00389 }
00390 else
00391 setMark(*it, treated);
00392 }
00393
00394 negateMaskMark(treated);
00395 }
00396
00397 for (it.reinit(); it.cont(); ++it)
00398 if (!isMarked(*it, treated))
00399 {
00400 if (isMarked(*it, toExtrude))
00401 {
00402 markOrbit(*it, ORBIT_CELL[ADim], treated);
00403
00404 if (!canExtrudeByPath(*it, ADim, APath))
00405 unmarkOrbit(*it, ORBIT_CELL[ADim], toExtrude);
00406 }
00407 else
00408 setMark(*it, treated);
00409 }
00410
00411 negateMaskMark(treated);
00412
00413
00414 if (AInitialTranslateExtrudedCells!=0 || AInitialRotateExtrudedCells!=0)
00415 {
00416
00417 pathOrigin = *findVertex(APath);
00418
00419 markIncidentCells(ORBIT_CELL[ADim], toExtrude, treated);
00420 cellsOrigin = barycenter(treated);
00421 unmarkAll(treated);
00422
00423
00424 if (AInitialRotateExtrudedCells!=0)
00425 {
00426
00427 CVertex vector1 = * findVertex(alpha0(APath)) - pathOrigin;
00428
00429 if (vector1.isNull())
00430 vector1 = OZ;
00431 else
00432 vector1 /= vector1.norm();
00433
00434 if (isFree1(APath) || isFree0(alpha1(APath)))
00435 pathDirection = vector1;
00436 else
00437 {
00438 CVertex vector0 = pathOrigin - * findVertex(alpha10(APath));
00439
00440 if (vector0.isNull())
00441 vector0 = OZ;
00442 else
00443 vector0 /= vector0.norm();
00444
00445 pathDirection = (vector0 + vector1) / 2;
00446 }
00447
00448 if (pathDirection.isNull())
00449 pathDirection = OZ;
00450
00451
00452 int nbCells = 0;
00453
00454 for (it.reinit(); it.cont(); ++it)
00455 if (!isMarked(*it, treated))
00456 {
00457 if (isMarked(*it, toExtrude))
00458 {
00459 markOrbit(*it, ORBIT_CELL[ADim], treated);
00460 ++nbCells;
00461 cellsDirection +=
00462
00463 faceNormalVector(*it);
00464 }
00465 else
00466 setMark(*it, treated);
00467 }
00468
00469 if (nbCells>0)
00470 cellsDirection /= nbCells;
00471
00472 if (cellsDirection.isNull())
00473 cellsDirection = ADim==0 ? OX : ADim==1 ? OY : OZ;
00474
00475 negateMaskMark(treated);
00476 }
00477 }
00478
00479
00480 if (AInitialRotateExtrudedCells!=0)
00481 {
00482 if (AInitialRotateExtrudedCells==1)
00483 {
00484
00485 CTransformationMatrix matrix;
00486 matrix.orientate(cellsOrigin, cellsDirection, pathDirection);
00487
00488 markIncidentCells(ORBIT_CC, toExtrude, treated);
00489 applyMatrix(matrix, treated);
00490 unmarkAll(treated);
00491 }
00492 else
00493 {
00494
00495 CTransformationMatrix matrix;
00496 matrix.orientate(pathOrigin, pathDirection, cellsDirection);
00497 applyMatrix(matrix, APath, ORBIT_CC);
00498 }
00499 }
00500
00501
00502 if (AInitialTranslateExtrudedCells!=0)
00503 {
00504 if (AInitialTranslateExtrudedCells==1)
00505 {
00506
00507 markIncidentCells(ORBIT_CC, toExtrude, treated);
00508 translate(treated, pathOrigin - cellsOrigin);
00509 unmarkAll(treated);
00510 }
00511 else
00512 {
00513
00514 markOrbit(APath, ORBIT_CC, treated);
00515 translate(treated, cellsOrigin - pathOrigin);
00516 unmarkOrbit(APath, ORBIT_CC, treated);
00517 }
00518 }
00519
00520
00521 int extruded = getNewMark();
00522
00523 int directInfoIndex = getNewDirectInfo();
00524
00525 for (it.reinit(); it.cont(); ++it)
00526 setDirectInfo(*it, directInfoIndex, alpha(*it, ADim));
00527
00528 for (it.reinit(); it.cont(); ++it)
00529 if (isMarked(*it, toExtrude))
00530 {
00531 unmarkOrbit(*it, ORBIT_CELL[ADim], toExtrude);
00532 extrudeByPath(*it, ADim, APath, AExtrusionWithAdjacentSews,
00533 ARotateExtrudedCells, AScaleExtrudedCells,
00534 APonderationPath,
00535 extruded, directInfoIndex);
00536 ++nbExtruded;
00537 }
00538
00539 freeDirectInfo(directInfoIndex);
00540
00541 freeMark(treated);
00542
00543 unmarkAll(extruded);
00544 freeMark(extruded);
00545
00546 unmarkAll(toExtrude);
00547 freeMark(toExtrude);
00548
00549
00550 if (AInitialTranslateExtrudedCells==2)
00551 {
00552 CTransformationMatrix matrix;
00553 matrix.translate(pathOrigin - cellsOrigin);
00554 applyMatrix(matrix, APath, ORBIT_CC);
00555 }
00556
00557
00558 if (AInitialRotateExtrudedCells==2)
00559 {
00560 CTransformationMatrix matrix;
00561 matrix.orientate(pathOrigin, cellsDirection, pathDirection);
00562 applyMatrix(matrix, APath, ORBIT_CC);
00563 }
00564
00565 return nbExtruded;
00566 }
00567
00568 CDart* CGMapVertex::createRevolutionPath(const CVertex & AAxeVertex,
00569 const CVertex & AAxeDirection,
00570 const CVertex & AFirstVertex,
00571 TCoordinate AAngle, int ANbEdges)
00572 {
00573 assert(!AAxeDirection.isNull());
00574 assert(ANbEdges>=3);
00575
00576
00577 TCoordinate nbRounds = fabs(AAngle)/360.0;
00578 bool closed = isZero(nbRounds - floor(nbRounds));
00579
00580 CDart* extremity = CGMapGeneric::createRevolutionPath(closed, ANbEdges);
00581
00582
00583 CVertex vertex(AFirstVertex);
00584
00585 CTransformationMatrix matrix;
00586 matrix.rotate(AAxeVertex, AAxeDirection, AAngle/ANbEdges);
00587
00588 int nbVertices = closed ? ANbEdges : ANbEdges + 1;
00589
00590 CDart* current = extremity;
00591
00592 for (int i=0; i<nbVertices; ++i)
00593 {
00594 setVertex(current, vertex);
00595 matrix.applyOn(vertex);
00596 current= alpha01(current);
00597 }
00598
00599 return extremity;
00600 }
00601
00602 CDart* CGMapVertex::extrudeByRevolution(CDart* ADart, int ADim,
00603 const CVertex & AAxeVertex,
00604 const CVertex & AAxeDirection,
00605 const CVertex & AFirstVertex,
00606 TCoordinate AAngle, int ANbEdges,
00607 bool AExtrusionWithAdjacentSews,
00608 bool ARotateExtrudedCells,
00609 bool AScaleExtrudedCells,
00610 CDart* APonderationPath,
00611 int AMarkExtruded, int ADirectInfoIndex)
00612 {
00613 #ifndef NDEBUG
00614 TCoordinate nbRounds = fabs(AAngle)/360.0;
00615 bool closed = isZero(nbRounds - floor(nbRounds));
00616
00617 assert(canExtrudeByRevolution(ADart, ADim, closed));
00618 assert(ANbEdges>=3);
00619 assert(!AAxeDirection.isNull());
00620 #endif
00621
00622
00623 CDart* path = createRevolutionPath(AAxeVertex, AAxeDirection,
00624 AFirstVertex, AAngle, ANbEdges);
00625
00626
00627 CDart* result = extrudeByPath(ADart, ADim, path,
00628 AExtrusionWithAdjacentSews,
00629 ARotateExtrudedCells, AScaleExtrudedCells,
00630 APonderationPath,
00631 AMarkExtruded, ADirectInfoIndex);
00632
00633
00634 destroyRevolutionPath(path);
00635
00636 return result;
00637 }
00638
00639 int CGMapVertex::
00640 extrudeByRevolutionMarkedCells(int AMarkNumber, int ADim,
00641 const CVertex & AAxeVertex,
00642 const CVertex & AAxeDirection,
00643 TCoordinate AAngle, int ANbEdges,
00644 bool AExtrusionWithAdjacentSews,
00645 int AInitialTranslateExtrudedCells,
00646 int AInitialRotateExtrudedCells,
00647 bool ARotateExtrudedCells,
00648 bool AScaleExtrudedCells,
00649 CDart* APonderationPath)
00650 {
00651 assert(ANbEdges>=3);
00652 assert(!AAxeDirection.isNull());
00653 assert(0<=AInitialTranslateExtrudedCells
00654 && AInitialTranslateExtrudedCells<=2);
00655 assert(0<=AInitialRotateExtrudedCells
00656 && AInitialRotateExtrudedCells<=2);
00657
00658 TCoordinate nbRounds = fabs(AAngle)/360.0;
00659 bool closed = isZero(nbRounds - floor(nbRounds));
00660
00661 int toExtrude = getNewMark();
00662 int treated = getNewMark();
00663
00664
00665 if (AInitialRotateExtrudedCells==0)
00666 markIncidentCells(ORBIT_INF[ADim], AMarkNumber, toExtrude);
00667 else
00668 {
00669 halfMarkIncidentCells(ORBIT_INF[ADim], AMarkNumber, toExtrude);
00670
00671 for (CDynamicCoverageAll it(this); it.cont(); ++it)
00672 if (!isMarked(*it, treated))
00673 {
00674 if (isMarked(*it, toExtrude) && !isFree0(*it) &&
00675 isMarked(alpha0(*it), toExtrude))
00676 {
00677 markOrbit(*it, ORBIT_INF[ADim], treated);
00678 unmarkOrbit(*it, ORBIT_INF[ADim], toExtrude);
00679 }
00680 else
00681 setMark(*it, treated);
00682 }
00683
00684 negateMaskMark(treated);
00685 }
00686
00687 for (CDynamicCoverageAll it(this); it.cont(); ++it)
00688 if (!isMarked(*it, treated))
00689 {
00690 if (isMarked(*it, toExtrude))
00691 {
00692 markOrbit(*it, ORBIT_CELL[ADim], treated);
00693
00694 if (!canExtrudeByRevolution(*it, ADim, closed))
00695 unmarkOrbit(*it, ORBIT_CELL[ADim], toExtrude);
00696 }
00697 else
00698 setMark(*it, treated);
00699 }
00700
00701 negateMaskMark(treated);
00702
00703
00704 markIncidentCells(ORBIT_CELL[ADim], toExtrude, treated);
00705 CVertex bary = barycenter(treated);
00706 unmarkAll(treated);
00707 freeMark(treated);
00708 freeMark(toExtrude);
00709
00710
00711 CDart* path = createRevolutionPath(AAxeVertex, AAxeDirection,
00712 bary, AAngle, ANbEdges);
00713
00714
00715 int result = extrudeByPathMarkedCells(AMarkNumber, ADim, path,
00716 AExtrusionWithAdjacentSews,
00717 0, AInitialRotateExtrudedCells,
00718 ARotateExtrudedCells,
00719 AScaleExtrudedCells,
00720 APonderationPath);
00721
00722
00723 destroyRevolutionPath(path);
00724
00725 return result;
00726 }
00727