Moka controlers
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
operations-merging-insertion-contraction.cc
Go to the documentation of this file.
1 /*
2  * lib-controler-gmap : Le contrôleur de 3-G-cartes, surcouche de lib-controler.
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-controler-gmap
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 //******************************************************************************
25 #include "g-map-vertex.hh"
26 #include "controler-gmap.hh"
27 #include <cassert>
28 
29 #ifndef _WINDOWS
30 #include "chrono.hh"
31 #endif
32 
33 using namespace GMap3d;
34 //******************************************************************************
36 {
37  if ( !getParameterGMapVertex()->getModeSimplification() )
38  return;
39 
40  int deleted = getParameterGMapVertex()->getDrawingMap()->getNewMark();
41  getParameterGMapVertex()->getDrawingMap()->negateMaskMark(deleted);
42 
43  //1) we unmark all surviving darts
44  for (CDynamicCoverageAll it(FMap); it.cont(); ++it)
45  {
47  unsetMark(getParameterGMapVertex()->getDartWithEmbedding(*it),deleted);
48  }
49 
50  if ( ADim==2 ) // TODO better ;)
51  {
53  mergeMarkedCells(deleted, 3, true);
54  return;
55  }
56 
57  // Now we run through all darts of the drawing map. Each dart marked with
58  // deleted and not yet marked with a removed mark was just being removed.
59  for (CDynamicCoverageAll it(getParameterGMapVertex()->getDrawingMap());
60  it.cont(); ++it)
61  {
62  if ( getParameterGMapVertex()->getDrawingMap()->isMarked(*it,deleted) &&
65  setMark(*it,getParameterGMapVertex()->getMarkRemoved(ADim));
66 
67  getParameterGMapVertex()->getDrawingMap()->unsetMark(*it, deleted);
68  }
69 
70  getParameterGMapVertex()->getDrawingMap()->freeMark(deleted);
71 }
72 //******************************************************************************
73 void CControlerGMap::updateDartAfterRemovals(int AMark0, int AMark1, int AMark2)
74 {
75  if ( !getParameterGMapVertex()->getModeSimplification() )
76  return;
77 
78  CDart* current = NULL;
79 
80  if ( AMark2!=-1 )
81  {
82  int deleted = getParameterGMapVertex()->getDrawingMap()->getNewMark();
83 
84  //1) we mark all 2-removed darts
85  for (CDynamicCoverageAll it(FMap); it.cont(); )
86  {
87  current = it++;
88  if ( FMap->isMarked(current,AMark2) )
89  {
91  setMark(getParameterGMapVertex()->
92  getDartWithEmbedding(current),deleted);
93  FMap->delMapDart(current);
94  }
95  }
97  mergeMarkedCells(deleted, 3, true);
98 
99  getParameterGMapVertex()->getDrawingMap()->freeMark(deleted);
100  }
101 
102  for (CDynamicCoverageAll it(FMap); it.cont(); )
103  {
104  current = it++;
105 
106  if ( AMark0!=-1 && FMap->isMarked(current,AMark0) )
107  {
109  setMark(getParameterGMapVertex()->getDartWithEmbedding(current),
110  getParameterGMapVertex()->getMarkRemoved(0));
111  FMap->delMapDart(current);
112  }
113  else if ( AMark1!=-1 && FMap->isMarked(current,AMark1) )
114  {
116  setMark(getParameterGMapVertex()->getDartWithEmbedding(current),
117  getParameterGMapVertex()->getMarkRemoved(1));
118  FMap->delMapDart(current);
119  }
120  // else if ( AMark2!=-1 && FMap->isMarked(current,AMark2) )
121  // {
122  // getParameterGMapVertex()->getDrawingMap()->
123  // setMark(getParameterGMapVertex()->getDartWithEmbedding(current),
124  // getParameterGMapVertex()->getMarkRemoved(2));
125  // FMap->delMapDart(current);
126  // }
127  }
128 }
129 //******************************************************************************
130 bool CControlerGMap::merge(int ADim)
131 {
132  assert(1 <= ADim && ADim <= 3);
133 
134  bool res = false;
135 
137  SUB_OPERATION_TOPO, ADim)))
138  {
139  undoRedoPreSave();
140 
141  int nb = FMap->mergeMarkedCells(getSelectionMark(), ADim, true);
142 
143  if (nb == 0)
144  {
145  setMessage(ADim, "-merge impossible");
147  }
148  else
149  {
150  updateDartAfterRemovals(ADim-1);
151 
154  setModelChanged();
155  setMessage(nb, ADim, (nb == 1 ? "-merge done" :
156  "-merges done"));
157  res = true;
158  }
159  }
160 
161  return res;
162 }
163 //******************************************************************************
165 {
166  bool res = false;
169  {
170  undoRedoPreSave();
171 
172  int nb = FMap->intuitiveMergeMarkedCells(getSelectionMark(), true);
173 
174  if (nb == 0)
175  {
176  setMessage("Intuitive merge impossible");
178  }
179  else
180  {
183  setModelChanged();
184  setMessage(nb, (nb == 1 ? " merge done" :
185  " merges done"));
186  res = true;
187  }
188  }
189 
190  return res;
191 }
192 //******************************************************************************
194 {
195  bool res = false;
196 
198  {
199  undoRedoPreSave();
200 
201  int nb = FMap->mergeMarkedColinearEdges(getSelectionMark(), true);
202 
203  if (nb == 0)
204  {
205  setMessage("No colinear edges exist");
207  }
208  else
209  {
211 
214  setModelChanged();
215  setMessage(nb, (nb == 1 ? " edge merged" :
216  " edges merged"));
217  res = true;
218  }
219  }
220 
221  return res;
222 }
223 //******************************************************************************
225 {
226  bool res = false;
228  {
229  undoRedoPreSave();
230 
231  int nb = FMap->mergeMarkedCoplanarFaces(getSelectionMark(), true);
232 
233  if (nb == 0)
234  {
235  setMessage("Coplanar face merging impossible");
237  }
238  else
239  {
241 
244  setModelChanged();
245  setMessage(nb, (nb == 1 ?
246  " edge removed between coplanar faces" :
247  " edges removed between coplanar faces"));
248  res = true;
249  }
250  }
251 
252  return res;
253 }
254 //******************************************************************************
256 {
257  bool res = false;
259  {
260  undoRedoPreSave();
261 
262  int nb = FMap->deleteNullLengthEdges();
263 
264  if (nb == 0)
265  {
266  setMessage("No null length edge");
268  }
269  else
270  {
272  setModelChanged();
273  setMessage(nb, nb == 1 ?
274  " null length edge removed" :
275  " null length edges removed");
276  res = true;
277  }
278  }
279 
280  return res;
281 }
282 //******************************************************************************
284 {
285  bool res = false;
287  {
288  undoRedoPreSave();
289 
290  int nb = FMap->deleteFlatFaces();
291 
292  if (nb == 0)
293  {
294  setMessage("No face made of only two edges");
296  }
297  else
298  {
300  setModelChanged();
301  setMessage(nb, nb == 1 ?
302  " face made of two edges removed" :
303  " faces made of two edges removed");
304  res = true;
305  }
306  }
307 
308  return res;
309 }
310 //******************************************************************************
312 {
313  bool res = false;
315  {
316  undoRedoPreSave();
317 
318  int nb = FMap->deleteFlatVolumes();
319 
320  if (nb == 0)
321  {
322  setMessage("No volume made of only two faces");
324  }
325  else
326  {
328  setModelChanged();
329  setMessage(nb, nb == 1 ?
330  " volume made of two faces removed" :
331  " volumes made of two faces removed");
332  res = true;
333  }
334  }
335 
336  return res;
337 }
338 //******************************************************************************
340 {
341  bool res = false;
342 
344  1)))
345  {
346  undoRedoPreSave();
347 
348  int nb = FMap->removeMarkedEdgesWithoutDisconnection(getSelectionMark());
349 
350  if (nb == 0)
351  {
352  setMessage("No 1-removal possible");
354  }
355  else
356  {
358 
361  setModelChanged();
362  setMessage(nb, (nb == 1 ? " 1-removal done" : " 1-removals done"));
363  res = true;
364  }
365  }
366 
367  return res;
368 }
369 //******************************************************************************
371 {
372  bool res = false;
373 
375  1)))
376  {
377  undoRedoPreSave();
378 
379  int nb = FMap->removeMarkedFacesButKeepBalls(getSelectionMark());
380 
381  if (nb == 0)
382  {
383  setMessage("No 2-removal possible");
385  }
386  else
387  {
389 
392  setModelChanged();
393  setMessage(nb, (nb == 1 ? " 2-removal done" : " 2-removals done"));
394  res = true;
395  }
396  }
397 
398  return res;
399 }
400 //******************************************************************************
402 {
403  bool res = false;
404 
405  if (getLastSelectedDart() == NULL)
406  {
407  setMessage("No last selected dart");
408  return false;
409  }
410 
412  {
413  undoRedoPreSave();
414 
415  unsigned int nb =
416  FMap->shiftAllEdgesIncidentToVertex(getLastSelectedDart());
417 
419 
421 
422  setModelChanged();
423  setMessage(nb, (nb == 1 ? " edge shifted." : " edges shifted."));
424  res = true;
425  }
426 
427  return res;
428 }
429 //******************************************************************************
431 {
432  bool res = false;
433 
435  {
436  undoRedoPreSave();
437 
438  int nb = FMap->removeDanglingEdges();
439 
440  if (nb == 0)
441  {
442  setMessage("No dangling edge removed");
444  }
445  else
446  {
448 
451  setModelChanged();
452  setMessage(nb, (nb == 1 ? " dangling edge removed" :
453  " dangling edges removed"));
454  res = true;
455  }
456  }
457 
458  return res;
459 }
460 //******************************************************************************
462 {
463  bool res = false;
464 
466  {
467  undoRedoPreSave();
468 
469  int nbdarts, nbvertices, nbedges, nbfaces, nbvolumes, nbcc;
470  getMapGlobalCharacteristics(&nbdarts,&nbvertices,&nbedges,
471  &nbfaces,&nbvolumes,&nbcc,
472  NULL,NULL,NULL,NULL);
473  std::cout<<"Map before simplification: darts="<<nbdarts
474  <<", vertices="<<nbvertices
475  <<", edges="<<nbedges
476  <<", faces="<<nbfaces
477  <<", volumes="<<nbvolumes
478  <<", cc="<<nbcc<<std::endl;
479 
480  int m0=-1;
481  int m1=-1;
482 
483  if ( getParameterGMapVertex()->getModeSimplification() )
484  {
485  m0=FMap->getNewMark();
486  m1=FMap->getNewMark();
487  }
488 
489 #ifndef _WINDOWS
490  CChrono c;
491  c.start();
492 #endif
493 
494  int nb = FMap->simplify2DObject(m0,m1);
495 
496 #ifndef _WINDOWS
497  c.stop();
498  c.display("Time for simplification");
499 #endif
500  assert(isMapOk());
501 
502  if ( nb==0 )
503  {
504  setMessage("Nothing was simplified, the map was already in "
505  "its minimal form.");
507  }
508  else
509  {
510  if ( getParameterGMapVertex()->getModeSimplification() )
511  {
512  updateDartAfterRemovals(m0,m1,-1);
513  FMap->freeMark(m0);
514  FMap->freeMark(m1);
515  }
516 
519  setModelChanged();
520  setMessage(nb, (nb == 1 ? " dart removed during the simplification." :
521  " darts removed during the simplification."));
522  res = true;
523 
524  getMapGlobalCharacteristics(&nbdarts,&nbvertices,&nbedges,
525  &nbfaces,&nbvolumes,&nbcc,
526  NULL,NULL,NULL,NULL);
527  std::cout<<"Map after simplification: darts="<<nbdarts
528  <<", vertices="<<nbvertices
529  <<", edges="<<nbedges
530  <<", faces="<<nbfaces
531  <<", volumes="<<nbvolumes
532  <<", cc="<<nbcc<<std::endl;
533  }
534  }
535 
536  return res;
537 }
538 //******************************************************************************
540 {
541  bool res = false;
542 
544  {
545  undoRedoPreSave();
546 
547  int nbdarts, nbvertices, nbedges, nbfaces, nbvolumes, nbcc;
548  getMapGlobalCharacteristics(&nbdarts,&nbvertices,&nbedges,
549  &nbfaces,&nbvolumes,&nbcc,
550  NULL,NULL,NULL,NULL);
551  std::cout<<"Map before simplification: darts="<<nbdarts
552  <<", vertices="<<nbvertices
553  <<", edges="<<nbedges
554  <<", faces="<<nbfaces
555  <<", volumes="<<nbvolumes
556  <<", cc="<<nbcc<<std::endl;
557 
558  int m0=-1;
559  int m1=-1;
560  int m2=-1;
561 
562  if ( getParameterGMapVertex()->getModeSimplification() )
563  {
564  m0=FMap->getNewMark();
565  m1=FMap->getNewMark();
566  m2=FMap->getNewMark(); // Problem with connected darts
567  }
568 
569 #ifndef _WINDOWS
570  CChrono c;
571  c.start();
572 #endif
573 
574  int nb;
575  if ( getParameterGMapVertex()->getModeSimplification() )
576  nb = FMap->simplify3DObject(m0, m1, m2);
577  else
578  nb = FMap->simplify3DObject();
579 
580 #ifndef _WINDOWS
581  c.stop();
582  c.display("Time for simplification");
583 #endif
584  assert(isMapOk());
585 
586  if ( nb==0 )
587  {
588  setMessage("Nothing was simplified, the map was already in "
589  "its minimal form.");
591  }
592  else
593  {
594  if ( getParameterGMapVertex()->getModeSimplification() )
595  {
596  updateDartAfterRemovals(m0,m1,m2);
597  FMap->freeMark(m0);
598  FMap->freeMark(m1);
599  FMap->freeMark(m2);
600  }
601 
604  setModelChanged();
605  setMessage(nb, (nb == 1 ? " dart removed during the simplification." :
606  " darts removed during the simplification."));
607  res = true;
608 
609  getMapGlobalCharacteristics(&nbdarts,&nbvertices,&nbedges,
610  &nbfaces,&nbvolumes,&nbcc,
611  NULL,NULL,NULL,NULL);
612  std::cout<<"Map after simplification: darts="<<nbdarts
613  <<", vertices="<<nbvertices
614  <<", edges="<<nbedges
615  <<", faces="<<nbfaces
616  <<", volumes="<<nbvolumes
617  <<", cc="<<nbcc<<std::endl;
618  }
619  }
620 
621  return res;
622 }
623 //******************************************************************************
624 bool CControlerGMap::contract(int ADimension)
625 {
626  assert(1 <= ADimension && ADimension <= 3);
627 
628  bool res = false;
629 
631  SUB_OPERATION_TOPO, ADimension)))
632  {
633  undoRedoPreSave();
634 
635  int nb = FMap->contractMarkedCells(getSelectionMark(), ADimension, true);
636 
637  if (nb == 0)
638  {
639  setMessage(ADimension, "-contraction not possible");
641  }
642  else
643  {
646  setModelChanged();
647  setMessage(nb, ADimension, (nb == 1 ? "-contraction done" :
648  "-contractions done"));
649  res = true;
650  }
651  }
652 
653  return res;
654 }
655 //******************************************************************************
657 {
658  bool res = false;
661  {
662  undoRedoPreSave();
663 
664  int dim = 0;
665  switch (getSelectionOrbit())
666  {
667  case ORBIT_EDGE : dim = 1; break;
668  case ORBIT_FACE : dim = 2; break;
669  case ORBIT_VOLUME : dim = 3; break;
670  default: setMessage("Selected orbit not correct"); return false;
671  }
672 
673  int nb = FMap->contractMarkedCells(getSelectionMark(), dim, true);
674 
675  if (nb == 0)
676  {
677  setMessage(dim, "-contraction impossible");
679  }
680  else
681  {
684  setModelChanged();
685  setMessage(nb, dim, (nb == 1 ? "-contraction done" :
686  "-contractions done"));
687  res = true;
688  }
689  }
690 
691  return res;
692 }
693 //******************************************************************************
695 {
696  bool res = false;
698  {
699  undoRedoPreSave();
700 
701  int nb = FMap->insertVertexOnMarkedEdges(getSelectionMark());
702 
703  if (nb == 0)
704  {
705  setMessage("No vertex inserted");
707  }
708  else
709  {
711  setModelChanged();
712  setMessage(nb, nb == 1 ? " vertex inserted" : " vertices inserted");
713  res = true;
714  }
715  }
716 
717  return res;
718 }
719 //******************************************************************************
721 {
722  bool res = false;
724  {
725  undoRedoPreSave();
726 
727  CDart* dart1;
728  CDart* dart2;
729 
730  int nb = 0;
731 
732  if (FMap->getMarkedCells(ORBIT_SELF, getSelectionMark(),
733  NULL, &dart1, &dart2) == 2)
734  {
735  if (!FMap->isSameOrbit(dart1, dart2, ORBIT_VERTEX))
736  {
737  nb = 1;
738  FMap->insertEdge(dart1, dart2);
739  }
740  }
741  else
742  nb = FMap->insertEdgeOnMarkedFaces(getSelectionMark(), true, true);
743 
744  if (nb == 0)
745  {
746  setMessage("No edge inserted");
748  }
749  else
750  {
752  setModelChanged();
753  setMessage(nb, nb == 1 ? " edge inserted" : " edges inserted");
754  res = true;
755  }
756  }
757 
758  return res;
759 }
760 //******************************************************************************
762 {
763  bool res = false;
765  {
766  undoRedoPreSave();
767 
768  int nb =
769  FMap->insertFaceOnMarkedVolumes(getSelectionMark(), true, true, true);
770 
771  if (nb == 0)
772  {
773  setMessage("No face inserted");
775  }
776  else
777  {
779  setModelChanged();
780  setMessage(nb, nb == 1 ? " face inserted" : " faces inserted");
781  res = true;
782  }
783  }
784 
785  return res;
786 }
787 //******************************************************************************
789 {
790  bool res = false;
793  {
794  undoRedoPreSave();
795 
796  int nb = FMap->intuitiveStopUpMarkedBorders(getSelectionMark());
797 
798  if (nb == 0)
799  {
800  setMessage("No border closed");
802  }
803  else
804  {
806  setModelChanged();
807  setMessage(nb, nb == 1 ? " border closed" : " borders closed");
808  res = true;
809  }
810  }
811 
812  return res;
813 }
814 //******************************************************************************
815 bool CControlerGMap::stopUp(int ADimension)
816 {
817  bool res = false;
819  {
820  undoRedoPreSave();
821 
822  int nb = FMap->stopUpMarkedBorders(getSelectionMark(), ADimension);
823 
824  if (nb == 0)
825  {
826  setMessage("No ", ADimension, "-border closed");
828  }
829  else
830  {
832  setModelChanged();
833  setMessage(nb, ADimension, nb == 1 ? "-border closed" :
834  "-borders closed");
835  res = true;
836  }
837  }
838 
839  return res;
840 }
841 //******************************************************************************
842