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