Moka controlers
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
precompile-dart.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 "controler-gmap-types.hh"
26 #include "view.hh"
27 #include "precompile-dart.hh"
28 #include "dart-vertex.hh"
29 #include "parameter-gmap-vertex.hh"
30 #include "parameter-dart.hh"
31 #include "parameter-selection.hh"
32 #include <cassert>
33 #include <climits>
34 using namespace GMap3d;
35 //******************************************************************************
37  CParameterDart * AParameterDart,
38  CParameterSelection * AParameterSelection) :
39  FParameterGMapV(AParameterGMapV),
40  FParameterDart(AParameterDart),
41  FParameterSelection(AParameterSelection)
42 {
43  assert(FParameterGMapV != NULL && FParameterDart != NULL);
44 
45  FParameterGMapV->addPrecompileToUpdate(this);
46  FParameterDart->addPrecompileToUpdate(this);
47 
48  if (FParameterSelection != NULL)
49  FParameterSelection->addPrecompileToUpdate(this);
50 }
51 //******************************************************************************
53  CPrecompile(APrecompile),
54  FParameterGMapV(APrecompile.FParameterGMapV),
55  FParameterDart(static_cast<CParameterDart*>
56  (APrecompile.FParameterDart->copy())),
57  FParameterSelection(APrecompile.FParameterSelection)
58 {
59  assert(FParameterGMapV != NULL && FParameterDart != NULL);
60 
61  FParameterGMapV->addPrecompileToUpdate(this);
62  FParameterDart->addPrecompileToUpdate(this);
63 
64  if (FParameterSelection != NULL)
65  FParameterSelection->addPrecompileToUpdate(this);
66 }
67 //******************************************************************************
69 {
70  FParameterGMapV->removePrecompileToUpdate(this);
71  FParameterDart->removePrecompileToUpdate(this);
72 
73  if (FParameterSelection != NULL)
74  FParameterSelection->removePrecompileToUpdate(this);
75 }
76 //******************************************************************************
78 { return new CPrecompileDart(*this); }
79 //******************************************************************************
81 {
82  switch (AParameter->getType())
83  {
85  setGMapVertex(static_cast<CParameterGMapVertex *>(AParameter));
86  break;
87  case PARAMETER_DART:
88  setDart(static_cast<CParameterDart *>(AParameter));
89  break;
91  setSelection(static_cast<CParameterSelection *>(AParameter));
92  break;
93  }
94 }
95 //******************************************************************************
97 { return FParameterDart; }
98 //******************************************************************************
100 {
101  assert(AParameterGMapV != NULL);
102  AParameterGMapV->addPrecompileToUpdate(this);
103  FParameterGMapV->removePrecompileToUpdate(this);
104  FParameterGMapV = AParameterGMapV;
105  setToUpdate();
106 }
107 //******************************************************************************
109 {
110  assert(ADart != NULL);
111  ADart->addPrecompileToUpdate(this);
112  FParameterDart->removePrecompileToUpdate(this);
113  FParameterDart = ADart;
114  setToUpdate();
115 }
116 //******************************************************************************
118 {
119  if (ASelection != NULL)
120  ASelection->addPrecompileToUpdate(this);
121 
122  if (FParameterSelection != NULL)
123  FParameterSelection->removePrecompileToUpdate(this);
124 
125  FParameterSelection = ASelection;
126  setToUpdate();
127 }
128 //******************************************************************************
130 { return PRECOMPILE_DART; }
131 //******************************************************************************
132 CDart* CPrecompileDart::nextDartAlpha(CDart* ADart, unsigned int ADim)
133 {
134  assert(ADim<=3);
135 
136  if ( !FParameterGMapV->getModeSimplification() || ADim==3 )
137  return ADart->getAlpha(ADim);
138 
139  assert(!FParameterGMapV->getDrawingMap()->
140  isMarked(ADart,FParameterGMapV->getMarkRemoved(ADim)));
141  CDart* res = ADart->getAlpha(ADim);
142  while ( FParameterGMapV->getDrawingMap()->
143  isMarked(res,FParameterGMapV->getMarkRemoved(ADim)) )
144  {
145  res = res->getAlpha(ADim+1)->getAlpha(ADim);
146  }
147  return res;
148 }
149 //******************************************************************************
150 void CPrecompileDart::drawOneEdge(CDart * ADart)
151 {
152  if ( !FParameterGMapV->getModeSimplification() ||
153  FParameterGMapV->getDrawingMap()->isFree0(ADart) )
154  return;
155 
156  CDart* start = FParameterGMapV->getDartWithEmbedding(ADart);
157  CDart* end = FParameterGMapV->getDartWithEmbedding(ADart->getAlpha(0));
158  while ( start!=end )
159  {
160  start = start->getAlpha(0);
161  if (start!=end)
162  {
163  drawOneDart(start);
164  start = nextDartAlpha(start,1);
165  if (start!=end) drawOneDart(start);
166  }
167  }
168 }
169 //******************************************************************************
170 void CPrecompileDart::drawOneDart(CDart * ADart)
171 {
172  CVertex * v1 = &FParameterGMapV->getDrawingMap()->getBurstVertex(ADart);
173 
174  if (FParameterGMapV->getDrawingMap()->isFree0(ADart))
175  {
176  // Affichage d'un point pour les brins 0-libres
177  glBegin(GL_POINTS);
178  PLOT(v1);
179  glEnd();
180  }
181  else
182  {
183  // Affichage de l'arête pour les brins 0-cousus
184  CVertex v2 = FParameterGMapV->getDrawingMap()->
185  computeBurstExtremity(ADart);
186  glBegin(GL_LINES);
187  LINE(v1, &v2);
188  glEnd();
189  }
190 }
191 //******************************************************************************
193 {
194  glLineWidth(FParameterDart->getLWDarts());
195  glPointSize(FParameterDart->getSAloneDarts());
196 
197  CVertex m;
198  const GLfloat * clSel = NULL;
199  const GLfloat * clUnsel = NULL;
200  const GLfloat * clLast = NULL;
201  const GLfloat * cl0Remove= NULL;
202  const GLfloat * cl1Remove= NULL;
203  int mark = -1;
204 
205  CDart * last = NULL;
206 
207  if (FParameterSelection != NULL)
208  {
209  mark = FParameterSelection->getSelectionMark();
210  last = FParameterSelection->getLastSelectedDart();
211 
212  clSel = FParameterDart->
213  getCLSel(FParameterSelection->getSelectionLevel());
214  clUnsel = FParameterDart->
215  getCLUnsel(FParameterSelection->getSelectionLevel());
216  clLast = FParameterDart->
217  getCLLastSel(FParameterSelection->getSelectionLevel());
218  cl0Remove= FParameterDart->
219  getCL0Remove(FParameterSelection->getSelectionLevel());
220  cl1Remove= FParameterDart->
221  getCL1Remove(FParameterSelection->getSelectionLevel());
222  }
223  else
224  clSel = FParameterDart->getCLUnsel(0);
225 
226  // 1) Draw the remove darts
227  if ( FParameterGMapV->getModeSimplification() )
228  {
229  glColor3fv(cl1Remove);
230  for (CDynamicCoverageAll it(FParameterGMapV->getMapEmbedding());
231  it.cont(); ++it)
232  {
233  if ( FParameterGMapV->getMapEmbedding()->
234  isMarked(*it, FParameterGMapV->getMarkRemoved(1)))
235  drawOneDart(*it);
236  }
237  }
238 
239  CDynamicCoverageAll it(FParameterGMapV->getMap());
240 
241  // Dessin des brins non sélectionnés :
242  for (; it.cont(); ++it)
243  if (mark == -1 || !FParameterGMapV->getMap()->isMarked(*it, mark))
244  {
245  glColor3fv(clUnsel);
246  drawOneDart(FParameterGMapV->getDartWithEmbedding(*it));
247  if ( FParameterGMapV->getModeSimplification() )
248  {
249  glColor3fv(cl0Remove);
250  drawOneEdge(*it);
251  }
252  }
253 
254  if (mark != -1)
255  {
256  // Dessin des brins sélectionnés différents du "last"
257  glColor3fv(clSel);
258  for (it.reinit(); it.cont(); ++it)
259  if (FParameterGMapV->getMap()->isMarked(*it, mark) && *it != last)
260  {
261  drawOneDart(FParameterGMapV->getDartWithEmbedding(*it));
262  drawOneEdge(*it);
263  }
264  }
265 
266  // Dessin du dernier brin sélectionné
267  if (last != NULL)
268  {
269  glColor3fv(clLast);
270  drawOneDart(FParameterGMapV->getDartWithEmbedding(last));
271  drawOneEdge(last);
272  }
273 }
274 //******************************************************************************
275 #define DMAX (20) // Distance maximum pour la sélection d'un segment.
276 #define RFREE (6) // Distance maximum pour la sélection d'un point.
277 //******************************************************************************
278 float distanceToSegment(float x, float y, float x1, float y1,
279  float x2, float y2)
280 {
281 #define SQR(X) (sqr((double)(X)))
282 
283  float xa = MIN(x1, x2) - DMAX;
284  float xb = MAX(x1, x2) + DMAX;
285  float ya = MIN(y1, y2) - DMAX;
286  float yb = MAX(y1, y2) + DMAX;
287 
288  if (x < xa || x > xb || y < ya || y > yb)
289  return INT_MAX;
290 
291  // Distance à un point:
292  if (x1 == x2 && y1 == y2)
293  return sqr(x -x1) + SQR(y - y1) - RFREE * RFREE;
294 
295  double k = - double((x1 - x2) * (x - x1) + (y - y1) * (y1 - y2)) /
296  (SQR(x1 - x2) + SQR(y1 - y2));
297 
298  // On est en dehors de la bande et du coté du point (x1,y1)
299  if (k <= 0) return sqr(x -x1) + sqr(y - y1);
300 
301  // On est en dehors de la bande et du coté du point (x2,y2)
302  if (k >= 1) return sqr(x -x2) + sqr(y - y2);
303 
304  // On est dans la bande du segment, il faut calculer la distance à la droite
305  return sqr(k*(x2 - x1) + x1 - x) + sqr(k*(y2 - y1) + y1 - y);
306 }
307 //******************************************************************************
308 void CPrecompileDart::pick(int AX, int AY, CView* AView)
309 {
310  assert(AView != NULL);
311 
312  CDart* nearest = NULL;
313  float bestDist = DMAX * DMAX;
314 
315  for (CDynamicCoverageAll it(FParameterGMapV->getMap()); it.cont(); ++it)
316  {
317  CDart* current = *it;
318 
319  CVertex& v1 = FParameterGMapV->getDrawingMap()->
320  getBurstVertex(FParameterGMapV->getDartWithEmbedding(current));
321 
322  float seg1[3], seg2[3];
323 
324  AView->project(v1.getX(), v1.getY(), v1.getZ(), seg1);
325 
326  if (FParameterGMapV->getMap()->isFree0(current))
327  {
328  seg2[0] = seg1[0];
329  seg2[1] = seg1[1];
330  }
331  else
332  {
333  CVertex e = FParameterGMapV->getDrawingMap()->
334  computeBurstExtremity(FParameterGMapV->getDartWithEmbedding(current));
335  AView->project(e.getX(), e.getY(), e.getZ(), seg2);
336  }
337 
338  float currentDist = distanceToSegment(AX, AY,
339  seg1[0], seg1[1],
340  seg2[0], seg2[1]);
341 
342  if (currentDist < bestDist)
343  {
344  nearest = current;
345  bestDist = currentDist;
346  }
347  }
348 
349  if (nearest != NULL)
350  FParameterSelection->toggleOrbitSelection(nearest);
351 }
352 //******************************************************************************