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 "message-macros.hh"
00026
00027 #include "boolean-operations.hh"
00028 using namespace std;
00029 using namespace GMap3d;
00030
00031
00032 ostream & operator << (ostream & AStream, TBooleanOperation ABoolOp)
00033 {
00034 switch (ABoolOp) {
00035 case BO_Union:
00036 AStream << "Union";
00037 break;
00038 case BO_Intersection:
00039 AStream << "Intersection";
00040 break;
00041 case BO_Difference1:
00042 AStream << "Difference1";
00043 break;
00044 case BO_Difference2:
00045 AStream << "Difference2";
00046 break;
00047 default:
00048 AStream << "Unknown";
00049 break;
00050 }
00051
00052 return (AStream);
00053 }
00054
00055
00056
00057 CBooleanOperations::CBooleanOperations(CGMapVertex * AMap,
00058 CDart * AObject1,
00059 CDart * AObject2,
00060 bool ACalculateOrientation,
00061 int AVertexDI)
00062 : FMap(AMap), FObject1(AObject1), FObject2(AObject2),
00063 FCalculateOrientation(ACalculateOrientation), FVertexDI(AVertexDI)
00064 {
00065 assert(AMap != NULL);
00066
00067 FObject1Mark = FMap->getNewMark();
00068 FObject2Mark = FMap->getNewMark();
00069
00070 if (FObject1 != NULL)
00071 FMap->markOrbit(FObject1, ORBIT_CC, FObject1Mark);
00072
00073 if (FObject2 != NULL)
00074 FMap->markOrbit(FObject2, ORBIT_CC, FObject2Mark);
00075 }
00076
00077
00078
00079 CBooleanOperations::~CBooleanOperations()
00080 {
00081
00082
00083
00084
00085
00086
00087 FMap->unmarkAll(FObject1Mark);
00088 FMap->unmarkAll(FObject2Mark);
00089 FMap->freeMark(FObject1Mark);
00090 FMap->freeMark(FObject2Mark);
00091 }
00092
00093
00094
00095 CDart * CBooleanOperations::getObject1() const
00096 {
00097 return FObject1;
00098 }
00099
00100
00101
00102 CDart * CBooleanOperations::getObject2() const
00103 {
00104 return FObject2;
00105 }
00106
00107
00108
00109 void CBooleanOperations::setObject1(CDart * AObject)
00110 {
00111 FObject1 = AObject;
00112 }
00113
00114
00115
00116 void CBooleanOperations::setObject2(CDart * AObject)
00117 {
00118 FObject2 = AObject;
00119 }
00120
00121
00122
00123 bool CBooleanOperations::isComputationPossible() const
00124 {
00125 return (FObject1 != NULL && FObject2 != NULL &&
00126 !FMap->isSameOrbit(FObject1, FObject2, ORBIT_CC));
00127 }
00128
00129
00130
00131 bool CBooleanOperations::computeResults(bitset<NB_MARKS> ACopyMarks)
00132 {
00133 assert(isComputationPossible());
00134
00135 ACopyMarks[getObject1Mark()] = true;
00136 ACopyMarks[getObject2Mark()] = true;
00137 bool result = corefineObjects(ACopyMarks);
00138 extendMarks();
00139
00140 return result;
00141 }
00142
00143
00144
00145 void CBooleanOperations::markResult(TBooleanOperation AOperation,
00146 int AMark)
00147 {
00148 DEBUG_FUNCTION;
00149
00150 CDynamicCoverageCC cov(FMap, FObject1);
00151
00152 switch (AOperation) {
00153 case BO_Union:
00154 for (; cov.cont(); cov++) {
00155 if (!FMap->isMarked(*cov, FObject1Mark) &&
00156 !FMap->isMarked(*cov, FObject2Mark))
00157 FMap->setMark(*cov, AMark);
00158 }
00159 break;
00160
00161 case BO_Intersection:
00162 for (; cov.cont(); cov++) {
00163 if (FMap->isMarked(*cov, FObject1Mark) &&
00164 FMap->isMarked(*cov, FObject2Mark))
00165 FMap->setMark(*cov, AMark);
00166 }
00167 break;
00168
00169 case BO_Difference1:
00170 for (; cov.cont(); cov++) {
00171 if (FMap->isMarked(*cov, FObject1Mark) &&
00172 !FMap->isMarked(*cov, FObject2Mark))
00173 FMap->setMark(*cov, AMark);
00174 }
00175 break;
00176
00177 case BO_Difference2:
00178 for (; cov.cont(); cov++) {
00179 if (!FMap->isMarked(*cov, FObject1Mark) &&
00180 FMap->isMarked(*cov, FObject2Mark))
00181 FMap->setMark(*cov, AMark);
00182 }
00183 break;
00184 }
00185 }
00186
00187
00188
00189 void CBooleanOperations::markAllButResult(TBooleanOperation AOperation,
00190 int AMark)
00191 {
00192 DEBUG_FUNCTION;
00193
00194 CDynamicCoverageCC cov(FMap, FObject1);
00195
00196 switch (AOperation) {
00197 case BO_Union:
00198 for (; cov.cont(); cov++) {
00199 if (FMap->isMarked(*cov, FObject1Mark) ||
00200 FMap->isMarked(*cov, FObject2Mark))
00201 FMap->setMark(*cov, AMark);
00202 }
00203 break;
00204
00205 case BO_Intersection:
00206 for (; cov.cont(); cov++) {
00207 if (!FMap->isMarked(*cov, FObject1Mark) ||
00208 !FMap->isMarked(*cov, FObject2Mark))
00209 FMap->setMark(*cov, AMark);
00210 }
00211 break;
00212
00213 case BO_Difference1:
00214 for (; cov.cont(); cov++) {
00215 if (!FMap->isMarked(*cov, FObject1Mark) ||
00216 FMap->isMarked(*cov, FObject2Mark))
00217 FMap->setMark(*cov, AMark);
00218 }
00219 break;
00220
00221 case BO_Difference2:
00222 for (; cov.cont(); cov++) {
00223 if (FMap->isMarked(*cov, FObject1Mark) ||
00224 !FMap->isMarked(*cov, FObject2Mark))
00225 FMap->setMark(*cov, AMark);
00226 }
00227 break;
00228 }
00229 }
00230
00231
00232
00233 void CBooleanOperations::markResults(TBooleanOperation AOperation,
00234 int AKeepMark, int ADiscardMark)
00235 {
00236 DEBUG_FUNCTION;
00237
00238 CDynamicCoverageCC cov(FMap, FObject1);
00239
00240 switch (AOperation) {
00241 case BO_Union:
00242 for (; cov.cont(); cov++) {
00243 if (!FMap->isMarked(*cov, FObject1Mark) &&
00244 !FMap->isMarked(*cov, FObject2Mark))
00245 FMap->setMark(*cov, AKeepMark);
00246 else
00247 FMap->setMark(*cov, ADiscardMark);
00248 }
00249 break;
00250
00251 case BO_Intersection:
00252 for (; cov.cont(); cov++) {
00253 if (FMap->isMarked(*cov, FObject1Mark) &&
00254 FMap->isMarked(*cov, FObject2Mark))
00255 FMap->setMark(*cov, AKeepMark);
00256 else
00257 FMap->setMark(*cov, ADiscardMark);
00258 }
00259 break;
00260
00261 case BO_Difference1:
00262 for (; cov.cont(); cov++) {
00263 if (FMap->isMarked(*cov, FObject1Mark) &&
00264 !FMap->isMarked(*cov, FObject2Mark))
00265 FMap->setMark(*cov, AKeepMark);
00266 else
00267 FMap->setMark(*cov, ADiscardMark);
00268 }
00269 break;
00270
00271 case BO_Difference2:
00272 for (; cov.cont(); cov++) {
00273 if (!FMap->isMarked(*cov, FObject1Mark) &&
00274 FMap->isMarked(*cov, FObject2Mark))
00275 FMap->setMark(*cov, AKeepMark);
00276 else
00277 FMap->setMark(*cov, ADiscardMark);
00278 }
00279 break;
00280 }
00281 }
00282
00283
00284
00285 CDart * CBooleanOperations::getDartFromResult(TBooleanOperation AOperation)
00286 {
00287 DEBUG_FUNCTION;
00288
00289 CDart *d = NULL;
00290 CDynamicCoverageCC cov(FMap, FObject1);
00291
00292 switch (AOperation) {
00293 case BO_Union:
00294 for (; cov.cont() && !d; cov++) {
00295 if (!FMap->isMarked(*cov, FObject1Mark) &&
00296 !FMap->isMarked(*cov, FObject2Mark))
00297 d = *cov;
00298 }
00299 break;
00300
00301 case BO_Intersection:
00302 for (; cov.cont() && !d; cov++) {
00303 if (FMap->isMarked(*cov, FObject1Mark) &&
00304 FMap->isMarked(*cov, FObject2Mark))
00305 d = *cov;
00306 }
00307 break;
00308
00309 case BO_Difference1:
00310 for (; cov.cont() && !d; cov++) {
00311 if (FMap->isMarked(*cov, FObject1Mark) &&
00312 !FMap->isMarked(*cov, FObject2Mark))
00313 d = *cov;
00314 }
00315 break;
00316
00317 case BO_Difference2:
00318 for (; cov.cont() && !d; cov++) {
00319 if (!FMap->isMarked(*cov, FObject1Mark) &&
00320 FMap->isMarked(*cov, FObject2Mark))
00321 d = *cov;
00322 }
00323 break;
00324 }
00325
00326 return d;
00327 }
00328
00329
00330
00331 CDart * CBooleanOperations::getDartOutOfResult(TBooleanOperation AOperation)
00332 {
00333 DEBUG_FUNCTION;
00334
00335 CDart *d = NULL;
00336 CDynamicCoverageCC cov(FMap, FObject1);
00337
00338 switch (AOperation) {
00339 case BO_Union:
00340 for (; cov.cont() && !d; cov++) {
00341 if (FMap->isMarked(*cov, FObject1Mark) ||
00342 FMap->isMarked(*cov, FObject2Mark))
00343 d = *cov;
00344 }
00345 break;
00346
00347 case BO_Intersection:
00348 for (; cov.cont() && !d; cov++) {
00349 if (!FMap->isMarked(*cov, FObject1Mark) ||
00350 !FMap->isMarked(*cov, FObject2Mark))
00351 d = *cov;
00352 }
00353 break;
00354
00355 case BO_Difference1:
00356 for (; cov.cont() && !d; cov++) {
00357 if (!FMap->isMarked(*cov, FObject1Mark) ||
00358 FMap->isMarked(*cov, FObject2Mark))
00359 d = *cov;
00360 }
00361 break;
00362
00363 case BO_Difference2:
00364 for (; cov.cont() && !d; cov++) {
00365 if (FMap->isMarked(*cov, FObject1Mark) ||
00366 !FMap->isMarked(*cov, FObject2Mark))
00367 d = *cov;
00368 }
00369 break;
00370 }
00371
00372 return d;
00373 }
00374
00375
00376
00377 void CBooleanOperations::keepResult(TBooleanOperation AOperation,
00378 list<CDart*> * ACompoundList)
00379 {
00380 DEBUG_FUNCTION;
00381
00382 int keep_mark = FMap->getNewMark();
00383 int discard_mark = FMap->getNewMark();
00384
00385
00386
00387 markResults(AOperation, keep_mark, discard_mark);
00388 if (FMap->isMarked(FObject1, discard_mark)) FObject1 = NULL;
00389 if (FMap->isMarked(FObject2, discard_mark)) FObject2 = NULL;
00390 FMap->deleteMarkedDarts(discard_mark);
00391
00392 if (ACompoundList)
00393 getMarkedCompounds(keep_mark, ACompoundList);
00394 else
00395 FMap->unmarkAll(keep_mark);
00396
00397
00398
00399 FMap->freeMark(keep_mark);
00400 FMap->freeMark(discard_mark);
00401 }
00402
00403
00404
00405 void CBooleanOperations::keepAllButResult(TBooleanOperation AOperation,
00406 list<CDart*> * ACompoundList)
00407 {
00408 DEBUG_FUNCTION;
00409
00410 int keep_mark = FMap->getNewMark();
00411 int discard_mark = FMap->getNewMark();
00412
00413
00414
00415 markResults(AOperation, discard_mark, keep_mark);
00416 if (FMap->isMarked(FObject1, discard_mark)) FObject1 = NULL;
00417 if (FMap->isMarked(FObject2, discard_mark)) FObject2 = NULL;
00418 FMap->deleteMarkedDarts(discard_mark);
00419
00420 if (ACompoundList)
00421 getMarkedCompounds(keep_mark, ACompoundList);
00422 else
00423 FMap->unmarkAll(keep_mark);
00424
00425
00426
00427 FMap->freeMark(keep_mark);
00428 FMap->freeMark(discard_mark);
00429 }
00430
00431
00432
00433 CGMapVertex * CBooleanOperations::getMap() const
00434 {
00435 return FMap;
00436 }
00437
00438
00439
00440 int CBooleanOperations::getObject1Mark() const
00441 {
00442 return FObject1Mark;
00443 }
00444
00445
00446
00447 int CBooleanOperations::getObject2Mark() const
00448 {
00449 return FObject2Mark;
00450 }
00451
00452
00453
00454 bool CBooleanOperations::calculateOrientation() const
00455 {
00456 return FCalculateOrientation;
00457 }
00458
00459
00460
00461 int CBooleanOperations::getVertexDI() const
00462 {
00463 return FVertexDI;
00464 }
00465
00466
00467
00468 void CBooleanOperations::getMarkedCompounds(int AMark, list<CDart*> * AList)
00469 {
00470 for (CDynamicCoverageAll cov(FMap); cov.cont(); ++cov)
00471 if (FMap->isMarked(*cov, AMark)) {
00472 FMap->unmarkOrbit(*cov, ORBIT_CC, AMark);
00473 AList->push_back(*cov);
00474 }
00475 }
00476
00477