Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYBoundaryNoiseMapEditor.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 
23 #include <limits>
24 
25 #include <qmessagebox.h>
26 #include <qdialog.h>
27 #include <qlayout.h>
28 #include <qlabel.h>
29 #include <qpushbutton.h>
30 #include <qbuttongroup.h>
31 // Added by qt3to4:
32 #include <QHBoxLayout>
33 #include <QGridLayout>
34 #include <QGroupBox>
35 #include <QtWidgets>
36 
53 
54 #define TR(id) OLocalizator::getString("TYBoundaryNoiseMapEditor", (id))
55 
56 #undef min
57 #undef max
58 
60 {
61  _dispDist = true;
62  QObject::connect(this, &TYBoundaryNoiseMapEditor::endedSavingPoints, this,
64 }
65 
67 
69 {
70  bool forceOpened = false;
71  if (!checkValidity(forceOpened))
72  {
73  return;
74  }
75  writeDebugMsg("Boundary Noise Map valid.");
76  createPropertiesDlg(forceOpened);
77 }
78 
80 {
81  if (!(getSavedPoints().size() > 1) || (!_pModeler->askForResetResultat()))
82  {
83  return false;
84  }
85 
86  const TYTabPoint& tabPts = this->getSavedPoints();
87  size_t nbPts = tabPts.size();
88  if (nbPts < 3)
89  {
90  // Not enough point to be a closed polyline
91  forceOpened = true;
92  return true;
93  }
94 
95  // We test if the polyline doesn't intersect itself
96  TYPoint ptInter;
97  for (size_t i = 0; i < nbPts; i++)
98  {
99  TYSegment seg1(tabPts[i], tabPts[(i + 1) % nbPts]);
100  for (size_t j = 0; j < nbPts; j++)
101  {
102  TYSegment seg2(tabPts[j], tabPts[(j + 1) % nbPts]);
103  // Test if at least one vertex is in common
104  if ((seg1._ptA != seg2._ptA) && (seg1._ptB != seg2._ptB) && (seg1._ptA != seg2._ptB) &&
105  (seg1._ptB != seg2._ptA))
106  {
107  // Test if there's an intersection
108  if (seg1.intersects(seg2, ptInter, TYSEUILCONFONDUS) != INTERS_NULLE)
109  {
110  // If the intersection occurs between the extremal point of the array
111  if ((i == nbPts - 1) || (j == nbPts - 1))
112  {
113  forceOpened = true;
114  }
115  else
116  {
117  writeDebugMsg("BoundaryNoiseMap invalid.");
118  QMessageBox::warning(_pModeler, TR("id_caption"),
119  TR("id_msg_boundarynoisemap_invalid"));
120  return false;
121  }
122  }
123  }
124  }
125  }
126  return true;
127 }
128 
130 {
131  QDialog* pDlg = new QDialog(_pModeler);
132  pDlg->setWindowTitle(TR("id_caption"));
133 
134  QGridLayout* pLayout = new QGridLayout();
135  pDlg->setLayout(pLayout);
136 
137  QGridLayout* pEditLayout = new QGridLayout();
138  pEditLayout->setContentsMargins(10, 10, 10, 10);
139  pLayout->addLayout(pEditLayout, 0, 0);
140 
141  // Height
142  TYDoubleSpinBox* pHeightSpinBox = new TYDoubleSpinBox();
143  pHeightSpinBox->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
144  pHeightSpinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
145  pHeightSpinBox->setFixedWidth(60);
146  pHeightSpinBox->setValue(2.0);
147  pEditLayout->addWidget(new QLabel(TR("id_height_label")), 0, 0);
148  pEditLayout->addWidget(pHeightSpinBox, 0, 1);
149 
150  // Thickness
152  _pThicknessSpinBox->setRange(0.1, std::numeric_limits<double>::max());
153  _pThicknessSpinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
154  _pThicknessSpinBox->setFixedWidth(60);
155  pEditLayout->addWidget(new QLabel(TR("id_thickness_label")), 1, 0);
156  pEditLayout->addWidget(_pThicknessSpinBox, 1, 1);
157 
158  // Closed
159  QCheckBox* pClosedCheckBox = new QCheckBox();
160  pClosedCheckBox->setChecked(false);
161  if (forceOpened)
162  {
163  pClosedCheckBox->setDisabled(true);
164  }
165  pEditLayout->addWidget(new QLabel(TR("id_closed_label")), 2, 0);
166  pEditLayout->addWidget(pClosedCheckBox, 2, 1);
167 
168  // Density
170  _pDistanceSpinBox->setFixedWidth(60);
171  _pDistanceSpinBox->setSingleStep(0.1);
172  _pDistanceSpinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
173  pEditLayout->addWidget(new QLabel(TR("id_distance_label")), 3, 0);
174  pEditLayout->addWidget(_pDistanceSpinBox, 3, 1);
175 
176  // Geometry
177  QBoxLayout* pGeomLayout = new QVBoxLayout();
178  _tabPtsW = new TabPointsWidget(getSavedPoints(), nullptr);
179  _tabPtsW->update();
180  pGeomLayout->addWidget(_tabPtsW);
181  pLayout->addLayout(pGeomLayout, 1, 0);
182 
183  QBoxLayout* pBtnLayout = new QHBoxLayout();
184  pLayout->addLayout(pBtnLayout, 2, 0);
185 
186  pBtnLayout->addStretch(1);
187 
188  // Ok button
189  QPushButton* pButtonOK = new QPushButton(TR("id_ok_btn"), pDlg);
190  pButtonOK->setDefault(true);
191  pBtnLayout->addWidget(pButtonOK);
192 
193  // Cancel button
194  QPushButton* pButtonCancel = new QPushButton(TR("id_cancel_btn"), pDlg);
195  pButtonCancel->setShortcut(Qt::Key_Escape);
196  pBtnLayout->addWidget(pButtonCancel);
197 
198  // Disambiguate the overloaded signals
199  void (QDoubleSpinBox::*_qDoubleSpinBox_valueChanged)(double) = &QDoubleSpinBox::valueChanged;
200 
201  // Connect and validity stuffs(relation between thickness and density)
202  QObject::connect(_pThicknessSpinBox, _qDoubleSpinBox_valueChanged, this,
204  QObject::connect(pButtonOK, &QPushButton::clicked, pDlg, &QDialog::accept);
205  QObject::connect(pButtonCancel, &QPushButton::clicked, pDlg, &QDialog::reject);
206 
207  // This line will trigger updateMinimumDensity()
208  _pThicknessSpinBox->setValue(10);
209  _pDistanceSpinBox->setValue(2.0); // arbitrary distance
210 
211  // Display the properties dialog
212  int ret = pDlg->exec();
213  TYApplication::setOverrideCursor(Qt::WaitCursor);
214 
215  if (ret == QDialog::Accepted)
216  dialogConfirmed(pHeightSpinBox->value(), _pThicknessSpinBox->value(), pClosedCheckBox->isChecked(),
217  _pDistanceSpinBox->value(), forceOpened);
218 
219  delete pEditLayout;
220  delete pBtnLayout;
222 
223  showText(false);
224 
228  TYApplication::restoreOverrideCursor();
229 }
230 
231 void TYBoundaryNoiseMapEditor::dialogConfirmed(double height, double thickness, bool closed, double distance,
232  bool forceOpened)
233 {
234  _tabPtsW->apply();
235 
238  if (this->getSavedPoints().empty())
239  {
240  return;
241  }
242 
243  // We create the BoundaryNoiseMap entity
245 
246  LPTYBoundaryNoiseMap pBoundaryNoiseMap = new TYBoundaryNoiseMap();
247  pBoundaryNoiseMap->setCanBeClosed(!forceOpened);
248  LPTYBoundaryNoiseMapGeoNode pBoundaryNoiseMapGeoNode =
249  new TYBoundaryNoiseMapGeoNode((LPTYElement)pBoundaryNoiseMap);
250 
251  TYProjet* pProjet = pSiteModeler->getProjet();
252  // XXX What's happen when the pointer is NULL?!
253  if (pProjet)
254  {
255  // Init
256  pBoundaryNoiseMap->setHauteur(height);
257  pBoundaryNoiseMap->make(this->getSavedPoints(), thickness, closed, 1.0f / distance);
258 
259  // Add action
260  TYAction* pAction =
261  new TYAddMaillageToProjetAction((LPTYMaillageGeoNode&)pBoundaryNoiseMapGeoNode, pProjet,
262  _pModeler, TR("id_action_add_boundarynoisemap"));
263  _pModeler->getActionManager()->addAction(pAction);
264 
265  pProjet->addMaillage((LPTYMaillageGeoNode&)pBoundaryNoiseMapGeoNode);
266 
267  if (pProjet->getSite()->getAltimetry()->containsData())
268  {
269  // Compte the noise map altimetry
270  pProjet->updateAltiMaillage(pBoundaryNoiseMapGeoNode);
271  }
272 
273  pBoundaryNoiseMap->updateGraphicTree();
274 
276  dynamic_cast<TYSiteModelerFrame*>(_pModeler)->updateSelectMaillageBox();
277  }
278 }
279 
281 {
282  _pDistanceSpinBox->setRange(0.1, 1.0f / TYBoundaryNoiseMap::computeMinimumDensity(thickness));
283 }
284 
285 void TYBoundaryNoiseMapEditor::slotMousePressed(int x, int y, Qt::MouseButton button,
286  Qt::KeyboardModifiers state)
287 {
288  if ((button == Qt::LeftButton) && _active)
289  {
290  if (!getTYApp()->getCurProjet() || !getTYApp()->getCurProjet()->getCurrentCalcul())
291  {
292  _active = false;
293 
294  // Msg "No current TYCalcul...
295  QString msg(TR("id_warning_no_curcalcul"));
296  writeOutputMsg(msg);
297  QMessageBox::warning(_pModeler, "Tympan", msg, QMessageBox::Ok, QMessageBox::NoButton);
298  }
299  }
300 }
#define TYSEUILCONFONDUS
Definition: 3d.h:47
#define INTERS_NULLE
No intersection.
Definition: 3d.h:35
fichier contenant differents types d'actions (fichier header)
void writeOutputMsg(QString msg)
Affiche un message dans la fenetre de sortie.
TYApplication * getTYApp()
Retourne le pointeur sur l'application.
void writeDebugMsg(QString msg)
Affiche un message de debug dans la fenetre de sortie.
pour l'application Tympan (fichier header)
#define TR(id)
Creation of a TYBoundaryNoiseMap (header file)
TYGeometryNode TYBoundaryNoiseMapGeoNode
TYBoundaryNoiseMap geometry node.
std::vector< TYPoint > TYTabPoint
Collection de TYPoint.
Definition: TYDefines.h:340
Classe Modeler specialisee pour l'edition des sites (fichier header)
OPoint3D _ptA
Point A of the segment.
Definition: 3d.h:1253
virtual int intersects(const OSegment3D &seg, OPoint3D &pt, double seuilConfondus) const
Return the intersection point with another segment.
Definition: 3d.cpp:1267
OPoint3D _ptB
Point B of the segment.
Definition: 3d.h:1255
void refreshProjectFrame()
Rafraichit l'arborescence du TYProjectFrame.
TYModelerFrame * _pModeler
Le modeler associe a cet editor.
void showText(bool show=true)
Affiche ou pas le texte informatif sur la vue 3D.
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
bool containsData()
Definition: TYAltimetrie.h:251
void updateMinimumDensity(double thickness)
Update the minimum value of the density thanks to the new thickness value.
TYBoundaryNoiseMapEditor(TYSiteModelerFrame *pModeler)
TYDoubleSpinBox * _pDistanceSpinBox
Density spin box.
void createPropertiesDlg(bool forceOpened)
Create the properties dialog that will pop up once the user finishes the polyline creation.
TYDoubleSpinBox * _pThicknessSpinBox
Thickness spin box.
TabPointsWidget * _tabPtsW
Geometry description.
void endBoundaryNoiseMap()
Build a BoundaryNoiseMap from an array of points.
bool checkValidity(bool &forceOpened)
Return true if the polyline is valid and can be built. It also tells if the polyline should be opened...
void dialogConfirmed(double height, double thickness, bool closed, double distance, bool forceOpened)
When the user confirms the boundary noise map creation after the properties dialog pop up.
virtual void slotMousePressed(int x, int y, Qt::MouseButton button, Qt::KeyboardModifiers state)
This class represents a polyline with a thickness. Acoustic receptors are sampled inside this region.
static double computeMinimumDensity(double thickness)
Return the minimum density to get a correct sampling.
static void setIsSavedOk(const bool &toSave)
Definition: TYElement.h:905
TYRenderWindowInteractor * getView()
TYActionManager * getActionManager()
bool askForResetResultat()
virtual void updateView(bool clipping=true, bool axesAndGrid=true)
void invalidateScene(void)
gestion de l'edition d'une polyligne
void endedSavingPoints()
TYTabPoint & getSavedPoints()
bool _dispDist
Indique si l'information de distance doit etre affichee ou non.
bool _active
Indique si cet editor est actif.
classe de definition d'un projet.
Definition: TYProjet.h:45
bool addMaillage(LPTYMaillageGeoNode pMaillageGeoNode)
Ajout d'un maillage.
Definition: TYProjet.cpp:816
bool updateAltiMaillage(TYMaillageGeoNode *pMaillageGeoNode, const TYAltimetrie *pAlti)
Met a niveau l'altimetrie d'un maillage.
Definition: TYProjet.cpp:939
LPTYSiteNode getSite()
Get du site.
Definition: TYProjet.h:169
TYOpenGLRenderer * getRenderer()
Classe Modeler specialisee pour l'edition des sites.
LPTYAltimetrie getAltimetry() const
virtual void apply()
virtual void update()