Code_TYMPAN  4.2.0
Industrial site acoustic simulation
TYElementPicker.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14 */
15 
30 #include "TYElementPicker.h"
31 
32 
34 static const float ElementPickerTolerance = 0.01f;
35 
37 static const float MaillagePickingTolerance = 1.0f;
38 
40 #define BUFSIZE 512
41 
42 
44 {
45  Q_CHECK_PTR(pModeler);
46  _pModeler = pModeler;
47 
48  _pLastPickedElt = NULL;
50  //_pOutlineActor = NULL;//az--: plus utilise
51 
52  _x = 0;
53  _y = 0;
54 }
55 
57 {
58 }
59 
60 bool TYElementPicker::pick(int x, int y)
61 {
62  bool res = true;
63 
64  _x = x;
65  _y = y;
66 
67  GLuint selectBuf[BUFSIZE], names, *ptr;
68  GLint hits;
69 
70  glSelectBuffer(BUFSIZE, selectBuf);
71  (void) glRenderMode(GL_SELECT);
72 
73  glInitNames();
74 
75  _pModeler->getView()->getRenderer()->OpenGLRender(GL_SELECT, x, y);
76 
77  hits = glRenderMode(GL_RENDER);
78 
79  _pLastPickedElt = NULL;
80  int i, j;
81 
82  ptr = (GLuint*) selectBuf;
83 
84  TYElement* pElementAutreQueAltimetrie = NULL;//az++
85  float zmin = (float)0xFFFFFFFF; //az++
86  float zElementAutreQueAltimetrie = -1;
87 
88  for (i = 0; i < hits; i++) //Pour chaque primitive OpenGL
89  {
90  // nombre de noms
91  names = *ptr; ptr++;//Recuperer la liste de nom correspondant a ce hit
92  // z1 : distance minimale, toujours positive
93  float z1 = *ptr; ptr++;
94  // z2 : distance maximale, toujours positive
95  ptr++;
96 
97  TYElement* pElementCourant = NULL;//az++
98  QString sCurrentClassName;
99  for (j = 0; j < (int)names; j++)
100  {
101  pElementCourant = TYPickingTable::getElement(*ptr);
102  sCurrentClassName = QString(pElementCourant->getClassName());
103  if (sCurrentClassName != "TYAltimetrie")
104  {
105  if (NULL == pElementAutreQueAltimetrie)
106  {
107  pElementAutreQueAltimetrie = pElementCourant;
108  zElementAutreQueAltimetrie = z1;
109  }
110  else
111  {
112  if (z1 < zElementAutreQueAltimetrie)
113  {
114  pElementAutreQueAltimetrie = pElementCourant;
115  zElementAutreQueAltimetrie = z1;
116  }
117  else if (z1 == zElementAutreQueAltimetrie)
118  {
119  //Cas des cheminees et autres bouches sur Face, voir des fenetres sur les murs
120  if (pElementAutreQueAltimetrie == pElementCourant->getParent())
121  {
122  pElementAutreQueAltimetrie = pElementCourant;
123  zElementAutreQueAltimetrie = z1;
124  }
125  }
126  }
127  }
128  else
129  {
130  if (z1 < zmin) //az++
131  {
132  //on s'interresse aux z les plus proches
133  zmin = z1;
135  }
136  }
137  ptr++;
138  }
139  }
140  if (pElementAutreQueAltimetrie)
141  {
142  _pLastPickedElt = pElementAutreQueAltimetrie;
143  }
144 
146 
147  if (_pLastPickedElt)
148  {
149  writeDebugMsg(QString("Element picke de type : ") + QString(_pLastPickedElt->getClassName()));
150 
151  // Qq chose de picker
153 
154  // Recherche des parents
156  }
157  else
158  {
159  res = false;
160  }
161 
162  return res;
163 }
164 
166 {
167  bool change = false;
168 
170  {
173  }
174 
175  if (!pElt)
176  {
177  return;
178  }
179 
180  if (_pHighlightedGraphicObject != pElt->getGraphicObject())
181  {
182  change = true;
183  }
184 
185  if (!pElt->isA("TYPoint"))
186  {
187  // On conserve un pointeur sur l'objet graphique
188  _pHighlightedGraphicObject = pElt->getGraphicObject();
190  }
191 
192  if (change) { _pModeler->getView()->getRenderer()->updateDisplayList(); }//az++ test
193 
194  _pModeler->updateView(false, false);
195 }
196 
198 {
200  {
203  }
204 
205  _pLastPickedElt = NULL;
206  _pModeler->getView()->getRenderer()->updateDisplayList();//az++ test
207 
208  _pModeler->getView()->updateGL();
209 }
210 
212 {
213  if (!pElt)
214  {
215  return;
216  }
217 
218  std::shared_ptr<LPTYElementArray> pElts (new LPTYElementArray());
219  TYElement* pTmpElt = pElt;
220 
221  while (pTmpElt != NULL)
222  {
223  // Cas particulier du maillage
224  TYMaillage* pMail = dynamic_cast<TYMaillage*>(pTmpElt);
225  if (pMail != nullptr)
226  {
227  // Recherche du point de calcul clicke
228  TYElement* pPtCalcul = findPointCalculOnMaillage(pMail);
229 
230  // Detecte le type pour emettre le signal
231  if (checkType(pPtCalcul))
232  {
233  // Ajout
234  pElts->push_back(pPtCalcul);
235  }
236  }
237 
238  // Detecte le type pour emettre le signal
239  checkType(pTmpElt); // DT-- le 31/08/04
240 
241  // Ajoute a la collection
242  pElts->push_back(pTmpElt);
243 
244  // Recupere le parent
245  pTmpElt = pTmpElt->getParent();
246  }
247 
248  // Au moins un parent a ete trouve
249  if (pElts->size() > 1)
250  {
251  // On signale le dernier parent trouve.
252  emit(highestParentPicked(pElts->back()));
253  }
254 
255  emit(elementCollectionPicked(pElts));
256 }
257 
259 {
260  if (!pElt)
261  {
262  return false;
263  }
264 
265  bool ret = true;
266 
267  if (pElt->isA("TYPoint"))
268  {
269  emit(pointPicked(pElt));
270  }
271  else if (pElt->isA("TYPointCalcul"))
272  {
273  emit(pointCalculPicked(pElt));
274  }
275  else if (pElt->isA("TYPointControl"))
276  {
277  emit(pointControlPicked(pElt));
278  }
279  else if (pElt->isA("TYTerrain"))
280  {
281  emit(terrainPicked(pElt));
282  }
283  else if (pElt->isA("TYPlanEau"))
284  {
285  emit(planEauPicked(pElt));
286  }
287  else if (pElt->isA("TYCourbeNiveau"))
288  {
289  emit(courbeNiveauPicked(pElt));
290  }
291  else if (pElt->isA("TYUserSourcePonctuelle"))
292  {
293  emit(sourcePonctuellePicked(pElt));
294  }
295  else if (pElt->isA("TYAcousticLine"))
296  {
297  emit(acousticLinePicked(pElt));
298  }
299  else if (pElt->isA("TYReseauTransport"))
300  {
301  emit(reseauTransportPicked(pElt));
302  }
303 #if WITH_NMPB
304  else if (pElt->isA("TYRoute"))
305  {
306  emit(routePicked(pElt));
307  }
308 #endif
309  else if (pElt->isA("TYCoursEau"))
310  {
311  emit(coursEauPicked(pElt));
312  }
313  else if (pElt->isA("TYAcousticRectangle"))
314  {
315  emit(acousticRectanglePicked(pElt));
316  }
317  else if (pElt->isA("TYMurElement"))
318  {
319  emit(murElementPicked(pElt));
320  }
321  else if (pElt->isA("TYDalle"))
322  {
323  emit(dallePicked(pElt));
324  }
325  else if (pElt->isA("TYAcousticCircle"))
326  {
327  emit(acousticCirclePicked(pElt));
328  }
329  else if (pElt->isA("TYAcousticSemiCircle"))
330  {
331  emit(acousticSemiCirclePicked(pElt));
332  }
333  else if (pElt->isA("TYAcousticCylinder"))
334  {
335  emit(acousticCylinderPicked(pElt));
336  }
337  else if (pElt->isA("TYAcousticSemiCylinder"))
338  {
339  emit(acousticSemiCylinderPicked(pElt));
340  }
341  else if (pElt->isA("TYMaillage"))
342  {
343  emit(maillagePicked(pElt));
344  }
345  else if (pElt->isA("TYRectangularMaillage"))
346  {
347  emit(rectangularMaillagePicked(pElt));
348  }
349  else if (pElt->isA("TYLinearMaillage"))
350  {
351  emit(linearMaillagePicked(pElt));
352  }
353  else if (pElt->isA("TYAcousticRectangleNode"))
354  {
355  emit(acousticRectangleNodePicked(pElt));
356  }
357  else if (pElt->isA("TYMur"))
358  {
359  emit(murPicked(pElt));
360  }
361  else if (pElt->isA("TYAcousticBox"))
362  {
363  emit(acousticBoxPicked(pElt));
364  }
365  else if (pElt->isA("TYAcousticVolumeNode"))
366  {
367  emit(acousticVolumeNodePicked(pElt));
368  }
369  else if (pElt->isA("TYEtage"))
370  {
371  emit(etagePicked(pElt));
372  }
373  else if (pElt->isA("TYMachine"))
374  {
375  emit(machinePicked(pElt));
376  }
377  else if (pElt->isA("TYBatiment"))
378  {
379  emit(batimentPicked(pElt));
380  }
381  else if (pElt->isA("TYTopographie"))
382  {
383  emit(topographiePicked(pElt));
384  }
385  else if (pElt->isA("TYSiteNode"))
386  {
387  emit(sitePicked(pElt));
388  }
389  else if (pElt->isA("TYSiteNode")) //???
390  {
391  emit(siteNodePicked(pElt));
392  }
393  else if (pElt->isA("TYEcran"))
394  {
395  emit(ecranPicked(pElt));
396  }
397  else if (pElt->isA("TYAcousticFaceSet"))
398  {
399  emit(acousticFaceSetPicked(pElt));
400  }
401  else
402  {
403  ret = false;
404  }
405 
406  return ret;
407 }
408 
410 {
411  Q_ASSERT(pMaillage);
412  TYPointCalcul* pPtCalcul = NULL;
413 
414  float mapperPos[2];
415  mapperPos[0] = _x; mapperPos[1] = _y;
416 
417  for (unsigned int i = 0; i < pMaillage->getPtsCalcul().size(); i++)
418  {
419  pPtCalcul = pMaillage->getPtsCalcul()[i];
420  Q_ASSERT(pPtCalcul);
421 
422  if ((mapperPos[0] <= pPtCalcul->_x + MaillagePickingTolerance) && (mapperPos[0] >= pPtCalcul->_x - MaillagePickingTolerance) &&
423  (mapperPos[1] >= pPtCalcul->_y - MaillagePickingTolerance) && (mapperPos[1] <= pPtCalcul->_y + MaillagePickingTolerance))
424  {
425  // Point trouve
426  return pPtCalcul;
427  }
428  }
429 
430  return NULL;
431 }
void sourcePonctuellePicked(TYElement *pElt)
void ecranPicked(TYElement *pElt)
void courbeNiveauPicked(TYElement *pElt)
#define BUFSIZE
Taille du buffer pour le picking.
gestion des elements selectionnes par picking (fichier header)
void pointPicked(TYElement *pElt)
TYElement * _pLastPickedElt
Le dernier element picke.
bool checkType(TYElement *pElt)
Teste le type de l&#39;element passe et emet le signal correspondant au type, avec en parametre l&#39;element...
bool pick(int x, int y)
Effectue un picking en (x, y).
void acousticCirclePicked(TYElement *pElt)
void machinePicked(TYElement *pElt)
void etagePicked(TYElement *pElt)
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:338
void pointControlPicked(TYElement *pElt)
outil IHM pour un objet metier de type TYElement (fichier header)
virtual void updateView(bool clipping=true, bool axesAndGrid=true)
void topographiePicked(TYElement *pElt)
virtual void updateGL()
Classe generique pour une fenetre de modeleur.
void acousticSemiCirclePicked(TYElement *pElt)
void acousticBoxPicked(TYElement *pElt)
void acousticLinePicked(TYElement *pElt)
pour l&#39;application Tympan (fichier header)
void sitePicked(TYElement *pElt)
void updateDisplayList(void)
void acousticRectanglePicked(TYElement *pElt)
void acousticRectangleNodePicked(TYElement *pElt)
void planEauPicked(TYElement *pElt)
bool isA(const char *className) const
Definition: TYElement.cpp:70
Classe generique pour une fenetre de modeleur (fichier header)
TYPointCalcul * findPointCalculOnMaillage(TYMaillage *pMaillage)
Effectue un picking sur un maillage.
void rectangularMaillagePicked(TYElement *pElt)
void maillagePicked(TYElement *pElt)
TYElement * getParent() const
Definition: TYElement.h:656
void acousticVolumeNodePicked(TYElement *pElt)
TYElementPicker(TYModelerFrame *pModeler)
TYOpenGLRenderer * getRenderer()
double _y
y coordinate of OCoord3D
Definition: 3d.h:281
static TYElement * getElement(int index)
double _x
x coordinate of OCoord3D
Definition: 3d.h:280
void reset()
Retourne dans son etat initial.
static void purgeElements()
void reseauTransportPicked(TYElement *pElt)
void highestParentPicked(TYElement *pElt)
Indique qu&#39;un element parent a ete picke, ce sera le dernier parent de l&#39;element de base picke...
void acousticSemiCylinderPicked(TYElement *pElt)
void writeDebugMsg(QString msg)
Affiche un message de debug dans la fenetre de sortie.
int _y
Position courante en y.
void batimentPicked(TYElement *pElt)
virtual const char * getClassName() const
Definition: TYElement.h:248
void murElementPicked(TYElement *pElt)
Gestion de la table de correspondance indice/element pour le picking (fichier header) ...
void acousticFaceSetPicked(TYElement *pElt)
void pointCalculPicked(TYElement *pElt)
void elementPicked(TYElement *pElt)
Indique qu&#39;un element a ete picke, sans connaitre son type. Celui-ci sera de type "bas niveau"...
void linearMaillagePicked(TYElement *pElt)
Objet pour le picking graphique (fichier header)
void routePicked(TYElement *pElt)
void highlightElement(TYElement *pElt)
Dessine la boite englobante de l&#39;element passe.
void dallePicked(TYElement *pElt)
TYRenderWindowInteractor * getView()
TYModelerFrame * _pModeler
Le modeler dans lequel on effectue le picking.
LPTYElementGraphic _pHighlightedGraphicObject
Pointeur sur le dernier objet graphique highlighte.
Classe de definition d&#39;un maillage.
Definition: TYMaillage.h:51
void acousticCylinderPicked(TYElement *pElt)
Classe de definition d&#39;un point de calcul.C&#39;est une classe derivee a TYPoint avec en plus un spectrep...
Definition: TYPointCalcul.h:33
void terrainPicked(TYElement *pElt)
TYTabLPPointCalcul & getPtsCalcul()
Set/Get de la liste des points de calcul.
Definition: TYMaillage.h:116
void murPicked(TYElement *pElt)
void siteNodePicked(TYElement *pElt)
void coursEauPicked(TYElement *pElt)
void elementCollectionPicked(std::shared_ptr< LPTYElementArray > pElts)
Indique qu&#39;un element a ete picke, sans connaitre son type. La collection d&#39;elements pickes est compo...
void OpenGLRender(GLenum mode=GL_RENDER, int x=0, int y=0)
void updateParents(TYElement *pElt)
Parcours les parents depuis le dernier element picke et emets les signaux correcpondants.
void highlight(bool state=true)
int _x
Position courante en x.