Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYPickEditor.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 
21 #include <qdialog.h>
22 #include <qpushbutton.h>
23 #include <qcheckbox.h>
24 #include <qlineedit.h>
25 #include <qlabel.h>
26 #include <qlayout.h>
27 #include <qmenu.h>
28 #include <qpainter.h>
29 #include <qcursor.h>
30 #include <qinputdialog.h>
31 #include <QMessageBox>
32 #include <QBoxLayout>
33 #include <QPixmap>
34 #include <QGridLayout>
35 #include <QHBoxLayout>
36 #include <QMdiArea>
37 #include <QMdiSubWindow>
38 
39 #include "Tympan/core/logging.h"
65 #include "TYPickEditor.h"
66 
67 #define TR(id) OLocalizator::getString("TYPickEditor", (id))
68 #define IMG(id) OLocalizator::getPicture("TYPickEditor", (id))
69 
70 // using namespace Qt;
71 
73 {
74  _useHighlight = true;
75  _usePopup = true;
76 
77  // On recupere le pointeur sur le picker du modeler
79 
80  setPickTolerance(3.0f);
82 
83  _pLastRolloverElt = nullptr;
84 }
85 
87 
88 void TYPickEditor::slotMousePressed(int x, int y, Qt::MouseButton button, Qt::KeyboardModifiers state)
89 {
90  if (_pModeler->hasFocus() && _pLastRolloverElt)
91  {
93  {
94  hidePanel();
95  _pModeler->getView()->update();
96  }
97  }
98 
99  _lastPressedCurPos.setX(x);
100  _lastPressedCurPos.setY(y);
101 }
102 
103 void TYPickEditor::slotMouseReleased(int x, int y, Qt::MouseButton button, Qt::KeyboardModifiers state)
104 {
105  if ((x >= _lastPressedCurPos.x() + _pickTolerance) || (x <= _lastPressedCurPos.x() - _pickTolerance) ||
107  {
108  return;
109  }
110 
111  bool doPick = false;
112 
113  if ((button == Qt::RightButton) || (button == Qt::LeftButton))
114  {
115  // Connections
116  if (_useHighlight || (button == Qt::RightButton))
117  {
120  doPick = true;
121  }
122  if ((button == Qt::RightButton) && _usePopup)
123  {
124  QObject::connect(_pPicker, &TYElementPicker::elementCollectionPicked, this,
126  doPick = true;
127  }
128 
129  // Picking
130  if (doPick)
131  {
132  if (!_pPicker->pick(x, _pInteractor->getViewport().height() - y))
133  {
134  resetPicker();
135  }
136 
137  // Deconnections
138  QObject::disconnect(_pPicker, &TYElementPicker::elementPicked, _pPicker,
140  QObject::disconnect(_pPicker, &TYElementPicker::elementCollectionPicked, this,
142  }
143  }
144 }
145 
146 void TYPickEditor::slotMouseMoved(int x, int y, Qt::MouseButtons button, Qt::KeyboardModifiers state)
147 {
148  // Si un bouton est enfonce, on retourne
149  if ((button == Qt::RightButton) || (button == Qt::LeftButton))
150  {
151  return;
152  }
153 
154  _lastMovedCurPos.setX(x);
155  _lastMovedCurPos.setY(y);
156 
157  // Si le modeleur peut contenir un maillage (TYSiteModelerFrame)
158  if ((QString(_pModeler->metaObject()->className()).compare("TYSiteModelerFrame") == 0) &&
159  _pModeler->hasFocus())
160  {
161  // On cherche a savoir si au moins un maillage est visible
162  bool hasMaillage = false;
163  LPTYProjet pProj = getTYApp()->getCurProjet();
164  if (pProj != nullptr)
165  {
166  TYTabMaillageGeoNode& pMaillages = pProj->getMaillages();
167  for (int i = 0; i < pMaillages.size(); ++i)
168  {
169  if (pMaillages[i]->getGraphicObject()->getVisible())
170  {
171  hasMaillage = true;
172  break;
173  }
174  }
175  }
176 
177  // Si au moins un maillage est visible
178  if (hasMaillage)
179  {
180  // Si le modeleur n'est pas en vue en perspective
182  {
183  // Si aucun bouton n'est enfonce
184  if (state == Qt::NoButton)
185  {
186  // Connection
187  QObject::connect(_pPicker, &TYElementPicker::elementPicked, this,
189 
190  // Picking
191  if (!_pPicker->pick(x, _pInteractor->getViewport().height() - y))
192  {
193  hidePanel();
194  }
195 
196  // Deconnection
197  QObject::disconnect(_pPicker, &TYElementPicker::elementPicked, this,
199 
200  // On met a jour la vue
201  _pModeler->getView()->update();
202  }
203  }
204  }
205  }
206 }
207 
208 void TYPickEditor::slotWheeled(int x, int y, int delta, Qt::KeyboardModifiers state)
209 {
210  if (_pModeler->hasFocus() && _pLastRolloverElt)
211  {
213  {
214  hidePanel();
215  _pModeler->getView()->update();
216  }
217  }
218 }
219 
221 {
222  if (key == Qt::Key_Escape)
223  {
224  // (un update est fait dans le reset)
225  resetPicker();
226  }
227 }
228 
230 {
231  if (_pModeler->hasFocus() && _pLastRolloverElt)
232  {
234  {
235  hidePanel();
236  _pModeler->getView()->update();
237  }
238  }
239 }
240 
241 // TODO : What's this monster ?!? Circa 1300 lines of code full of if ?!?
242 void TYPickEditor::showPopupMenu(std::shared_ptr<LPTYElementArray> pElts)
243 {
244  if (!pElts)
245  {
246  return;
247  }
248 
249  if (QString(_pModeler->metaObject()->className()).compare("TYSiteModelerFrame") == 0)
250  {
251  siteModelerPopupMenu(pElts);
252  }
253  else if (QString(_pModeler->metaObject()->className()).compare("TYMachineModelerFrame") == 0)
254  {
256  }
257  else if (QString(_pModeler->metaObject()->className()).compare("TYBatimentModelerFrame") == 0)
258  {
260  }
261 
262  // Deselection
263  resetPicker();
264 
265  TYProjet* pProjet = getTYApp()->getCurProjet();
266  if (pProjet)
267  {
268  pProjet->getSite()->getTopographie()->updateGraphicTree();
269  }
270  // Update
271  getTYMainWnd()->updateModelers(true, true, true); // xbh++
272 }
273 
274 void TYPickEditor::siteModelerPopupMenu(std::shared_ptr<LPTYElementArray> pElts)
275 {
276  // Check site existance
277  TYSiteModelerFrame* pModelerFrame = dynamic_cast<TYSiteModelerFrame*>(_pModeler);
278  TYSiteNode* pModelerSite = nullptr;
279  if (pModelerFrame)
280  {
281  pModelerSite = pModelerFrame->getSite();
282  }
283  if (pModelerSite == nullptr)
284  {
285  return;
286  }
287 
288  QMenu* pPopup = new QMenu(nullptr);
289 
290  std::map<QAction*, int> retCodes;
291  std::map<QAction*, TYGeometryNode*> posRetCodes;
292  std::map<QAction*, TYGeometryNode*> rotRetCodes;
293  std::map<QAction*, TYSiteNode*> copySiteNodeRetCodes;
294  std::map<QAction*, TYSiteNode*> remSiteNodeRetCodes;
295  std::map<QAction*, TYAcousticVolumeNode*> calculVolNodeRetCodes;
296  QAction* inverseNormales = NULL;
297  std::map<QAction*, TYMaillage*> copyMaillageRetCodes;
298  std::map<QAction*, TYMaillage*> remMaillageRetCodes;
299  std::map<QAction*, TYPointControl*> copyPtControlRetCodes;
300  std::map<QAction*, TYPointControl*> remPtControlRetCodes;
301  QAction* split = NULL;
302  std::map<QAction*, TYElement*> copyTopoRetCodes;
303  std::map<QAction*, TYElement*> remTopoRetCodes;
304  std::map<QAction*, TYElement*> copyInfraRetCodes;
305  std::map<QAction*, TYElement*> remInfraRetCodes;
306  QAction* code = NULL;
307 
308  LPTYElement pRemovedEltParent = NULL;
309  LPTYElement pAddedElt = NULL;
310 
311  int volumeFound = -2, levelCurveFound = -2;
312 
313  QFont font = pPopup->font();
314  font.setBold(true);
315  TYElement* elem_0 = nullptr; // Currrent element
316  TYElement* elem_1 = nullptr; // next in queue
317  TYElement* elem_2 = nullptr; // 2nd level next in queue
318  for (unsigned int i = 0; i < pElts->size(); i++)
319  {
320  elem_0 = pElts->at(i); // Currrent element
321  if ((i + 1) < pElts->size())
322  {
323  elem_1 = pElts->at(i + 1)._pObj;
324  }
325  if ((i + 2) < pElts->size())
326  {
327  elem_2 = pElts->at(i + 2)._pObj;
328  }
329 
330  TYSiteNode* pCurrentSite = dynamic_cast<TYSiteNode*>(elem_0);
331 
332  // Edition des proprietes de l'element (quelque soit l'element)
333  QString labelTxt;
334  if ((pCurrentSite != nullptr) && (pCurrentSite->getRoot()))
335  {
336  labelTxt = TR("id_popup_siteroot");
337  }
338  else
339  {
340  labelTxt = TYWidget::getDisplayName(pElts->at(i));
341  }
342  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_editeelt"))), labelTxt);
343  code->setFont(font);
344  retCodes[code] = i;
345 
346  if (pCurrentSite != nullptr) // Current element is a site
347  {
348  // Recherche du site parent
349  TYSiteNode* pCurrentSiteParent = nullptr;
350  if (i + 1 < pElts->size())
351  {
352  pCurrentSiteParent = dynamic_cast<TYSiteNode*>(elem_1);
353  }
354 
355  if (pCurrentSiteParent == pModelerSite)
356  {
357  // GeoNode
358  TYGeometryNode* pEltGeoNode = TYGeometryNode::GetGeoNode(pCurrentSite);
359 
360  // Position
361  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_moving"))), TR("id_popup_position"));
362  posRetCodes[code] = pEltGeoNode;
363 
364  // Rotation
365  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_rotation"))), TR("id_popup_rotation"));
366  rotRetCodes[code] = pEltGeoNode;
367 
368  // Duplication
369  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_duplicate"))), TR("id_popup_duplicate"));
370  copySiteNodeRetCodes[code] = pCurrentSite;
371 
372  // Suppression
373  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
374  remSiteNodeRetCodes[code] = pCurrentSite;
375  }
376  }
377 
378  if (dynamic_cast<TYAcousticVolume*>(elem_0) != nullptr)
379  {
380  // Dans tous les cas, on offre la possibilite d'inverser la normales des faces
381  volumeFound = i;
382  inverseNormales = pPopup->addAction(TR("id_popup_normales"));
383  }
384 
385  TYMaillage* pMaillage = dynamic_cast<TYMaillage*>(elem_0);
386  if (pMaillage != nullptr)
387  {
388  // Calcul parent
389  if (dynamic_cast<TYProjet*>(elem_1) != nullptr)
390  {
391  // Si le maillage est bien present dans le calcul
392  TYMaillageGeoNode* pMaillageGeoNode = TYGeometryNode::GetGeoNode(elem_0);
393  if (pMaillageGeoNode != nullptr)
394  {
395  // Position via le parent (GeoNode)
396  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_moving"))), TR("id_popup_position"));
397  posRetCodes[code] = dynamic_cast<TYGeometryNode*>(pMaillageGeoNode);
398 
399  // Rotation via le parent (GeoNode)
400  code =
401  pPopup->addAction(QIcon(QPixmap(IMG("id_icon_rotation"))), TR("id_popup_rotation"));
402  rotRetCodes[code] = dynamic_cast<TYGeometryNode*>(pMaillageGeoNode);
403 
404  // Duplication
405  code =
406  pPopup->addAction(QIcon(QPixmap(IMG("id_icon_duplicate"))), TR("id_popup_duplicate"));
407  copyMaillageRetCodes[code] = pMaillage;
408 
409  // Suppression
410  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
411  remMaillageRetCodes[code] = pMaillage;
412  }
413  }
414  }
415 
416  TYPointControl* pPointCtrl = dynamic_cast<TYPointControl*>(pElts->at(i)._pObj);
417  if (pPointCtrl != nullptr)
418  {
419  // Projet parent
420  if (dynamic_cast<TYProjet*>(elem_1) != nullptr)
421  {
422  // Suppression
423  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
424  remPtControlRetCodes[code] = pPointCtrl;
425  }
426  }
427 
428  if (dynamic_cast<TYTopographie*>(elem_1) != nullptr)
429  {
430 
431  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(elem_2);
432  if (pSite == pModelerSite)
433  {
434  // On ne peut dupliquer ou supprimer que dans le modeler de son site
435  if (dynamic_cast<TYCourbeNiveau*>(pElts->at(i)._pObj) != nullptr)
436  {
437  split = pPopup->addAction(TR("id_popup_split"));
438  levelCurveFound = i;
439  }
440  // Duplication
441  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_duplicate"))), TR("id_popup_duplicate"));
442  copyTopoRetCodes[code] = pElts->at(i);
443 
444  // Suppression
445  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
446  remTopoRetCodes[code] = pElts->at(i);
447  }
448  }
449 
450  if (dynamic_cast<TYInfrastructure*>(elem_1) != nullptr)
451  {
452  // Acoustic computation is always possible
453  if (dynamic_cast<TYAcousticVolumeNode*>(elem_0))
454  {
455  // Calcul acoustique
456  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_calcul"))), TR("id_popup_calculer"));
457  calculVolNodeRetCodes[code] = dynamic_cast<TYAcousticVolumeNode*>(elem_0);
458  }
459 
460  // Geometric changes only possible in parent site meodeler
461  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(elem_2);
462  if (pSite == pModelerSite)
463  {
464  // GeoNode
465  TYGeometryNode* pEltGeoNode = TYGeometryNode::GetGeoNode(elem_0);
466 
467  // Position via le parent (GeoNode)
468  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_moving"))), TR("id_popup_position"));
469  posRetCodes[code] = pEltGeoNode;
470 
471  // Rotation via le parent (GeoNode)
472  if (dynamic_cast<TYUserSourcePonctuelle*>(elem_0) ==
473  nullptr) // a user_source cannot be oriented
474  {
475  code =
476  pPopup->addAction(QIcon(QPixmap(IMG("id_icon_rotation"))), TR("id_popup_rotation"));
477  rotRetCodes[code] = pEltGeoNode;
478  }
479 
480  // Duplication
481  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_duplicate"))), TR("id_popup_duplicate"));
482  copyInfraRetCodes[code] = elem_0;
483 
484  // Suppression
485  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
486  remInfraRetCodes[code] = elem_0;
487  }
488  }
489  // Ajoute un separateur entre les elements
490  pPopup->addSeparator();
491  }
492 
493  // Gestion du choix de l'utilisateur
494  pPopup->setMouseTracking(true);
495  QAction* popupRet = pPopup->exec(QCursor::pos());
496  if (popupRet == nullptr)
497  {
498  return;
499  }
500  qApp->processEvents();
501 
502  if (retCodes.find(popupRet) != retCodes.end())
503  {
504  TYElement* pElement = pElts->at(retCodes[popupRet]);
505  manageProperties(pElement);
506  }
507  else if (posRetCodes.find(popupRet) != posRetCodes.end())
508  {
509  bool bHeight = true;
510  if (dynamic_cast<TYGeometryNode*>(posRetCodes[popupRet])->getElement()->isA("TYSiteNode"))
511  {
512  bHeight = false;
513  }
514  showPositionDialog(posRetCodes[popupRet], bHeight);
515  }
516  else if (rotRetCodes.find(popupRet) != rotRetCodes.end())
517  {
518  showRotationDialog(rotRetCodes[popupRet]);
519  }
520  else if (popupRet == inverseNormales)
521  {
522  inverseNormal(pElts->at(volumeFound)._pObj);
523  }
524  else if (_pModeler->askForResetResultat())
525  {
526  if (copySiteNodeRetCodes.find(popupRet) != copySiteNodeRetCodes.end())
527  {
528  copySite(copySiteNodeRetCodes[popupRet]);
529  }
530  else if (remSiteNodeRetCodes.find(popupRet) != remSiteNodeRetCodes.end())
531  {
532  remSite(remSiteNodeRetCodes[popupRet]);
533  }
534  else if (calculVolNodeRetCodes.find(popupRet) != calculVolNodeRetCodes.end())
535  {
536  getTYApp()->getCalculManager()->updateAcoustic(calculVolNodeRetCodes[popupRet]);
537  }
538  else if (popupRet == split)
539  {
540  splitCurve(pElts->at(levelCurveFound)._pObj);
541  }
542  else if (copyMaillageRetCodes.find(popupRet) != copyMaillageRetCodes.end())
543  {
544  copyMaillage(copyMaillageRetCodes[popupRet]);
545  }
546  else if (remMaillageRetCodes.find(popupRet) != remMaillageRetCodes.end())
547  {
548  remMaillage(remMaillageRetCodes[popupRet]);
549  }
550  else if (copyPtControlRetCodes.find(popupRet) != copyPtControlRetCodes.end())
551  {
552  copyPtCtrl(copyPtControlRetCodes[popupRet]);
553  }
554  else if (remPtControlRetCodes.find(popupRet) != remPtControlRetCodes.end())
555  {
556  remPtCtrl(remPtControlRetCodes[popupRet]);
557  }
558  else if (remTopoRetCodes.find(popupRet) != remTopoRetCodes.end())
559  {
560  remTopoElmt(remTopoRetCodes[popupRet]);
561  }
562  else if (copyTopoRetCodes.find(popupRet) != copyTopoRetCodes.end())
563  {
564  copyTopoElmt(copyTopoRetCodes[popupRet]);
565  }
566  else if (remInfraRetCodes.find(popupRet) != remInfraRetCodes.end())
567  {
568  remInfraElmt(remInfraRetCodes[popupRet]);
569  }
570  else if (copyInfraRetCodes.find(popupRet) != copyInfraRetCodes.end())
571  {
572  copyInfraElmt(copyInfraRetCodes[popupRet]);
573  }
574  }
575 
576  delete pPopup;
577 }
578 
579 void TYPickEditor::machineModelerPopupMenu(std::shared_ptr<LPTYElementArray> pElts)
580 {
581  QMenu* pPopup = new QMenu(nullptr);
582 
583  std::map<QAction*, int> retCodes;
584  std::map<QAction*, TYAcousticVolumeNode*> calculVolNodeRetCodes;
585  QAction* inverseNormales = nullptr;
586  std::map<QAction*, TYGeometryNode*> posRetCodes;
587  std::map<QAction*, TYGeometryNode*> rotRetCodes;
588  std::map<QAction*, TYAcousticVolume*> dimVolRetCodes;
589  std::map<QAction*, TYAcousticVolume*> remVolRetCodes;
590  std::map<QAction*, TYAcousticVolume*> copyVolRetCodes;
591  QAction* editFace = nullptr;
592  QAction* code = nullptr;
593 
594  LPTYElement pRemovedEltParent = nullptr;
595  LPTYElement pAddedElt = nullptr;
596 
597  int rectFound = -2, volumeFound = -2;
598 
599  QFont font = pPopup->font();
600  font.setBold(true);
601  for (unsigned int i = 0; i < pElts->size(); i++)
602  {
603  // Edition des proprietes de l'element
604  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_editeelt"))),
605  TYWidget::getDisplayName(pElts->at(i)));
606  code->setFont(font);
607  retCodes[code] = i;
608 
609  // Calcul des proprietes acoustiques
610  if (dynamic_cast<TYAcousticVolumeNode*>(pElts->at(i)._pObj))
611  {
612  // Calcul acoustique
613  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_calcul"))), TR("id_popup_calculer"));
614  calculVolNodeRetCodes[code] = (LPTYAcousticVolumeNode&)pElts->at(i);
615  }
616  else if (dynamic_cast<TYAcousticVolume*>(pElts->at(i)._pObj) != nullptr &&
617  !(pElts->at(i)->isA("TYEtage")))
618  {
619  // Dans tous les cas, on offre la possibilite d'inverser la normales des faces
620  volumeFound = i;
621  inverseNormales = pPopup->addAction(TR("id_popup_normales"));
622 
623  // Gestion position / rotation
624  TYGeometryNode* pEltGeoNode = TYGeometryNode::GetGeoNode(pElts->at(i)._pObj);
625  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_moving"))), TR("id_popup_position"));
626  posRetCodes[code] = pEltGeoNode;
627 
628  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_rotation"))), TR("id_popup_rotation"));
629  rotRetCodes[code] = pEltGeoNode;
630 
631  // Dimensions
632  code = pPopup->addAction(TR("id_popup_dimension"));
633  dimVolRetCodes[code] = (LPTYAcousticVolume&)pElts->at(i);
634 
635  // Duplication
636  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_duplicate"))), TR("id_popup_duplicate"));
637  copyVolRetCodes[code] = (LPTYAcousticVolume&)pElts->at(i);
638 
639  // Suppression
640  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
641  remVolRetCodes[code] = (LPTYAcousticVolume&)pElts->at(i);
642  }
643  else if (dynamic_cast<TYAcousticRectangleNode*>(pElts->at(i)._pObj) != nullptr)
644  {
645  // On permet d'editer une face uniquement dans un modeleur de batiment ou de machine
646  rectFound = i;
647  editFace = pPopup->addAction(TR("id_popup_editface"));
648  }
649 
650  // Ajoute un separateur entre les elements
651  pPopup->addSeparator();
652  }
653 
654  // Gestion du choix de l'utilisateur
655  pPopup->setMouseTracking(true);
656  QAction* popupRet = pPopup->exec(QCursor::pos());
657  if (popupRet == nullptr)
658  {
659  return;
660  }
661  qApp->processEvents();
662 
663  if (retCodes.find(popupRet) != retCodes.end())
664  {
665  TYElement* pElement = pElts->at(retCodes[popupRet]);
666  manageProperties(pElement);
667  }
668  else if (posRetCodes.find(popupRet) != posRetCodes.end())
669  {
670  showPositionDialog(posRetCodes[popupRet], false);
671  }
672  else if (rotRetCodes.find(popupRet) != rotRetCodes.end())
673  {
674  showRotationDialog(rotRetCodes[popupRet]);
675  }
676  else if (dimVolRetCodes.find(popupRet) != dimVolRetCodes.end())
677  {
678  TYElement* pElement = dimVolRetCodes[popupRet];
679  setVolumeSize(pElement);
680  }
681  else if (popupRet == editFace)
682  {
683  TYElement* pElement = pElts->at(rectFound)._pObj;
684  openFaceModeler(pElement);
685  }
686  else if (popupRet == inverseNormales)
687  {
688  inverseNormal(pElts->at(volumeFound)._pObj);
689  }
690  else if (_pModeler->askForResetResultat())
691  {
692  if (calculVolNodeRetCodes.find(popupRet) != calculVolNodeRetCodes.end())
693  {
694  getTYApp()->getCalculManager()->updateAcoustic(calculVolNodeRetCodes[popupRet]);
695  }
696  else if (remVolRetCodes.find(popupRet) != remVolRetCodes.end())
697  {
698  removeVolume(remVolRetCodes[popupRet]);
699  }
700  else if (copyVolRetCodes.find(popupRet) != copyVolRetCodes.end())
701  {
702  copyVolume(copyVolRetCodes[popupRet]);
703  }
704  }
705 
706  delete pPopup;
707 }
708 
709 void TYPickEditor::batimentModelerPopupMenu(std::shared_ptr<LPTYElementArray> pElts)
710 {
711  QMenu* pPopup = new QMenu(nullptr);
712 
713  QAction* code = nullptr;
714  std::map<QAction*, int> retCodes;
715  std::map<QAction*, TYAcousticVolumeNode*> calculVolNodeRetCodes;
716  QAction* inverseNormales = nullptr;
717  std::map<QAction*, TYGeometryNode*> posRetCodes;
718  std::map<QAction*, TYGeometryNode*> rotRetCodes;
719  QAction* hauteurEtage = nullptr;
720  QAction* hauteurEcran = nullptr;
721  QAction* epaisseurEcran = nullptr;
722  QAction* editFace = nullptr;
723  std::map<QAction*, TYAcousticVolume*> remVolRetCodes;
724  std::map<QAction*, TYAcousticVolume*> copyVolRetCodes;
725  std::map<QAction*, TYAcousticVolume*> dimVolRetCodes;
726 
727  LPTYElement pRemovedEltParent = nullptr;
728  LPTYElement pAddedElt = nullptr;
729 
730  int etageFound = -2, ecranFound = -2, rectFound = -2, volumeFound = -2;
731 
732  QFont font = pPopup->font();
733  font.setBold(true);
734  for (unsigned int i = 0; i < pElts->size(); i++)
735  {
736  // Edition des proprietes de l'element
737  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_editeelt"))),
738  TYWidget::getDisplayName(pElts->at(i)));
739  code->setFont(font);
740  retCodes[code] = i;
741 
742  // Calcul des proprietes acoustiques
743  if (dynamic_cast<TYAcousticVolumeNode*>(pElts->at(i)._pObj))
744  {
745  // Calcul acoustique
746  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_calcul"))), TR("id_popup_calculer"));
747  calculVolNodeRetCodes[code] = (LPTYAcousticVolumeNode&)pElts->at(i);
748  }
749  else if (dynamic_cast<TYAcousticVolume*>(pElts->at(i)._pObj) != nullptr)
750  {
751  // Dans tous les cas, on offre la possibilite d'inverser la normales des faces
752  volumeFound = i;
753  inverseNormales = pPopup->addAction(TR("id_popup_normales"));
754 
755  // Gestion position / rotation
756  TYGeometryNode* pEltGeoNode = TYGeometryNode::GetGeoNode(pElts->at(i)._pObj);
757 
758  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_moving"))), TR("id_popup_position"));
759  posRetCodes[code] = pEltGeoNode;
760 
761  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_rotation"))), TR("id_popup_rotation"));
762  rotRetCodes[code] = pEltGeoNode;
763 
764  // Dimensions
765  if (pElts->at(i)->isA("TYEtage"))
766  {
767  etageFound = i;
768  hauteurEtage = pPopup->addAction(TR("id_popup_hauteur"));
769  }
770  else if (pElts->at(i)->isA("TYEcran"))
771  {
772  ecranFound = i;
773  hauteurEcran = pPopup->addAction(TR("id_popup_hauteur"));
774  epaisseurEcran = pPopup->addAction(TR("id_popup_epaisseur"));
775  }
776  else if (pElts->at(i)->isA("TYAcousticCylinder"))
777  {
778  code = pPopup->addAction(TR("id_popup_dimension"));
779  dimVolRetCodes[code] = (LPTYAcousticVolume&)pElts->at(i);
780  }
781 
782  // Duplication
783  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_duplicate"))), TR("id_popup_duplicate"));
784  copyVolRetCodes[code] = (LPTYAcousticVolume&)pElts->at(i);
785 
786  // Suppression
787  code = pPopup->addAction(QIcon(QPixmap(IMG("id_icon_del"))), TR("id_popup_remove"));
788  remVolRetCodes[code] = (LPTYAcousticVolume&)pElts->at(i);
789  }
790  else if (dynamic_cast<TYAcousticRectangleNode*>(pElts->at(i)._pObj) != nullptr)
791  {
792  // On permet d'editer une face uniquement dans un modeleur de batiment ou de machine
793  rectFound = i;
794  editFace = pPopup->addAction(TR("id_popup_editface"));
795  }
796 
797  // Ajoute un separateur entre les elements
798  pPopup->addSeparator();
799  }
800 
801  // Gestion du choix de l'utilisateur
802  pPopup->setMouseTracking(true);
803  QAction* popupRet = pPopup->exec(QCursor::pos());
804  if (popupRet == nullptr)
805  {
806  return;
807  }
808  qApp->processEvents();
809 
810  if (retCodes.find(popupRet) != retCodes.end())
811  {
812  TYElement* pElement = pElts->at(retCodes[popupRet]);
813  manageProperties(pElement);
814  }
815  else if (posRetCodes.find(popupRet) != posRetCodes.end())
816  {
817  bool bHeight = false;
818  if (posRetCodes[popupRet]->isA("TYMachine"))
819  {
820  bHeight = true;
821  }
822  showPositionDialog(posRetCodes[popupRet], bHeight);
823  }
824  else if (rotRetCodes.find(popupRet) != rotRetCodes.end())
825  {
826  showRotationDialog(rotRetCodes[popupRet]);
827  }
828  else if (popupRet == editFace)
829  {
830  TYElement* pElement = pElts->at(rectFound)._pObj;
831  openFaceModeler(pElement);
832  }
833  else if (popupRet == hauteurEtage)
834  {
835  floorHeight(pElts->at(etageFound)._pObj);
836  }
837  else if (popupRet == hauteurEcran)
838  {
839  screenHeight(pElts->at(ecranFound)._pObj);
840  }
841  else if (popupRet == epaisseurEcran)
842  {
843  screenThick(pElts->at(ecranFound)._pObj);
844  }
845  else if (popupRet == inverseNormales)
846  {
847  inverseNormal(pElts->at(volumeFound)._pObj);
848  }
849  else if (dimVolRetCodes.find(popupRet) != dimVolRetCodes.end())
850  {
851  TYElement* pElement = dimVolRetCodes[popupRet];
852  setVolumeSize(pElement);
853  }
854  else if (_pModeler->askForResetResultat())
855  {
856  if (calculVolNodeRetCodes.find(popupRet) != calculVolNodeRetCodes.end())
857  {
858  getTYApp()->getCalculManager()->updateAcoustic(calculVolNodeRetCodes[popupRet]);
859  }
860  else if (remVolRetCodes.find(popupRet) != remVolRetCodes.end())
861  {
862  removeVolume(remVolRetCodes[popupRet]);
863  }
864  else if (copyVolRetCodes.find(popupRet) != copyVolRetCodes.end())
865  {
866  copyVolume(copyVolRetCodes[popupRet]);
867  }
868  }
869 
870  delete pPopup;
871 }
872 
873 void TYPickEditor::showPositionDialog(TYGeometryNode* pGeoNode, bool activeHeight)
874 {
875  assert(pGeoNode);
876 
877  // Si c'est une source ponctuelle on fait autrement.
878  if (pGeoNode->getElement()->isA("TYUserSourcePonctuelle"))
879  {
880  pGeoNode->getElement()->edit(_pModeler);
881  return;
882  }
883 
884  // Recuperation de la hauteur de l'element
885  double hauteur = pGeoNode->getHauteur();
886 
887  // On doit presenter la position de l'origine du GeoNode selectionne.
888  // Cette position doit etre dans le repere du modeler frame.
889  TYElement* pRootTYElement = _pModeler->getElement();
890  TYGeometryNode* pRootGeometryNode = TYGeometryNode::GetGeoNode(pRootTYElement);
891 
892  // On cree un geonode temporaire copie du geonode transmis (uniquement les elements geometrique)
893  std::shared_ptr<TYGeometryNode> pTempGeoNode = std::make_shared<TYGeometryNode>();
894 
895  pTempGeoNode->setRepere(pGeoNode->getORepere3D());
896 
897  // On a besoin du type d'element pointé par le geonode
898  // Cet élément va servir à adapter la boîte de dialogue position dans TYPositionDialog::updateContent()
899  TYElement* pElement = pGeoNode->getElement();
900  auto pElementClone = pElement->clone();
901  TYElement* pElementCopy = dynamic_cast<TYElement*>(pElementClone);
902  if (pElementCopy)
903  {
904  pTempGeoNode->setElement(pElementCopy);
905  }
906 
907  TYPoint oldZero(0, 0, 0);
908  oldZero = pGeoNode->localToGlobal() * oldZero;
909  if (pRootGeometryNode)
910  {
911  oldZero = pRootGeometryNode->globalToLocal() * oldZero;
912  pTempGeoNode->getORepere3D()._origin = oldZero;
913  }
914 
915  // Affectation de la hauteur au geoNode temporaire
916  pTempGeoNode->setHauteur(hauteur);
917 
918  // Affiche la boite de dialogue
919  TYPositionDialog* pDlg = new TYPositionDialog(pTempGeoNode.get(), _pModeler);
920  pDlg->setHauteurEnabled(
921  activeHeight); // Activation ou non de la hauteur pour les elements de volumes nodes
922 
923  int ret = pDlg->exec();
924 
925  // Applique les modificatins si necessaire
926  if (ret == QDialog::Accepted)
927  {
929  {
930  // On a bouge l'origine (exprime dans le repere root)
931  OPoint3D newZero = pTempGeoNode->getORepere3D()._origin;
932 
933  // on modifie l'origine du GeoNode de newZero:
934  ORepere3D repere = pGeoNode->getORepere3D();
935  TYPoint oldOrg = repere._origin;
936  repere._origin._x = newZero._x;
937  repere._origin._y = newZero._y;
938  repere._origin._z = newZero._z;
939  pGeoNode->setRepere(repere);
940 
941  pGeoNode->setHauteur(pTempGeoNode->getHauteur());
942 
943  TYAction* pAction = new TYMoveGeoNodeAction(pGeoNode, oldOrg, repere._origin, _pModeler,
944  TR("id_action_setposition"));
945  _pModeler->getActionManager()->addAction(pAction);
946 
947  // Refresh
948  pGeoNode->setIsGeometryModified(true);
949  pGeoNode->updateGraphicTree();
950  // (un update est fait dans le reset)
951  resetPicker();
952 
953  // La scene a ete modifiee
955  }
956  }
957 
958  delete pDlg;
959  pDlg = nullptr;
960 }
961 
963 {
964  if (!pGeoNode)
965  {
966  return;
967  }
968 
969  // On doit une vue de la matrice du GeoNode selectionne, dans le repere du modeler frame.
970  TYElement* pRootTYElement = _pModeler->getElement();
971  TYGeometryNode* pRootGeometryNode = TYGeometryNode::GetGeoNode(pRootTYElement);
972 
973  OMatrix oldTyMat = pGeoNode->localToGlobal();
974  if (pRootGeometryNode)
975  {
976  oldTyMat = oldTyMat *
977  pRootGeometryNode
978  ->globalToLocal(); // origin est maintenant exprime dans le repere pRootGeometryNode
979  }
980 
981  // Get rotations from transform matrix
982  OPoint3D vec;
983  vec._x = oldTyMat._m[0][1];
984  vec._y = oldTyMat._m[1][1];
985  vec._z = oldTyMat._m[2][1];
986 
987  // Get X-vector for roll calculation
988  OPoint3D xv;
989  xv._x = oldTyMat._m[0][0];
990  xv._y = oldTyMat._m[1][0];
991  xv._z = oldTyMat._m[2][0];
992 
993  // Calculate PRH (x = pitch, y = roll, z = heading)
994  OPoint3D rotTmp(-atan2(vec._z, sqrt(vec._x * vec._x + vec._y * vec._y)), xv._z, -atan2(-vec._x, vec._y));
995 
996  // Set up vars
997  double pitch = RADTODEG(rotTmp._x); // Pitch
998  double yaw = -RADTODEG(rotTmp._z); // Heading
999  double roll = RADTODEG(rotTmp._y); // Roll
1000 
1001  // Affiche la boite de dialogue
1002  OPoint3D rot(pitch, roll, yaw);
1003  TYRotationDialog* pDlg = new TYRotationDialog(&rot, _pModeler);
1004  if ((dynamic_cast<TYMaillage*>(pGeoNode->getElement()) != nullptr) ||
1005  (dynamic_cast<TYSiteNode*>(pGeoNode->getElement()) != nullptr))
1006  {
1007  pDlg->lockXY();
1008  }
1009 
1010  int ret = pDlg->exec();
1011 
1012  // Applique les modifications si necessaire
1013  if (ret == QDialog::Accepted)
1014  {
1016  {
1017  ORepere3D Repere = pGeoNode->getORepere3D();
1018  ORepere3D oldRepere = Repere;
1019  OMatrix tyMat;
1020  OMatrix tyMatTmpX;
1021  OMatrix tyMatTmpY;
1022  OMatrix tyMatTmpZ;
1023  OMatrix tyMatTmpConcat;
1024 
1025  // On applique la rotation
1026  double dRotateX = rot._x;
1027  double dRotateY = rot._y;
1028  double dRotateZ = rot._z;
1029  if (pDlg->getConcatenateStatus())
1030  {
1031  dRotateX -= pitch;
1032  dRotateY -= roll;
1033  dRotateZ -= yaw;
1034  }
1035 
1036  tyMatTmpX.setRotationOx(-DEGTORAD(dRotateX));
1037  tyMatTmpY.setRotationOy(-DEGTORAD(dRotateY));
1038  tyMatTmpZ.setRotationOz(DEGTORAD(dRotateZ));
1039 
1040  if (pDlg->getConcatenateStatus()) // az--
1041  {
1042  tyMat = Repere.asMatrix();
1043  tyMatTmpConcat = tyMat;
1044  }
1045 
1046  tyMat = tyMat * tyMatTmpZ * tyMatTmpY * tyMatTmpX * tyMatTmpConcat;
1047 
1048  OPoint3D org = Repere._origin; // On conserve l'origine de depart
1049  Repere.set(tyMat);
1050  Repere._origin = org;
1051 
1052  pGeoNode->setRepere(Repere);
1053 
1054  TYAction* pAction = new TYRotateGeoNodeAction(pGeoNode, oldRepere, Repere, _pModeler,
1055  TR("id_action_setrotation"));
1056  _pModeler->getActionManager()->addAction(pAction);
1057 
1058  pGeoNode->setIsGeometryModified(true);
1059  pGeoNode->getElement()->getParent()->setIsGeometryModified(true);
1060 
1061  // Refresh
1062  pGeoNode->getElement()->getParent()->updateGraphic();
1063  // (un update est fait dans le reset)
1064  resetPicker();
1065 
1066  // La scene a ete modifiee
1068  }
1069  }
1070 
1071  delete pDlg;
1072  pDlg = nullptr;
1073 }
1074 
1076 {
1077  if (!pAccVol)
1078  {
1079  return;
1080  }
1081 
1082  TYAcousticVolume* pBackupVolume = dynamic_cast<TYAcousticVolume*>(pAccVol->clone());
1083 
1084  TYDimensionDialog* pDlg = new TYDimensionDialog(pAccVol, _pModeler);
1085 
1086  // Affiche la boite de dialogue
1087  int ret = pDlg->exec();
1088 
1089  // Applique les modificatins si necessaire
1090  if (ret == QDialog::Accepted)
1091  {
1093  {
1094  *pAccVol = *pBackupVolume;
1095  }
1096  else
1097  {
1098  pAccVol->setIsGeometryModified(true);
1099  pAccVol->getParent()->setIsGeometryModified(true);
1100 
1101  // Refresh
1102  pAccVol->getParent()->updateGraphic();
1103  // (un update est fait dans le reset)
1104  _pPicker->reset();
1105 
1106  // La scene a ete modifiee
1108  }
1109  }
1110 }
1111 
1113 {
1114  hidePanel();
1115 
1116  if (!pElt)
1117  {
1118  return;
1119  }
1120 
1121  LPTYMaillage pMaillage = dynamic_cast<TYMaillage*>(pElt);
1122  if (pMaillage != nullptr)
1123  {
1124  LPTYPanel pPanel = pMaillage->getPanel();
1125 
1126  // Position du curseur (repere modeleur)
1127  double x = _lastMovedCurPos.x();
1128  double y = _pInteractor->getViewport().height() - _lastMovedCurPos.y();
1129  TYElementGraphic* pTYElementGraphic = pPanel->getGraphicObject();
1130  ((TYPanelGraphic*)pTYElementGraphic)->setPosX(x);
1131  ((TYPanelGraphic*)pTYElementGraphic)->setPosY(y);
1132  pTYElementGraphic->setVisible();
1133 
1134  // Position dans le repère "monde"
1135  OPoint3D pt;
1136  if (realWorldPosition(pt) == false)
1137  {
1138  return;
1139  }
1140  double X = pt._x, Y = pt._y, Z = pt._z;
1141 
1142  switch (_pModeler->getCurrentView())
1143  {
1145  pPanel->setFirstPos("X : " + doubleToStrPre(X, 1));
1146  pPanel->setSecondPos("Y : " + doubleToStrPre(Y, 1));
1147  break;
1149  pPanel->setFirstPos("Y : " + doubleToStrPre(Y, 1));
1150  pPanel->setSecondPos("Z : " + doubleToStrPre(Z, 1));
1151  break;
1153  pPanel->setFirstPos("X : " + doubleToStrPre(X, 1));
1154  pPanel->setSecondPos("Z : " + doubleToStrPre(Z, 1));
1155  break;
1156  }
1157 
1158  // Valeur
1159  LPTYMaillageGeoNode pMaillageGeoNode =
1160  dynamic_cast<TYProjet*>(pMaillage->getParent())->findMaillage(pMaillage);
1161 
1162  // On recupere la premiere distance
1163  OPoint3D coord;
1164  double minDistSquare = 0.0;
1165  LPTYPointCalcul pPtCalcul = pMaillage->getPtsCalcul().front();
1166  LPTYPointCalcul pResult = 0;
1167  if (pPtCalcul)
1168  {
1169  // coord = pMaillageGeoNode->localToGlobal() * OCoord3D(pPtCalcul->_x, pPtCalcul->_y, 0.0);
1170  coord = pMaillageGeoNode->localToGlobal() * OPoint3D(pPtCalcul->_x, pPtCalcul->_y, 0.0);
1171  switch (_pModeler->getCurrentView())
1172  {
1174  minDistSquare = std::sqrt(std::pow(coord._x - X, 2) + std::pow(coord._y - Y, 2));
1175  break;
1177  minDistSquare = std::sqrt(std::pow(coord._y - Y, 2) + std::pow(coord._z - Z, 2));
1178  break;
1180  minDistSquare = std::sqrt(std::pow(coord._x - X, 2) + std::pow(coord._z - Z, 2));
1181  break;
1182  }
1183 
1184  pResult = pPtCalcul;
1185  }
1186 
1187  // On teste les suivantes pour trouver le point de calcul le plus proche
1188  for (unsigned int i = 1; i < pMaillage->getPtsCalcul().size(); i++)
1189  {
1190  pPtCalcul = pMaillage->getPtsCalcul()[i];
1191  coord = pMaillageGeoNode->localToGlobal() * OPoint3D(pPtCalcul->_x, pPtCalcul->_y, 0.0);
1192 
1193  double distSquare = 0.0;
1194  switch (_pModeler->getCurrentView())
1195  {
1197  distSquare = std::sqrt(std::pow(coord._x - X, 2) + std::pow(coord._y - Y, 2));
1198  break;
1200  distSquare = std::sqrt(std::pow(coord._y - Y, 2) + std::pow(coord._z - Z, 2));
1201  break;
1203  distSquare = std::sqrt(std::pow(coord._x - X, 2) + std::pow(coord._z - Z, 2));
1204  break;
1205  }
1206 
1207  if (distSquare < minDistSquare)
1208  {
1209  pResult = pPtCalcul;
1210  minDistSquare = distSquare;
1211  }
1212  }
1213 
1214  std::string value = "dB : N/A";
1215  if (pResult)
1216  {
1217  switch (pMaillage->getDataType())
1218  {
1220  value = "dB(A) : " + doubleToStrPre(pResult->getValA(), 1);
1221  break;
1223  value = "dB(Lin) : " + doubleToStrPre(pResult->getValLin(), 1);
1224  break;
1225  case TYMaillage::DataFreq:
1226  value = "dB(Freq) : " +
1227  doubleToStrPre(pResult->getSpectre()->getValueReal(pMaillage->getDataFreq()), 1);
1228  break;
1229  }
1230  }
1231 
1232  pPanel->setValue(value);
1233 
1234  // On met a jour uniquement le maillage
1236  }
1237  else
1238  {
1239  hidePanel();
1240  }
1241 
1242  _pLastRolloverElt = pElt;
1243 }
1244 
1246 {
1247  if (!_pLastRolloverElt)
1248  {
1249  return;
1250  }
1251 
1253  if (pMaillage != nullptr)
1254  {
1255  pMaillage->getPanel()->getGraphicObject()->setVisible(false);
1256 
1257  // On met a jour uniquement le maillage
1259  _pLastRolloverElt = nullptr;
1260  }
1261 }
1262 
1264 {
1265  dynamic_cast<TYModelerFrame*>(_pModeler)->updateView();
1266 
1267  // Position dans la scene 3D
1268  QPoint curPos = _lastMovedCurPos;
1269 
1270  // Calcul des coords
1271  float* pos = new float[3];
1272 
1273  if (!(_pModeler->computeCurPos(curPos.x(), curPos.y(), pos)))
1274  {
1275  delete[] pos;
1276  return false;
1277  }
1278 
1279  pt._x = pos[0];
1280  pt._y = -pos[2];
1281  pt._z = pos[1];
1282 
1283  delete[] pos;
1284 
1285  return true;
1286 }
1287 
1289 {
1290  if ((pElement != nullptr) && (pElement->edit(_pModeler) == QDialog::Accepted))
1291  {
1292  // Mise a jour du projet
1293  TYProjet* pProjet = getTYApp()->getCurProjet();
1294  if (pProjet)
1295  {
1296  TYSiteNode* pSite = pProjet->getSite();
1297  if (pSite)
1298  {
1299  pSite->update(pElement);
1301  }
1303  }
1304 
1305  pElement->updateGraphicTree();
1306  }
1307 }
1308 
1310 {
1311  if (pElement == nullptr)
1312  {
1313  return;
1314  }
1315 
1316  TYElement* pParent = pElement->getParent();
1317 
1318  if (pParent == nullptr)
1319  {
1320  return;
1321  }
1322 
1323  TYSiteNodeGeoNode* pGeoNode = TYGeometryNode::GetGeoNode(pElement);
1324 
1325  // Nouvel element du meme type que l'objet a dupliquer (clone)
1326  LPTYSiteNodeGeoNode pCopy = new TYSiteNodeGeoNode(dynamic_cast<TYSiteNode*>(pElement->clone()));
1327 
1328  // Duplication
1329  pCopy->deepCopy(pGeoNode, false);
1330  pCopy->setParent(pElement->getParent());
1331 
1332  // Ajout
1333  if (dynamic_cast<TYSiteNode*>(pParent)->addSiteNode(pCopy))
1334  {
1335  ORepere3D repere = pCopy->getORepere3D();
1336  // Offset
1337  repere._origin._x += 100.0;
1338  repere._origin._y -= 100.0;
1339 
1340  pCopy->setRepere(repere);
1341 
1342  LPTYCalcul pCalc = nullptr;
1343  TYSiteNode* pSite = nullptr;
1344  pSite = dynamic_cast<TYSiteNode*>(pCopy->getElement());
1345  if (getTYApp()->getCurProjet() && pSite)
1346  {
1347  pCalc = getTYApp()->getCurProjet()->getCurrentCalcul();
1348  if (pCalc)
1349  {
1350  pCalc->getCalculElements(pSite);
1351  }
1352  }
1353 
1354  // Update Graphic
1355  pCopy->updateGraphicTree();
1356 
1357  // Action
1358  TYAction* pAction = new TYAddSiteNodeToSiteNodeAction(pCopy, dynamic_cast<TYSiteNode*>(pParent),
1359  _pModeler, TR("id_action_addsitenode"));
1360  _pModeler->getActionManager()->addAction(pAction);
1361  }
1362 
1363  updateSiteFrame();
1364 
1365  // La scene a ete modifiee
1367 }
1368 
1370 {
1371  if (pElement == nullptr)
1372  {
1373  return;
1374  }
1375  TYElement* pParent = pElement->getParent();
1376  if (pParent == nullptr)
1377  {
1378  return;
1379  }
1380 
1381  LPTYSiteNode pSiteParent = dynamic_cast<TYSiteNode*>(pParent);
1382  LPTYSiteNodeGeoNode pGeoNode = TYGeometryNode::GetGeoNode(pElement);
1383 
1384  if (pSiteParent->remSiteNode((LPTYSiteNode&)pElement))
1385  {
1386  TYAction* pAction =
1387  new TYRemSiteNodeToSiteNodeAction(pGeoNode, pSiteParent, _pModeler, TR("id_action_remsitenode"));
1388  _pModeler->getActionManager()->addAction(pAction);
1389  }
1390 
1391  updateSiteFrame();
1392 
1393  // La scene a ete modifiee
1395 }
1396 
1398 {
1399  OPoint3D pt;
1400  if (realWorldPosition(pt))
1401  {
1402  TYCourbeNiveau* pCurrentCurve = dynamic_cast<TYCourbeNiveau*>(pElement);
1403  TYTopographie* pTopo = dynamic_cast<TYTopographie*>(pCurrentCurve->getParent());
1404 
1405  if (pCurrentCurve != nullptr)
1406  {
1407  LPTYCourbeNiveau newCurve = pCurrentCurve->split(pt);
1408  if (newCurve._pObj != nullptr)
1409  {
1410  // Copie du geonode de l'actuelle courbe
1411  TYGeometryNode* pCurrentGeoNode = TYGeometryNode::GetGeoNode(pCurrentCurve);
1412  LPTYGeometryNode pNewGeoNode = new TYGeometryNode();
1413  pNewGeoNode->deepCopy(pCurrentGeoNode, false);
1414 
1415  // Association du geonode avec la nouvelle courbe
1416  pNewGeoNode->setElement((LPTYElement)newCurve);
1417 
1418  // Ajout de la nouvelle courbe au projet
1419  if (pTopo != nullptr)
1420  {
1421  pTopo->addCrbNiv(pNewGeoNode);
1422  // Ajout de la courbe de niveau au calcul courant s'il existe
1423  if (newCurve && getTYApp()->getCurProjet() &&
1424  getTYApp()->getCurProjet()->getCurrentCalcul())
1425  {
1427  }
1428  }
1429  }
1430 
1431  pTopo->updateGraphicTree();
1432  pTopo->updateGraphic();
1433  updateSiteFrame();
1434  // La scene a ete modifiee
1436  }
1437  }
1438 }
1439 
1441 {
1442  if (pElement == nullptr)
1443  {
1444  return;
1445  }
1446  TYElement* pParent = pElement->getParent();
1447  if (pParent == nullptr)
1448  {
1449  return;
1450  }
1451 
1452  TYMaillageGeoNode* pGeoNode = TYGeometryNode::GetGeoNode(pElement);
1453 
1454  // Nouvel element du meme type que l'objet a dupliquer (clone)
1455  LPTYMaillageGeoNode pCopy = new TYMaillageGeoNode(dynamic_cast<TYMaillage*>(pElement->clone()));
1456 
1457  // Duplication
1458  pCopy->deepCopy(pGeoNode, false);
1459  pCopy->setParent(pParent);
1460 
1461  // Nettoyage
1462  dynamic_cast<TYMaillage*>(pCopy->getElement())->clearResult();
1463 
1464  // Ajout
1465  if ((dynamic_cast<TYProjet*>(pParent))->addMaillage(pCopy))
1466  {
1467  TYRectangularMaillage* pMaillage = dynamic_cast<TYRectangularMaillage*>(pCopy->getElement());
1468  double x = 10., y = 10.;
1469  if (pMaillage != nullptr)
1470  {
1471  LPTYRectangle pRect = pMaillage->getRectangle();
1472  x = pRect->getSizeX() / 2.;
1473  y = pRect->getSizeY() / 2.;
1474  }
1475 
1476  ORepere3D repere = pCopy->getORepere3D();
1477  // Offset
1478  repere._origin._x += x;
1479  repere._origin._y -= y;
1480 
1481  pCopy->setRepere(repere);
1482 
1483  // Update Graphic
1484  pCopy->updateGraphicTree();
1485 
1486  // Action
1487  TYAction* pAction = new TYAddMaillageToProjetAction(pCopy, (dynamic_cast<TYProjet*>(pParent)),
1488  _pModeler, TR("id_action_addmaillage"));
1489  _pModeler->getActionManager()->addAction(pAction);
1490 
1491  // Mise à jour du modeleur
1492  dynamic_cast<TYSiteModelerFrame*>(_pModeler)->updateSelectMaillageBox();
1493  dynamic_cast<TYSiteModelerFrame*>(_pModeler)->updateElementGraphic(true);
1494 
1495  // Mise à jour de l'arborescence de projet
1497  }
1498 
1499  // La scene a ete modifiee
1501 }
1502 
1504 {
1505  if (pElement == nullptr)
1506  {
1507  return;
1508  }
1509  TYElement* pParent = pElement->getParent();
1510  if (pParent == nullptr)
1511  {
1512  return;
1513  }
1514 
1515  LPTYMaillageGeoNode pGeoNode = TYGeometryNode::GetGeoNode(pElement);
1516  LPTYProjet pProjet = getTYApp()->getCurProjet();
1517 
1518  if (pProjet && pProjet->remMaillage(dynamic_cast<TYMaillage*>(pElement)))
1519  {
1520  TYAction* pAction =
1521  new TYRemMaillageToProjetAction(pGeoNode, pProjet, _pModeler, TR("id_action_remmaillage"));
1522  _pModeler->getActionManager()->addAction(pAction);
1523  }
1524 
1525  dynamic_cast<TYSiteModelerFrame*>(_pModeler)->updateSelectMaillageBox();
1526  dynamic_cast<TYSiteModelerFrame*>(_pModeler)->updateElementGraphic(true);
1527 
1529 
1530  // La scene a ete modifiee
1532 }
1533 
1535 {
1536  if (pElement == nullptr)
1537  {
1538  return;
1539  }
1540  TYElement* pParent = pElement->getParent();
1541  if (pParent == nullptr)
1542  {
1543  return;
1544  }
1545 
1546  // Nouvel element du meme type que l'objet a dupliquer (clone)
1547  LPTYPointControl pCopy = dynamic_cast<TYPointControl*>(pElement->clone());
1548 
1549  // Duplication
1550  pCopy->deepCopy(dynamic_cast<TYPointControl*>(pElement), false);
1551  pCopy->setParent(pElement->getParent());
1552 
1553  // Ajout
1554  if ((dynamic_cast<TYProjet*>(pParent))->addPointControl(pCopy))
1555  {
1556  // Offset
1557  pCopy->_x += 10.0;
1558  pCopy->_y -= 10.0;
1559 
1560  // Update Graphic
1561  pCopy->updateGraphicTree();
1562 
1564 
1565  // Action
1566  TYAction* pAction = new TYAddPointControlAction(dynamic_cast<TYProjet*>(pParent), pCopy, _pModeler,
1567  TR("id_action_addptcontrol"));
1568  _pModeler->getActionManager()->addAction(pAction);
1569  }
1570 
1572  getTYMainWnd()->updateModelers(false);
1573 
1574  // La scene a ete modifiee
1576 }
1578 {
1579  if (pElement == nullptr)
1580  {
1581  return;
1582  }
1583  LPTYProjet pParent = dynamic_cast<TYProjet*>(pElement->getParent());
1584  if (pParent == nullptr)
1585  {
1586  return;
1587  }
1588 
1589  if (pParent->remPointControl(dynamic_cast<TYPointControl*>(pElement)))
1590  {
1591  TYAction* pAction = new TYRemPointControlAction(pParent, dynamic_cast<TYPointControl*>(pElement),
1592  _pModeler, TR("id_action_remptcontrol"));
1593  _pModeler->getActionManager()->addAction(pAction);
1594  }
1595 
1597  getTYMainWnd()->updateModelers(false);
1598 
1599  // La scene a ete modifiee
1601 }
1603 {
1604  if (pElement == nullptr)
1605  {
1606  return;
1607  }
1608  TYTopographie* pTopo = dynamic_cast<TYTopographie*>(pElement->getParent());
1609  if (pTopo == nullptr)
1610  {
1611  return;
1612  }
1613 
1614  // On recupere le site parent
1615  TYAction* pAction = new TYRemElementToTopoAction(pElement, pTopo, _pModeler, TR("id_action_remelttopo"));
1616  _pModeler->getActionManager()->addAction(pAction);
1617 
1618  if (pElement->isA("TYCourbeNiveau"))
1619  {
1620  pTopo->remCrbNiv((LPTYCourbeNiveau&)pElement);
1621  }
1622  else if (pElement->isA("TYTerrain"))
1623  {
1624  pTopo->remTerrain((LPTYTerrain&)pElement);
1625  }
1626  else if (pElement->isA("TYCoursEau"))
1627  {
1628  pTopo->remCrsEau((LPTYCoursEau&)pElement);
1629  }
1630  else if (pElement->isA("TYPlanEau"))
1631  {
1632  pTopo->remPlanEau((LPTYPlanEau&)pElement);
1633  }
1634 
1635  updateSiteFrame();
1636 
1637  // La scene a ete modifiee
1639 }
1641 {
1642  if (pElement == nullptr)
1643  {
1644  return;
1645  }
1646  TYTopographie* pTopo = dynamic_cast<TYTopographie*>(pElement->getParent());
1647  if (pTopo == nullptr)
1648  {
1649  return;
1650  }
1651 
1652  SmartPtr<TYGeometryNode> pCopyTmp = nullptr;
1653  LPTYGeometryNode pCopy = nullptr;
1654 
1655  if (pElement->isA("TYCourbeNiveau"))
1656  {
1657  // Nouvel element
1658  pCopy = new TYCourbeNiveauGeoNode(new TYCourbeNiveau());
1659  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1660 
1661  // Duplication
1662  pCopy->deepCopy(pTopo->findCrbNiv((LPTYCourbeNiveau&)pElement), false);
1663  pCopy->setParent(pElement->getParent());
1664 
1665  // Ajout
1666  pTopo->addCrbNiv(pCopy);
1667 
1668  // Offset
1669  TYCourbeNiveau* courbeNiveau = TYCourbeNiveau::safeDownCast(pCopy->getElement());
1670  courbeNiveau->offsetListPoints();
1671  }
1672  else if (pElement->isA("TYTerrain"))
1673  {
1674  // Nouvel element
1675  pCopy = new TYTerrainGeoNode(new TYTerrain);
1676  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1677 
1678  // Duplication
1679  pCopy->deepCopy(pTopo->findTerrain((LPTYTerrain&)pElement), false);
1680  pCopy->setParent(pElement->getParent());
1681 
1682  // Ajout
1683  pTopo->addTerrain(pCopy);
1684 
1685  // Offset
1686  TYTerrain* terrain = TYTerrain::safeDownCast(pCopy->getElement());
1687  terrain->offsetListPoints();
1688  }
1689  else if (pElement->isA("TYCoursEau"))
1690  {
1691  // Nouvel element
1692  pCopy = new TYCoursEauGeoNode(new TYCoursEau);
1693  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1694 
1695  // Duplication
1696  pCopy->deepCopy(pTopo->findCrsEau((LPTYCoursEau&)pElement), false);
1697  pCopy->setParent(pElement->getParent());
1698 
1699  // Ajout
1700  pTopo->addCrsEau(pCopy);
1701  }
1702  else if (pElement->isA("TYPlanEau"))
1703  {
1704  // Nouvel element
1705  pCopy = new TYPlanEauGeoNode(new TYPlanEau);
1706  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1707 
1708  // Duplication
1709  pCopy->deepCopy(pTopo->findPlanEau((LPTYPlanEau&)pElement), false);
1710  pCopy->setParent(pElement->getParent());
1711 
1712  // Ajout
1713  pTopo->addPlanEau(pCopy);
1714 
1715  // Offset
1716  TYPlanEau* planEau = TYPlanEau::safeDownCast(pCopy->getElement());
1717  planEau->offsetListPoints();
1718  }
1719 
1720  // if (pCopyTmp)
1721  //{
1722  // ORepere3D repere = pCopyTmp->getORepere3D();
1723  // // Offset
1724  // repere._origin._x += 50.0;
1725  // repere._origin._y -= 50.0;
1726  // pCopyTmp->setRepere(repere);
1727 
1728  // // Action
1729  // TYAction* pAction = new TYAddElementToTopoAction(pCopyTmp, pTopo, _pModeler,
1730  // TR("id_action_addelttopo")); _pModeler->getActionManager()->addAction(pAction);
1731 
1732  // // Update graphic
1733  // pCopyTmp->updateGraphicTree();
1734  //}
1735 
1736  // Ajout de l'élément TYCourbeNiveau ou TYPlanEau dans le calcul courant s'il existe
1737  if ((pElement->isA("TYPlanEau") || pElement->isA("TYCourbeNiveau")) && pCopy &&
1738  getTYApp()->getCurProjet() && getTYApp()->getCurProjet()->getCurrentCalcul())
1739  {
1741  }
1742  updateSiteFrame();
1743 
1744  // La scene a ete modifiee
1746 }
1748 {
1749  if (pElement == nullptr)
1750  {
1751  return;
1752  }
1753  TYInfrastructure* pInfra = dynamic_cast<TYInfrastructure*>(pElement->getParent());
1754  if (pInfra == nullptr)
1755  {
1756  return;
1757  }
1758 
1759  TYAction* pAction =
1760  new TYRemElementToInfraAction(pElement, pInfra, _pModeler, TR("id_action_remeltinfra"));
1761  _pModeler->getActionManager()->addAction(pAction);
1762 #if WITH_NMPB
1763  if (pElement->isA("TYRoute"))
1764  {
1765  pInfra->remRoute((LPTYRoute&)pElement);
1766  }
1767 #endif
1768  if (pElement->isA("TYReseauTransport"))
1769  {
1770  pInfra->remResTrans((LPTYReseauTransport&)pElement);
1771  }
1772  else if (pElement->isA("TYBatiment"))
1773  {
1774  pInfra->remBatiment((LPTYBatiment&)pElement);
1775  }
1776  else if (pElement->isA("TYMachine"))
1777  {
1778  pInfra->remMachine((LPTYMachine&)pElement);
1779  }
1780  else if (pElement->isA("TYUserSourcePonctuelle"))
1781  {
1782  pInfra->remSrc((LPTYUserSourcePonctuelle&)pElement);
1783  }
1784 
1785  updateSiteFrame(); // Mise a jour de l'arborescence du site
1786 
1787  // La scene a ete modifiee
1789 }
1791 {
1792  if (pElement == nullptr)
1793  {
1794  return;
1795  }
1796  TYInfrastructure* pInfra = dynamic_cast<TYInfrastructure*>(pElement->getParent());
1797  if (pInfra == nullptr)
1798  {
1799  return;
1800  }
1801 
1802  SmartPtr<TYGeometryNode> pCopyTmp = nullptr;
1803  TYBox boundBox;
1804 
1805  LPTYGeometryNode pCopy = nullptr;
1806 #if WITH_NMPB
1807  if (pElement->isA("TYRoute"))
1808  {
1809  // Nouvelle element
1810  pCopy = new TYRouteGeoNode(new TYRoute);
1811  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1812 
1813  // Duplication
1814  pCopy->deepCopy(pInfra->findRoute((LPTYRoute&)pElement), false);
1815  pCopy->setParent(pElement->getParent());
1816 
1817  // Ajout
1818  pInfra->addRoute(pCopy);
1819  }
1820 #endif
1821  if (pElement->isA("TYReseauTransport"))
1822  {
1823  // Nouvel element
1825  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1826 
1827  // Duplication
1828  pCopy->deepCopy(pInfra->findResTrans((LPTYReseauTransport&)pElement), false);
1829  pCopy->setParent(pElement->getParent());
1830 
1831  // Ajout
1832  pInfra->addResTrans(pCopy);
1833  }
1834  else if (pElement->isA("TYBatiment"))
1835  {
1836  // Nouvelle element
1837  pCopy = new TYBatimentGeoNode(new TYBatiment);
1838  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1839 
1840  // Duplication
1841  pCopy->deepCopy(pInfra->findBatiment((LPTYBatiment&)pElement), false);
1842  pCopy->setParent(pElement->getParent());
1843  updateCopyPosition(pCopy);
1844 
1845  // Ajout
1846  pInfra->addBatiment(pCopy);
1847  }
1848  else if (pElement->isA("TYMachine"))
1849  {
1850  // Nouvelle element
1851  pCopy = new TYMachineGeoNode(new TYMachine);
1852  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1853 
1854  // Duplication
1855  pCopy->deepCopy(pInfra->findMachine((LPTYMachine&)pElement), false);
1856  pCopy->setParent(pElement->getParent());
1857  updateCopyPosition(pCopy);
1858 
1859  // Ajout
1860  pInfra->addMachine(pCopy);
1861  }
1862  else if (pElement->isA("TYUserSourcePonctuelle"))
1863  {
1864  // Nouvelle element
1866  pCopyTmp = (SmartPtr<TYGeometryNode>&)pCopy;
1867 
1868  // Duplication
1869  pCopy->deepCopy(pInfra->findSrc((LPTYUserSourcePonctuelle&)pElement), false, true);
1870  pCopy->setParent(pElement->getParent());
1871 
1872  // Ajout
1873  pInfra->addSrc(pCopy);
1874 
1875  // Offset
1876  TYUserSourcePonctuelle::safeDownCast(pCopy->getElement())->getPos()->_x += 10;
1877  TYUserSourcePonctuelle::safeDownCast(pCopy->getElement())->getPos()->_y -= 10;
1878  }
1879 
1880  // if (pCopyTmp)
1881  //{
1882  // if (!pElement->isA("TYUserSourcePonctuelle"))
1883  // {
1884  // ORepere3D repere = pCopyTmp->getORepere3D();
1885 
1886  // // Offset proportionnel a la taille de l'objet
1887  // repere._origin._x += boundBox._sizeX; //10.0;
1888  // repere._origin._y -= boundBox._sizeY; //10.0;
1889 
1890  // pCopyTmp->setRepere(repere);
1891  // }
1892 
1893  // // Action
1894  // TYAction* pAction = new TYAddElementToInfraAction(pCopyTmp, pInfra, _pModeler,
1895  // TR("id_action_addeltinfra")); _pModeler->getActionManager()->addAction(pAction);
1896  //}
1897 
1898  // On l'ajoute dans le calcul courant (si calcul courant il y a !)
1899  if (pCopy && getTYApp()->getCurProjet() && getTYApp()->getCurProjet()->getCurrentCalcul())
1900  {
1902  }
1903 
1904  updateSiteFrame(); // Mise a jour de l'arborescence du site
1905 
1906  // La scene a ete modifiee
1908 }
1910 {
1911  if (pElement == nullptr)
1912  {
1913  return;
1914  }
1915  // On preserve la dimension en hauteur de l'objet
1916  TYAcousticVolume* pVol = dynamic_cast<TYAcousticVolume*>(pElement);
1917  if (pVol == nullptr)
1918  {
1919  return;
1920  }
1921 
1922  float sizeX = 0, sizeY = 0, sizeZ = 0;
1923 
1924  if (pVol != nullptr)
1925  {
1926  if (pVol->isA("TYAcousticBox"))
1927  {
1928  TYAcousticBox* pBox = (TYAcousticBox*)pVol;
1929  pBox->getDimension(sizeX, sizeY, sizeZ);
1930  }
1931  else if (pVol->isA("TYAcousticCylinder"))
1932  {
1933  sizeZ = ((TYAcousticCylinder*)pVol)->getHauteur();
1934  }
1935  else if (pVol->isA("TYAcousticSemiCylinder"))
1936  {
1937  sizeZ = ((TYAcousticSemiCylinder*)pVol)->getHauteur();
1938  }
1939  }
1940 
1941  // Affichage de la boite de dialogue
1942  showDimensionsDialog(pVol);
1943 
1944  // Modification de la position pour tenir compte des nouvelles dimensions
1946  LPTYAcousticVolumeGeoNode pGeoNode = pParent->findAcousticVol(pVol);
1947 
1948  if (pGeoNode)
1949  {
1950  if (pElement->isA("TYAcousticBox"))
1951  {
1952  TYAcousticBox* pAccBox = (TYAcousticBox*)pVol;
1953  pAccBox->getDimension(sizeX, sizeY, sizeZ);
1954  ((TYAcousticBox*)(TYAcousticVolume*)pElement)->setDimension(sizeX, sizeY, sizeZ);
1955  return;
1956  }
1957  else if (pVol->isA("TYAcousticCylinder"))
1958  {
1959  sizeZ = ((TYAcousticCylinder*)pVol)->getHauteur();
1960  ((TYAcousticCylinder*)(TYAcousticVolume*)pElement)->setHauteur(sizeZ);
1961  }
1962  else if (pVol->isA("TYAcousticSemiCylinder"))
1963  {
1964  sizeZ = ((TYAcousticSemiCylinder*)pVol)->getHauteur();
1965  ((TYAcousticSemiCylinder*)(TYAcousticVolume*)pElement)->setHauteur(sizeZ);
1966  }
1967  }
1968 }
1970 {
1971  if (pElement == nullptr)
1972  {
1973  return;
1974  }
1975  TYAcousticVolumeNode* pParent = dynamic_cast<TYAcousticVolumeNode*>(pElement->getParent());
1976  if (pParent == nullptr)
1977  {
1978  return;
1979  }
1980  TYAcousticVolumeGeoNode* pGeoNode = pParent->findAcousticVol(dynamic_cast<TYAcousticVolume*>(pElement));
1981  if (pGeoNode == nullptr)
1982  {
1983  return;
1984  }
1985 
1986  // The action is added to the ActionManager before the object is deleted
1987  TYAction* pAction =
1988  new TYRemAccVolToAccVolNodeAction(pGeoNode, pParent, _pModeler, TR("id_action_remvol"));
1989  _pModeler->getActionManager()->addAction(pAction);
1990  pParent->remAcousticVol(dynamic_cast<TYAcousticVolume*>(pElement));
1991  updateSiteFrame();
1992 
1993  // La scene a ete modifiee
1995 }
1997 {
1998  if (pElement == nullptr)
1999  {
2000  return;
2001  }
2002  TYAcousticVolumeNode* pVolParent = dynamic_cast<TYAcousticVolumeNode*>(pElement->getParent());
2003  if (pVolParent == nullptr)
2004  {
2005  return;
2006  }
2008  if (pGeoNode == nullptr)
2009  {
2010  return;
2011  }
2012 
2013  // Nouvel element du meme type que l'objet a dupliquer (clone)
2015  new TYAcousticVolumeGeoNode(dynamic_cast<TYAcousticVolume*>(pElement->clone()));
2016 
2017  // Duplication
2018  pCopy->deepCopy(pGeoNode, false);
2019 
2020  // Ajout
2021  if (pVolParent->addAcousticVol(pCopy))
2022  {
2023  // Offset
2024  ORepere3D repere = pCopy->getORepere3D();
2025 
2026  if (dynamic_cast<TYEtage*>(pCopy->getElement()) != nullptr)
2027  {
2028  TYElement* pElt = pCopy->getElement();
2029  repere._origin._z += ((TYEtage*)pElt)->getHauteur();
2030  }
2031  else
2032  {
2033  repere._origin._x += 20.0;
2034  repere._origin._y -= 20.0;
2035  }
2036 
2037  pCopy->setRepere(repere);
2038  // Update Graphic
2039  pCopy->updateGraphicTree();
2040 
2041  // Action
2042  TYAction* pAction =
2043  new TYAddAccVolToAccVolNodeAction(pCopy, pVolParent, _pModeler, TR("id_action_addvol"));
2044  _pModeler->getActionManager()->addAction(pAction);
2045  }
2046 
2047  updateSiteFrame();
2048 
2049  // La scene a ete modifiee
2051 }
2053 {
2054  if (pElement == nullptr)
2055  {
2056  return;
2057  }
2058  TYAcousticRectangleNode* pAccRectNode = dynamic_cast<TYAcousticRectangleNode*>(pElement);
2059  if (pAccRectNode == nullptr)
2060  {
2061  return;
2062  }
2063 
2064  TYFaceModelerFrame* pFaceMdF;
2065  pFaceMdF = new TYFaceModelerFrame(pAccRectNode, getTYMainWnd()->getWorkspace(), "face modeler");
2066  pFaceMdF->setAttribute(Qt::WA_DeleteOnClose);
2067  getTYMainWnd()->getWorkspace()->addSubWindow(pFaceMdF)->setObjectName("TYFaceModelerFrame");
2068 
2069  pFaceMdF->showMaximized();
2070  pFaceMdF->fit();
2071 }
2073 {
2074  if (pElement == nullptr)
2075  {
2076  return;
2077  }
2078  TYAcousticVolume* pVol = dynamic_cast<TYAcousticVolume*>(pElement);
2079 
2080  if (pVol)
2081  {
2082  pVol->inverseNormales();
2083  }
2084  pVol->setNormalStatus();
2085 }
2087 {
2089  {
2090  if (pElement == nullptr)
2091  {
2092  return;
2093  }
2094  TYEtage* pEtage = dynamic_cast<TYEtage*>(pElement);
2095  if (pEtage == nullptr)
2096  {
2097  return;
2098  }
2099 
2100  bool ok = false;
2101  double hauteur =
2102  TYModelerFrame::getDouble("", TR("id_msg_gethauteur"), 0.0, 1000.0, pEtage->getHauteur(), ok);
2103 
2104  if (ok)
2105  {
2106  pEtage->setHauteur(hauteur);
2107  pEtage->updateGraphic();
2108  }
2109  }
2110 }
2112 {
2114  {
2115  TYEcran* pEcran = dynamic_cast<TYEcran*>(pElement);
2116 
2117  bool ok = false;
2118  double hauteur = TYModelerFrame::getDouble("", TR("id_msg_gethauteur_ecran"), 0.0, 1000.0,
2119  pEcran->getHauteur(), ok);
2120 
2121  if (ok)
2122  {
2123  pEcran->setHauteur(hauteur);
2124  pEcran->updateGeometry();
2125  pEcran->updateGraphic();
2126  }
2127  }
2128 }
2130 {
2132  {
2133  TYEcran* pEcran = dynamic_cast<TYEcran*>(pElement);
2134 
2135  bool ok = false;
2136  double epaisseur = TYModelerFrame::getDouble("", TR("id_msg_getepaisseur_ecran"), 0.0, 1000.0,
2137  pEcran->getEpaisseur(), ok);
2138 
2139  if (ok)
2140  {
2141  pEcran->setEpaisseur(epaisseur);
2142  pEcran->updateGeometry();
2143  pEcran->updateGraphic();
2144  }
2145  }
2146 }
2147 
2149 {
2150  TYBox boundBox = dynamic_cast<TYAcousticVolumeNode*>(pNode->getElement())->volEnglob();
2151 
2152  pNode->getORepere3D()._origin =
2153  pNode->getORepere3D()._origin + OCoord3D(boundBox._sizeX / 2., boundBox._sizeY / 2., 0.);
2154 }
double RADTODEG(double a)
Converts an angle from radians to degrees.
Definition: 3d.h:137
double DEGTORAD(double a)
Converts an angle from degrees to radians.
Definition: 3d.h:126
TYGeometryNode TYAcousticVolumeGeoNode
Noeud geometrique de type TYAcousticVolume.
fichier contenant differents types d'actions (fichier header)
TYApplication * getTYApp()
Retourne le pointeur sur l'application.
TYMainWindow * getTYMainWnd()
Retourne le pointeur sur la fenetre principale.
pour l'application Tympan (fichier header)
TYGeometryNode TYBatimentGeoNode
Noeud geometrique de type TYBatiment.
Definition: TYBatiment.h:90
TYGeometryNode TYCourbeNiveauGeoNode
Noeud geometrique de type TYCourbeNiveau.
TYGeometryNode TYCoursEauGeoNode
Noeud geometrique de type TYCoursEau.
Definition: TYCoursEau.h:66
boite de dialogue pour la gestion des dimensions des volumes (fichier header)
Classe Modeler specialisee pour l'edition des faces (fichier header)
TYGeometryNode TYMachineGeoNode
Noeud geometrique de type TYMachine.
Definition: TYMachine.h:164
TYGeometryNode TYMaillageGeoNode
Noeud geometrique de type TYMaillage.
Definition: TYMaillage.h:434
std::vector< LPTYMaillageGeoNode > TYTabMaillageGeoNode
Collection de noeuds geometriques de type TYMaillage.
Definition: TYMaillage.h:438
Fenetre principale de l'application Tympan (fichier header)
gestion des items de menu avec une police et des styles particuliers (gras, italique....
Classe generique pour une fenetre de modeleur (fichier header)
Representation graphique d'un panel d'informations (fichier header)
#define IMG(id)
#define TR(id)
gestion de l'element actionne par picking (fichier header)
Objet pour le picking graphique (fichier header)
TYGeometryNode TYPlanEauGeoNode
Noeud geometrique de type TYPlanEau.
Definition: TYPlanEau.h:198
boite de dialogue pour la gestion de la position selon les modes 'moving', 'rotation',...
Frame pour la gestion de projet (fichier header)
Representation graphique d'un maillage rectangulaire (fichier header)
Le role de cette classe est limite a emettre des signaux pouvant etre utilise pour interagir sur le r...
TYGeometryNode TYReseauTransportGeoNode
Noeud geometrique de type TYReseauTransport.
Boite de dialogue pour la saisie de la l'angle des objets (fichier header)
TYGeometryNode TYRouteGeoNode
Geometrical node of type TYRoute.
Definition: TYRoute.h:33
Frame pour la gestion de site (fichier header)
Classe Modeler specialisee pour l'edition des sites (fichier header)
TYGeometryNode TYSiteNodeGeoNode
Noeud geometrique de type TYSiteNode.
Definition: TYSiteNode.h:36
TYGeometryNode TYSourcePonctuelleGeoNode
Noeud geometrique de type TYSourcePonctuelle.
TYGeometryNode TYTerrainGeoNode
Noeud geometrique de type TYTerrain.
Definition: TYTerrain.h:177
outil IHM pour un objet metier de type TYElement (fichier header)
The 3D coordinate class.
Definition: 3d.h:226
double _y
y coordinate of OCoord3D
Definition: 3d.h:283
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
double _x
x coordinate of OCoord3D
Definition: 3d.h:282
The 4x4 matrix class.
Definition: 3d.h:625
int setRotationOz(double a)
Update a rotation matrix (Oz axis).
Definition: 3d.cpp:688
int setRotationOy(double a)
Update a rotation matrix (Oy axis).
Definition: 3d.cpp:676
int setRotationOx(double a)
Update a rotation matrix (Ox axis).
Definition: 3d.cpp:664
double _m[4][4]
The 4x4 matrix array.
Definition: 3d.h:974
The 3D point class.
Definition: 3d.h:487
virtual OPrototype * clone() const =0
static OPrototype * safeDownCast(OPrototype *pObject)
Definition: TYElement.cpp:71
bool isA(const char *className) const
Definition: TYElement.cpp:65
3D frame with a point and 3 vectors.
Definition: 3d.h:1263
OPoint3D _origin
The origin point.
Definition: 3d.h:1331
double getValueReal(double freq)
Definition: spectre.cpp:974
Frame class.
Definition: Repere.h:26
void set(vec3 _U, vec3 _V, vec3 _W, vec3 _O)
Set global coordinates of local axis U,V,W and origin O.
Definition: Repere.h:41
T * _pObj
The real pointer, must derived IRefCount.
Definition: smartptr.h:307
Classe abstraite pour la gestion de l'interaction entre la vue graphique (2D ou 3D) et le clavier et ...
void refreshProjectFrame()
Rafraichit l'arborescence du TYProjectFrame.
void updateSiteFrame()
Reconstruit l'arborescence du TYSiteFrame.
TYModelerFrame * _pModeler
Le modeler associe a cet editor.
TYRenderWindowInteractor * _pInteractor
La vue graphique associee a cet editor.
void getDimension(float &larg, float &lon, float &haut)
bool addAcousticVol(LPTYAcousticVolumeGeoNode pAccVolGeoNode, bool recursif=true)
LPTYAcousticVolumeGeoNode findAcousticVol(const LPTYAcousticVolume pAccVol)
bool remAcousticVol(const LPTYAcousticVolumeGeoNode pAccVolGeoNode)
virtual void inverseNormales()
void addAction(TYAction *pAction)
Ajoute une nouvelle action a l'historique.
Definit une action, necessaire pour la gestion de l'undo.
Definition: TYAction.h:37
ajout d'un volume acoustique a un ensemble de volumes acoustiques
Definition: TYActions.h:147
Action d'ajout d'un point de controle.
Definition: TYActions.h:876
Action d'ajout d'un site a un ensemble de sites.
Definition: TYActions.h:990
LPTYProjet getCurProjet()
Set/Get du projet courant.
TYCalculManager * getCalculManager()
Get du gestionnaire de calculs.
Definition: TYApplication.h:99
Definition: TYBox.h:34
double _sizeX
Dimension en X.
Definition: TYBox.h:128
double _sizeY
Dimension en Y.
Definition: TYBox.h:130
bool updateAcoustic(TYElement *pElement)
Appelle la methode de calcul acoustique du volume node passe.
bool askForResetResultat()
Previent l'utilisateur que le resultat va etre efface, si celui-ci est valide.
void getCalculElements(LPTYSiteNode pSite)
Recover all the elements of the scene which take part in the calculation.
Definition: TYCalcul.cpp:1038
bool addToSelection(TYUUID id)
Adds the item to the selection of this Calculation.
Definition: TYCalcul.cpp:873
LPTYCourbeNiveau split(const TYPoint &pt)
return a new level curve by spliting the actual one at indicated point
boite de dialogue pour la gestion des dimensions des volumes
void setEpaisseur(double epaisseur)
Definition: TYEcran.cpp:353
void updateGeometry()
Definition: TYEcran.cpp:372
double getHauteur() const
Definition: TYEcran.cpp:362
double getEpaisseur() const
Definition: TYEcran.cpp:367
void setHauteur(double hauteur)
Definition: TYEcran.cpp:344
classe graphique pour un element de base
void setVisible(bool visible=true)
void elementPicked(TYElement *pElt)
Indique qu'un element a ete picke, sans connaitre son type. Celui-ci sera de type "bas niveau".
void reset()
Retourne dans son etat initial.
void highlightElement(TYElement *pElt)
Dessine la boite englobante de l'element passe.
bool pick(int x, int y)
Effectue un picking en (x, y).
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...
TYElement * getParent() const
Definition: TYElement.h:706
static void setIsSavedOk(const bool &toSave)
Definition: TYElement.h:914
void setParent(TYElement *pParent)
Definition: TYElement.h:699
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
double getHauteur() const
Definition: TYEtage.cpp:1039
void setHauteur(double hauteur)
Definition: TYEtage.cpp:1015
Classe Modeler specialisee pour l'edition des faces.
const ORepere3D & getORepere3D() const
OMatrix localToGlobal() const
OMatrix globalToLocal() const
void setHauteur(const double &hauteur)
Set the heigth above the ground.
void setElement(LPTYElement pElt)
double getHauteur()
Get the height above the ground.
TYElement * getElement() const
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
static TYGeometryNode * GetGeoNode(TYElement *pElement)
void setRepere(const ORepere3D &repere)
bool remSrc(const LPTYUserSourcePonctuelle pSrc)
LPTYMachineGeoNode findMachine(const LPTYMachine pMachine)
bool addBatiment(LPTYBatimentGeoNode pBatimentGeoNode)
bool addMachine(LPTYMachineGeoNode pMachineGeoNode)
LPTYBatimentGeoNode findBatiment(const LPTYBatiment pBatiment)
bool addSrc(LPTYUserSourcePonctuelle pSrc)
bool remResTrans(const LPTYReseauTransportGeoNode pResTransGeoNode)
bool remMachine(const LPTYMachine pMachine)
LPTYUserSourcePonctuelleGeoNode findSrc(const LPTYUserSourcePonctuelle pSrc)
bool remBatiment(const LPTYBatimentGeoNode pBatimentGeoNode)
LPTYReseauTransportGeoNode findResTrans(const LPTYReseauTransport pResTrans)
bool addResTrans(LPTYReseauTransportGeoNode pResTransGeoNode)
Classe de definition d'un maillage.
Definition: TYMaillage.h:51
@ ValGlobalDBLin
Definition: TYMaillage.h:299
TYProjetFrame * getProjetFrame()
Definition: TYMainWindow.h:73
void updateModelers(bool clipping=true, bool axesAndGrid=true, bool displayList=true)
TYSiteFrame * getSiteFrame()
Definition: TYMainWindow.h:77
QMdiArea * getWorkspace()
Definition: TYMainWindow.h:63
Generic class for a modeler window.
LPTYElement getElement()
virtual bool computeCurPos(int x, int y, float *pos)
TYRenderWindowInteractor * getView()
TYElementPicker * getElementPicker()
TYActionManager * getActionManager()
bool askForResetResultat()
static double getDouble(const QString &title, const QString &txt, double min, double max, double val, bool &ok, int dec=2)
Actions de deplacement d'un GeometryNode.
Definition: TYActions.h:576
void invalidateScene(void)
classe graphique pour un panel d'informations
void setFirstPos(const std::string &firstPos)
Set de la premiere position.
Definition: TYPanel.h:96
void setValue(const std::string &value)
Set de la valeur.
Definition: TYPanel.h:134
void setSecondPos(const std::string &secondPos)
Set de la seconde position.
Definition: TYPanel.h:115
void remSite(TYElement *pElement)
void copyTopoElmt(TYElement *pElement)
void screenThick(TYElement *pElement)
void openFaceModeler(TYElement *pElement)
void inverseNormal(TYElement *pElement)
void copyMaillage(TYElement *pElement)
void updateCopyPosition(LPTYGeometryNode &pNode)
void copySite(TYElement *pElement)
void screenHeight(TYElement *pElement)
virtual void showPopupMenu(std::shared_ptr< LPTYElementArray > pElts)
void resetPicker()
Definition: TYPickEditor.h:112
void showRotationDialog(TYGeometryNode *pGeoNode)
void manageProperties(TYElement *pElement)
virtual void slotKeyPressed(int key)
bool realWorldPosition(OPoint3D &pt)
TYPickEditor(TYModelerFrame *pModeler)
void setVolumeSize(TYElement *pElement)
void showDimensionsDialog(TYAcousticVolume *pAccVol)
void removeVolume(TYElement *pElement)
void copyVolume(TYElement *pElement)
void batimentModelerPopupMenu(std::shared_ptr< LPTYElementArray > pElts)
void setRolloverTolerance(float tolerance)
Definition: TYPickEditor.h:74
void setPickTolerance(float tolerance)
Definition: TYPickEditor.h:59
virtual void slotMousePressed(int x, int y, Qt::MouseButton button, Qt::KeyboardModifiers state)
virtual void slotMouseLeave()
virtual void slotMouseReleased(int x, int y, Qt::MouseButton button, Qt::KeyboardModifiers state)
void floorHeight(TYElement *pElement)
void showPositionDialog(TYGeometryNode *pGeoNode, bool activeHeight)
void remTopoElmt(TYElement *pElement)
void copyInfraElmt(TYElement *pElement)
TYElementPicker * _pPicker
Le picker du modeler.
Definition: TYPickEditor.h:154
void siteModelerPopupMenu(std::shared_ptr< LPTYElementArray > pElts)
QPoint _lastPressedCurPos
Derniere position de la souris.
Definition: TYPickEditor.h:157
float _pickTolerance
Tolerance du picking.
Definition: TYPickEditor.h:169
void remPtCtrl(TYElement *pElement)
void machineModelerPopupMenu(std::shared_ptr< LPTYElementArray > pElts)
LPTYElement _pLastRolloverElt
Definition: TYPickEditor.h:161
void remInfraElmt(TYElement *pElement)
QPoint _lastMovedCurPos
Definition: TYPickEditor.h:158
void remMaillage(TYElement *pElement)
void splitCurve(TYElement *pElement)
void copyPtCtrl(TYElement *pElement)
virtual void slotMouseMoved(int x, int y, Qt::MouseButtons button, Qt::KeyboardModifiers state)
bool _useHighlight
Flag pour l'activation du highlight.
Definition: TYPickEditor.h:164
void showPanel(TYElement *pElt)
bool _usePopup
Flag pour l'activation du popup menu.
Definition: TYPickEditor.h:166
virtual void slotWheeled(int x, int y, int delta, Qt::KeyboardModifiers state)
void offsetListPoints()
Definition: TYPlanEau.cpp:159
double getValLin()
Get de la valeur globale Lin au point.
virtual LPTYSpectre getSpectre()
Get du spectre resultat d'un calcul donne.
double getValA()
Get de la valeur globale A au point.
Classe de definition d'un point de controle.Le point de controle est un point de calcul avec une haut...
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
boite de dialogue pour la gestion de la position selon les modes 'moving', 'rotation',...
void setHauteurEnabled(const bool &enable)
Get/Set de l'etat de la zone de saisie des hauteurs.
classe de definition d'un projet.
Definition: TYProjet.h:45
TYTabMaillageGeoNode & getMaillages()
Get de la collection de maillages.
Definition: TYProjet.h:261
bool remPointControl(LPTYPointControl pPointControl)
Definition: TYProjet.cpp:466
bool remMaillage(const LPTYMaillageGeoNode pMaillageGeoNode)
Suppression d'un maillage.
Definition: TYProjet.cpp:872
LPTYSiteNode getSite()
Get du site.
Definition: TYProjet.h:169
LPTYCalcul getCurrentCalcul()
Set/Get du pointeur du Calcul courant.
Definition: TYProjet.h:426
float getSizeX()
float getSizeY()
Classe de definition d'un maillage rectangulaire.
LPTYRectangle getRectangle() const
Retourne le rectangle associe a ce maillage.
suppression d'un volume acoustique a un ensemble de volumes acoustiques
Definition: TYActions.h:178
Suppression d'un element a une infrastructure.
Definition: TYActions.h:431
Suppression d'un element a la topographie.
Definition: TYActions.h:368
Action de suppression d'un point de controle.
Definition: TYActions.h:902
Action de suppression d'un site a un ensemble de sites.
Definition: TYActions.h:1021
const TYRenderViewport & getViewport() const
TYOpenGLRenderer * getRenderer()
Actions de rotation d'un GeometryNode.
Definition: TYActions.h:608
Boite de dialogue pour la saisie de la l'angle des objets.
void lockXY()
Empeche les rotations selon X et Y (utile pour les sites ...)
bool getConcatenateStatus()
Retourne l'etat du checkbox de concatenation des rotations.
void updateList()
Classe Modeler specialisee pour l'edition des sites.
LPTYSiteNode getSite()
LPTYTopographie getTopographie()
Definition: TYSiteNode.h:149
bool remSiteNode(const LPTYSiteNodeGeoNode pSiteNodeGeoNode)
void update(const bool &force=false)
bool getRoot() const
Definition: TYSiteNode.h:321
void offsetListPoints()
Definition: TYTerrain.cpp:279
LPTYCourbeNiveauGeoNode findCrbNiv(const LPTYCourbeNiveau pCrbNiv)
LPTYTerrainGeoNode findTerrain(const LPTYTerrain pTerrain)
bool remCrbNiv(const LPTYCourbeNiveauGeoNode pCrbNivGeoNode)
bool addCrsEau(LPTYCoursEauGeoNode pCoursEauGeoNode)
LPTYPlanEauGeoNode findPlanEau(const LPTYPlanEau pPlanEau)
bool remPlanEau(const LPTYPlanEauGeoNode pPlanEauGeoNode)
LPTYCoursEauGeoNode findCrsEau(const LPTYCoursEau pCrsEau)
bool addCrbNiv(LPTYCourbeNiveauGeoNode pCrbNivGeoNode)
bool addPlanEau(LPTYPlanEauGeoNode pPlanEauGeoNode)
bool remCrsEau(const LPTYCoursEauGeoNode pCoursEauGeoNode)
bool addTerrain(LPTYTerrainGeoNode pTerGeoNode)
bool remTerrain(const LPTYTerrainGeoNode pTerGeoNode)
static QString getDisplayName(TYElement *pElt)
Definition: TYWidget.cpp:125
std::string doubleToStrPre(double val, int precision=2)
Definition: macros.h:205