Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
boolean-operations.cc
Go to the documentation of this file.
1 /*
2  * lib-corefinement : Opérations de corafinement.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-corefinement
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 // #define DEBUG_MESSAGES
25 #include "message-macros.hh"
26 
27 #include "boolean-operations.hh"
28 using namespace std;
29 using namespace GMap3d;
30 //******************************************************************************
31 
32 ostream & operator << (ostream & AStream, TBooleanOperation ABoolOp)
33 {
34  switch (ABoolOp) {
35  case BO_Union:
36  AStream << "Union";
37  break;
38  case BO_Intersection:
39  AStream << "Intersection";
40  break;
41  case BO_Difference1:
42  AStream << "Difference1";
43  break;
44  case BO_Difference2:
45  AStream << "Difference2";
46  break;
47  default:
48  AStream << "Unknown";
49  break;
50  }
51 
52  return (AStream);
53 }
54 
55 //******************************************************************************
56 
57 CBooleanOperations::CBooleanOperations(CGMapVertex * AMap,
58  CDart * AObject1,
59  CDart * AObject2,
60  bool ACalculateOrientation,
61  int AVertexDI)
62  : FMap(AMap), FObject1(AObject1), FObject2(AObject2),
63  FCalculateOrientation(ACalculateOrientation), FVertexDI(AVertexDI)
64 {
65  assert(AMap != NULL);
66 
67  FObject1Mark = FMap->getNewMark();
68  FObject2Mark = FMap->getNewMark();
69 
70  if (FObject1 != NULL)
71  FMap->markOrbit(FObject1, ORBIT_CC, FObject1Mark);
72 
73  if (FObject2 != NULL)
74  FMap->markOrbit(FObject2, ORBIT_CC, FObject2Mark);
75 }
76 
77 //******************************************************************************
78 
80 {
81 // if (FObject1 != NULL)
82 // FMap->unmarkOrbit(FObject1, ORBIT_CC, FObject1Mark);
83 
84 // if (FObject2 != NULL)
85 // FMap->unmarkOrbit(FObject2, ORBIT_CC, FObject2Mark);
86 
87  FMap->unmarkAll(FObject1Mark);
88  FMap->unmarkAll(FObject2Mark);
89  FMap->freeMark(FObject1Mark);
90  FMap->freeMark(FObject2Mark);
91 }
92 
93 //******************************************************************************
94 
96 {
97  return FObject1;
98 }
99 
100 //******************************************************************************
101 
103 {
104  return FObject2;
105 }
106 
107 //******************************************************************************
108 
109 void CBooleanOperations::setObject1(CDart * AObject)
110 {
111  FObject1 = AObject;
112 }
113 
114 //******************************************************************************
115 
116 void CBooleanOperations::setObject2(CDart * AObject)
117 {
118  FObject2 = AObject;
119 }
120 
121 //******************************************************************************
122 
124 {
125  return (FObject1 != NULL && FObject2 != NULL &&
126  !FMap->isSameOrbit(FObject1, FObject2, ORBIT_CC));
127 }
128 
129 //******************************************************************************
130 
131 bool CBooleanOperations::computeResults(bitset<NB_MARKS> ACopyMarks)
132 {
133  assert(isComputationPossible());
134 
135  ACopyMarks[getObject1Mark()] = true;
136  ACopyMarks[getObject2Mark()] = true;
137  bool result = corefineObjects(ACopyMarks);
138  extendMarks();
139 
140  return result;
141 }
142 
143 //******************************************************************************
144 
146  int AMark)
147 {
148  DEBUG_FUNCTION;
149 
150  CDynamicCoverageCC cov(FMap, FObject1);
151 
152  switch (AOperation) {
153  case BO_Union:
154  for (; cov.cont(); cov++) {
155  if (!FMap->isMarked(*cov, FObject1Mark) &&
156  !FMap->isMarked(*cov, FObject2Mark))
157  FMap->setMark(*cov, AMark);
158  }
159  break;
160 
161  case BO_Intersection:
162  for (; cov.cont(); cov++) {
163  if (FMap->isMarked(*cov, FObject1Mark) &&
164  FMap->isMarked(*cov, FObject2Mark))
165  FMap->setMark(*cov, AMark);
166  }
167  break;
168 
169  case BO_Difference1:
170  for (; cov.cont(); cov++) {
171  if (FMap->isMarked(*cov, FObject1Mark) &&
172  !FMap->isMarked(*cov, FObject2Mark))
173  FMap->setMark(*cov, AMark);
174  }
175  break;
176 
177  case BO_Difference2:
178  for (; cov.cont(); cov++) {
179  if (!FMap->isMarked(*cov, FObject1Mark) &&
180  FMap->isMarked(*cov, FObject2Mark))
181  FMap->setMark(*cov, AMark);
182  }
183  break;
184  }
185 }
186 
187 //******************************************************************************
188 
190  int AMark)
191 {
192  DEBUG_FUNCTION;
193 
194  CDynamicCoverageCC cov(FMap, FObject1);
195 
196  switch (AOperation) {
197  case BO_Union:
198  for (; cov.cont(); cov++) {
199  if (FMap->isMarked(*cov, FObject1Mark) ||
200  FMap->isMarked(*cov, FObject2Mark))
201  FMap->setMark(*cov, AMark);
202  }
203  break;
204 
205  case BO_Intersection:
206  for (; cov.cont(); cov++) {
207  if (!FMap->isMarked(*cov, FObject1Mark) ||
208  !FMap->isMarked(*cov, FObject2Mark))
209  FMap->setMark(*cov, AMark);
210  }
211  break;
212 
213  case BO_Difference1:
214  for (; cov.cont(); cov++) {
215  if (!FMap->isMarked(*cov, FObject1Mark) ||
216  FMap->isMarked(*cov, FObject2Mark))
217  FMap->setMark(*cov, AMark);
218  }
219  break;
220 
221  case BO_Difference2:
222  for (; cov.cont(); cov++) {
223  if (FMap->isMarked(*cov, FObject1Mark) ||
224  !FMap->isMarked(*cov, FObject2Mark))
225  FMap->setMark(*cov, AMark);
226  }
227  break;
228  }
229 }
230 
231 //******************************************************************************
232 
234  int AKeepMark, int ADiscardMark)
235 {
236  DEBUG_FUNCTION;
237 
238  CDynamicCoverageCC cov(FMap, FObject1);
239 
240  switch (AOperation) {
241  case BO_Union:
242  for (; cov.cont(); cov++) {
243  if (!FMap->isMarked(*cov, FObject1Mark) &&
244  !FMap->isMarked(*cov, FObject2Mark))
245  FMap->setMark(*cov, AKeepMark);
246  else
247  FMap->setMark(*cov, ADiscardMark);
248  }
249  break;
250 
251  case BO_Intersection:
252  for (; cov.cont(); cov++) {
253  if (FMap->isMarked(*cov, FObject1Mark) &&
254  FMap->isMarked(*cov, FObject2Mark))
255  FMap->setMark(*cov, AKeepMark);
256  else
257  FMap->setMark(*cov, ADiscardMark);
258  }
259  break;
260 
261  case BO_Difference1:
262  for (; cov.cont(); cov++) {
263  if (FMap->isMarked(*cov, FObject1Mark) &&
264  !FMap->isMarked(*cov, FObject2Mark))
265  FMap->setMark(*cov, AKeepMark);
266  else
267  FMap->setMark(*cov, ADiscardMark);
268  }
269  break;
270 
271  case BO_Difference2:
272  for (; cov.cont(); cov++) {
273  if (!FMap->isMarked(*cov, FObject1Mark) &&
274  FMap->isMarked(*cov, FObject2Mark))
275  FMap->setMark(*cov, AKeepMark);
276  else
277  FMap->setMark(*cov, ADiscardMark);
278  }
279  break;
280  }
281 }
282 
283 //******************************************************************************
284 
286 {
287  DEBUG_FUNCTION;
288 
289  CDart *d = NULL;
290  CDynamicCoverageCC cov(FMap, FObject1);
291 
292  switch (AOperation) {
293  case BO_Union:
294  for (; cov.cont() && !d; cov++) {
295  if (!FMap->isMarked(*cov, FObject1Mark) &&
296  !FMap->isMarked(*cov, FObject2Mark))
297  d = *cov;
298  }
299  break;
300 
301  case BO_Intersection:
302  for (; cov.cont() && !d; cov++) {
303  if (FMap->isMarked(*cov, FObject1Mark) &&
304  FMap->isMarked(*cov, FObject2Mark))
305  d = *cov;
306  }
307  break;
308 
309  case BO_Difference1:
310  for (; cov.cont() && !d; cov++) {
311  if (FMap->isMarked(*cov, FObject1Mark) &&
312  !FMap->isMarked(*cov, FObject2Mark))
313  d = *cov;
314  }
315  break;
316 
317  case BO_Difference2:
318  for (; cov.cont() && !d; cov++) {
319  if (!FMap->isMarked(*cov, FObject1Mark) &&
320  FMap->isMarked(*cov, FObject2Mark))
321  d = *cov;
322  }
323  break;
324  }
325 
326  return d;
327 }
328 
329 //******************************************************************************
330 
332 {
333  DEBUG_FUNCTION;
334 
335  CDart *d = NULL;
336  CDynamicCoverageCC cov(FMap, FObject1);
337 
338  switch (AOperation) {
339  case BO_Union:
340  for (; cov.cont() && !d; cov++) {
341  if (FMap->isMarked(*cov, FObject1Mark) ||
342  FMap->isMarked(*cov, FObject2Mark))
343  d = *cov;
344  }
345  break;
346 
347  case BO_Intersection:
348  for (; cov.cont() && !d; cov++) {
349  if (!FMap->isMarked(*cov, FObject1Mark) ||
350  !FMap->isMarked(*cov, FObject2Mark))
351  d = *cov;
352  }
353  break;
354 
355  case BO_Difference1:
356  for (; cov.cont() && !d; cov++) {
357  if (!FMap->isMarked(*cov, FObject1Mark) ||
358  FMap->isMarked(*cov, FObject2Mark))
359  d = *cov;
360  }
361  break;
362 
363  case BO_Difference2:
364  for (; cov.cont() && !d; cov++) {
365  if (FMap->isMarked(*cov, FObject1Mark) ||
366  !FMap->isMarked(*cov, FObject2Mark))
367  d = *cov;
368  }
369  break;
370  }
371 
372  return d;
373 }
374 
375 //******************************************************************************
376 
378  list<CDart*> * ACompoundList)
379 {
380  DEBUG_FUNCTION;
381 
382  int keep_mark = FMap->getNewMark();
383  int discard_mark = FMap->getNewMark();
384 
385 // FObject1 = FObject2 = getDartFromResult(AOperation);
386 
387  markResults(AOperation, keep_mark, discard_mark);
388  if (FMap->isMarked(FObject1, discard_mark)) FObject1 = NULL;
389  if (FMap->isMarked(FObject2, discard_mark)) FObject2 = NULL;
390  FMap->deleteMarkedDarts(discard_mark);
391 
392  if (ACompoundList)
393  getMarkedCompounds(keep_mark, ACompoundList);
394  else
395  FMap->unmarkAll(keep_mark);
396 
397 // assert(FMap->isWholeMapUnmarked(keep_mark));
398 // assert(FMap->isWholeMapUnmarked(discard_mark));
399  FMap->freeMark(keep_mark);
400  FMap->freeMark(discard_mark);
401 }
402 
403 //******************************************************************************
404 
406  list<CDart*> * ACompoundList)
407 {
408  DEBUG_FUNCTION;
409 
410  int keep_mark = FMap->getNewMark();
411  int discard_mark = FMap->getNewMark();
412 
413 // FObject1 = FObject2 = getDartFromResult(AOperation);
414 
415  markResults(AOperation, discard_mark, keep_mark);
416  if (FMap->isMarked(FObject1, discard_mark)) FObject1 = NULL;
417  if (FMap->isMarked(FObject2, discard_mark)) FObject2 = NULL;
418  FMap->deleteMarkedDarts(discard_mark);
419 
420  if (ACompoundList)
421  getMarkedCompounds(keep_mark, ACompoundList);
422  else
423  FMap->unmarkAll(keep_mark);
424 
425 // assert(FMap->isWholeMapUnmarked(keep_mark));
426 // assert(FMap->isWholeMapUnmarked(discard_mark));
427  FMap->freeMark(keep_mark);
428  FMap->freeMark(discard_mark);
429 }
430 
431 //******************************************************************************
432 
433 CGMapVertex * CBooleanOperations::getMap() const
434 {
435  return FMap;
436 }
437 
438 //******************************************************************************
439 
441 {
442  return FObject1Mark;
443 }
444 
445 //******************************************************************************
446 
448 {
449  return FObject2Mark;
450 }
451 
452 //******************************************************************************
453 
455 {
456  return FCalculateOrientation;
457 }
458 
459 //******************************************************************************
460 
462 {
463  return FVertexDI;
464 }
465 
466 //******************************************************************************
467 
468 void CBooleanOperations::getMarkedCompounds(int AMark, list<CDart*> * AList)
469 {
470  for (CDynamicCoverageAll cov(FMap); cov.cont(); ++cov)
471  if (FMap->isMarked(*cov, AMark)) {
472  FMap->unmarkOrbit(*cov, ORBIT_CC, AMark);
473  AList->push_back(*cov);
474  }
475 }
476 
477 //******************************************************************************