Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmg-quadrangulation.cc
Go to the documentation of this file.
1 /*
2  * lib-gmapkernel : Un noyau de 3-G-cartes et des opérations.
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-gmapkernel
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-generic.hh"
26 using namespace GMap3d;
27 //******************************************************************************
29  bool AInsertVertices /*true*/)
30 {
31  int nb = getNbPolylineEdges(ADart);
32  return (nb != 0) && (AInsertVertices || nb % 2 == 0);
33 }
34 //******************************************************************************
35 CDart * CGMapGeneric::quadrangulateFace(CDart * ADart, bool AInsertVertices)
36 {
37  assert(ADart!=NULL);
38  assert(canQuadrangulateFace(ADart, AInsertVertices));
39 
40  int treated = getNewMark();
41 
42  // Insertion de nouveaux sommets (chaque arête est coupée en deux):
43  if (AInsertVertices)
44  {
45  for (CStaticCoverage01 cov(this, ADart); cov.cont(); ++cov)
46  if (!isMarked(*cov, treated))
47  {
48  markOrbit(*cov, ORBIT_0, treated);
49  negateMaskMark(treated);
50  insertVertex(*cov);
51  negateMaskMark(treated);
52  }
53 
54  unmarkOrbit(ADart, ORBIT_01, treated);
55  }
56 
57  // Quadrangulation:
58  assert(canQuadrangulateFace(ADart, false));
59 
60  CStaticCoverage01 cov(this, ADart);
61  int toTreat = getNewMark();
62 
63  // Marquage des sommets qui doivent être traités (un sur deux):
64  for (; cov.cont(); ++cov)
65  {
66  if (isMarked(*cov, toTreat))
67  {
68  if (!isFree1(*cov))
69  setMark(alpha1(*cov), toTreat);
70  }
71  else
72  {
73  if (!isFree0(*cov))
74  setMark(alpha0(*cov), toTreat);
75  }
76  }
77 
78  for (cov.reinit(); cov.cont(); setMark(*cov, treated), ++cov)
79  if (isMarked(*cov, toTreat))
80  {
81  CDart * n1 = addMapDart();
82  CDart * n2 = addMapDart(); linkAlpha0(n1,n2);
83 
84  CDart * nn1 = NULL, * nn2 = NULL, * d3;
85 
86  if (isFree3(*cov))
87  d3=NULL;
88  else
89  {
90  d3=alpha3(*cov);
91  nn1=addMapDart();
92  nn2=addMapDart(); linkAlpha0(nn1,nn2);
93  linkAlpha3(n1,nn1);
94  linkAlpha3(n2,nn2);
95  }
96 
97  if (!isFree0(*cov) && !isFree1(alpha0(*cov)) &&
98  !isFree0(alpha01(*cov)) && isMarked(alpha010(*cov), treated))
99  {
100  linkAlpha1(n2,alpha01010(*cov));
101  if (d3!=NULL) linkAlpha1(nn2,alpha01010(d3));
102  }
103 
104  if (!isFree1(*cov) && isMarked(alpha1(*cov), treated))
105  {
106  topoSew2(n1,alpha1(alpha1(*cov)));
107  if (d3!=NULL) topoSew2(nn1,alpha1(alpha1(d3)));
108  }
109 
110  linkAlpha1(*cov,n1);
111  if (d3!=NULL) linkAlpha1(d3,nn1);
112  }
113 
114  for (cov.reinit(); cov.cont(); ++cov)
115  {
116  unsetMark(*cov, treated);
117  unsetMark(*cov, toTreat);
118  }
119 
120  freeMark(treated);
121  freeMark(toTreat);
122 
123  if (isFree0(ADart))
124  ADart = alpha1(ADart);
125 
126  assert(checkTopology());
127 
128  return alpha010(ADart);
129 }
130 //******************************************************************************
132  bool AInsertVertices)
133 {
134  int nbQuadrangulated = 0;
135 
136  int selected = getNewMark();
137 
138  // Sélection des faces qui peuvent être quadrangulées:
139 
140  int treated = getNewMark();
141  CDynamicCoverageAll it(this);
142 
143  for (; it.cont(); ++it)
144  if (!isMarked(*it, treated))
145  {
146  if (isMarked(*it, AMarkNumber))
147  {
148  if (canQuadrangulateFace(*it, AInsertVertices))
149  setMark(*it, selected);
150 
151  markOrbit(*it, ORBIT_FACE, treated);
152  }
153  else
154  setMark(*it, treated);
155  }
156 
157  negateMaskMark(treated);
158  freeMark(treated);
159 
160  // Insertion de nouveaux sommets (chaque arête est coupée en deux):
161 
162  if (AInsertVertices)
163  {
164  int edges = getNewMark();
165 
166  markIncidentCells(ORBIT_01, selected, edges);
167 
169 
170  unmarkAll(edges);
171  freeMark(edges);
172  }
173 
174  // Quadrangulation:
175 
176  for (it.reinit(); it.cont(); ++it)
177  if (isMarked(*it, selected))
178  {
179  quadrangulateFace(*it, false);
180  ++nbQuadrangulated;
181  unsetMark(*it, selected);
182  }
183 
184  freeMark(selected);
185 
186  return nbQuadrangulated;
187 }
188 //******************************************************************************