Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYBoundaryNoiseMapEditor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
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 
52 
53 #define TR(id) OLocalizator::getString("TYBoundaryNoiseMapEditor", (id))
54 
55 #undef min
56 #undef max
57 
59 {
60  _dispDist = true;
61  QObject::connect(this, &TYBoundaryNoiseMapEditor::endedSavingPoints, this,
63 }
64 
66 
68 {
69  bool forceOpened = false;
70  if (!checkValidity(forceOpened))
71  {
72  return;
73  }
74  writeDebugMsg("Boundary Noise Map valid.");
75  createPropertiesDlg(forceOpened);
76 }
77 
79 {
80  if (!(getSavedPoints().size() > 1) || (!_pModeler->askForResetResultat()))
81  {
82  return false;
83  }
84 
85  const TYTabPoint& tabPts = this->getSavedPoints();
86  size_t nbPts = tabPts.size();
87  if (nbPts < 3)
88  {
89  // Not enough point to be a closed polyline
90  forceOpened = true;
91  return true;
92  }
93 
94  // We test if the polyline doesn't intersect itself
95  TYPoint ptInter;
96  for (size_t i = 0; i < nbPts; i++)
97  {
98  TYSegment seg1(tabPts[i], tabPts[(i + 1) % nbPts]);
99  for (size_t j = 0; j < nbPts; j++)
100  {
101  TYSegment seg2(tabPts[j], tabPts[(j + 1) % nbPts]);
102  // Test if at least one vertex is in common
103  if ((seg1._ptA != seg2._ptA) && (seg1._ptB != seg2._ptB) && (seg1._ptA != seg2._ptB) &&
104  (seg1._ptB != seg2._ptA))
105  {
106  // Test if there's an intersection
107  if (seg1.intersects(seg2, ptInter, TYSEUILCONFONDUS) != INTERS_NULLE)
108  {
109  // If the intersection occurs between the extremal point of the array
110  if ((i == nbPts - 1) || (j == nbPts - 1))
111  {
112  forceOpened = true;
113  }
114  else
115  {
116  writeDebugMsg("BoundaryNoiseMap invalid.");
117  QMessageBox::warning(_pModeler, TR("id_caption"),
118  TR("id_msg_boundarynoisemap_invalid"));
119  return false;
120  }
121  }
122  }
123  }
124  }
125  return true;
126 }
127 
129 {
130  QDialog* pDlg = new QDialog(_pModeler);
131  pDlg->setWindowTitle(TR("id_caption"));
132 
133  QGridLayout* pLayout = new QGridLayout();
134  pDlg->setLayout(pLayout);
135 
136  QGridLayout* pEditLayout = new QGridLayout();
137  pEditLayout->setContentsMargins(10, 10, 10, 10);
138  pLayout->addLayout(pEditLayout, 0, 0);
139 
140  // Height
141  QDoubleSpinBox* pHeightSpinBox = new QDoubleSpinBox();
142  pHeightSpinBox->setRange(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
143  pHeightSpinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
144  pHeightSpinBox->setFixedWidth(60);
145  pHeightSpinBox->setValue(2.0);
146  pEditLayout->addWidget(new QLabel(TR("id_height_label")), 0, 0);
147  pEditLayout->addWidget(pHeightSpinBox, 0, 1);
148 
149  // Thickness
150  _pThicknessSpinBox = new QDoubleSpinBox();
151  _pThicknessSpinBox->setRange(0.1, std::numeric_limits<double>::max());
152  _pThicknessSpinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
153  _pThicknessSpinBox->setFixedWidth(60);
154  pEditLayout->addWidget(new QLabel(TR("id_thickness_label")), 1, 0);
155  pEditLayout->addWidget(_pThicknessSpinBox, 1, 1);
156 
157  // Closed
158  QCheckBox* pClosedCheckBox = new QCheckBox();
159  pClosedCheckBox->setChecked(false);
160  if (forceOpened)
161  {
162  pClosedCheckBox->setDisabled(true);
163  }
164  pEditLayout->addWidget(new QLabel(TR("id_closed_label")), 2, 0);
165  pEditLayout->addWidget(pClosedCheckBox, 2, 1);
166 
167  // Density
168  _pDensitySpinBox = new QDoubleSpinBox();
169  _pDensitySpinBox->setFixedWidth(60);
170  _pDensitySpinBox->setSingleStep(0.1);
171  _pDensitySpinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
172  pEditLayout->addWidget(new QLabel(TR("id_density_label")), 3, 0);
173  pEditLayout->addWidget(_pDensitySpinBox, 3, 1);
174 
175  // Geometry
176  QBoxLayout* pGeomLayout = new QVBoxLayout();
177  _tabPtsW = new TabPointsWidget(getSavedPoints(), nullptr);
178  _tabPtsW->update();
179  pGeomLayout->addWidget(_tabPtsW);
180  pLayout->addLayout(pGeomLayout, 1, 0);
181 
182  QBoxLayout* pBtnLayout = new QHBoxLayout();
183  pLayout->addLayout(pBtnLayout, 2, 0);
184 
185  pBtnLayout->addStretch(1);
186 
187  // Ok button
188  QPushButton* pButtonOK = new QPushButton(TR("id_ok_btn"), pDlg);
189  pButtonOK->setDefault(true);
190  pBtnLayout->addWidget(pButtonOK);
191 
192  // Cancel button
193  QPushButton* pButtonCancel = new QPushButton(TR("id_cancel_btn"), pDlg);
194  pButtonCancel->setShortcut(Qt::Key_Escape);
195  pBtnLayout->addWidget(pButtonCancel);
196 
197  // Disambiguate the overloaded signals
198  void (QDoubleSpinBox::*_qDoubleSpinBox_valueChanged)(double) = &QDoubleSpinBox::valueChanged;
199 
200  // Connect and validity stuffs(relation between thickness and density)
201  QObject::connect(_pThicknessSpinBox, _qDoubleSpinBox_valueChanged, this,
203  QObject::connect(pButtonOK, &QPushButton::clicked, pDlg, &QDialog::accept);
204  QObject::connect(pButtonCancel, &QPushButton::clicked, pDlg, &QDialog::reject);
205 
206  // This line will trigger updateMinimumDensity()
207  _pThicknessSpinBox->setValue(10);
208  _pDensitySpinBox->setValue(_pDensitySpinBox->minimum() * 3.0); // arbitrary density
209 
210  // Display the properties dialog
211  int ret = pDlg->exec();
212  TYApplication::setOverrideCursor(Qt::WaitCursor);
213 
214  if (ret == QDialog::Accepted)
215  dialogConfirmed(pHeightSpinBox->value(), _pThicknessSpinBox->value(), pClosedCheckBox->isChecked(),
216  _pDensitySpinBox->value(), forceOpened);
217 
218  delete pEditLayout;
219  delete pBtnLayout;
221 
222  showText(false);
223 
227  TYApplication::restoreOverrideCursor();
228 }
229 
230 void TYBoundaryNoiseMapEditor::dialogConfirmed(double height, double thickness, bool closed, double density,
231  bool forceOpened)
232 {
233  _tabPtsW->apply();
234 
237  if (this->getSavedPoints().empty())
238  {
239  return;
240  }
241 
242  // We create the BoundaryNoiseMap entity
244 
245  LPTYBoundaryNoiseMap pBoundaryNoiseMap = new TYBoundaryNoiseMap();
246  pBoundaryNoiseMap->setCanBeClosed(!forceOpened);
247  LPTYBoundaryNoiseMapGeoNode pBoundaryNoiseMapGeoNode =
248  new TYBoundaryNoiseMapGeoNode((LPTYElement)pBoundaryNoiseMap);
249 
250  TYProjet* pProjet = pSiteModeler->getProjet();
251  // XXX What's happen when the pointer is NULL?!
252  if (pProjet)
253  {
254  // Init
255  pBoundaryNoiseMap->setHauteur(height);
256  pBoundaryNoiseMap->make(this->getSavedPoints(), thickness, closed, density);
257 
258  // Add action
259  TYAction* pAction =
260  new TYAddMaillageToProjetAction((LPTYMaillageGeoNode&)pBoundaryNoiseMapGeoNode, pProjet,
261  _pModeler, TR("id_action_add_boundarynoisemap"));
262  _pModeler->getActionManager()->addAction(pAction);
263 
264  pProjet->addMaillage((LPTYMaillageGeoNode&)pBoundaryNoiseMapGeoNode);
265 
266  if (pProjet->getSite()->getAltimetry()->containsData())
267  {
268  // Compte the noise map altimetry
269  pProjet->updateAltiMaillage(pBoundaryNoiseMapGeoNode);
270  }
271 
272  pBoundaryNoiseMap->updateGraphicTree();
273 
275  dynamic_cast<TYSiteModelerFrame*>(_pModeler)->updateSelectMaillageBox();
276  }
277 }
278 
280 {
282  std::numeric_limits<double>::max());
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:1201
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:1203
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:237
void updateMinimumDensity(double thickness)
Update the minimum value of the density thanks to the new thickness value.
QDoubleSpinBox * _pThicknessSpinBox
Thickness spin box.
TYBoundaryNoiseMapEditor(TYSiteModelerFrame *pModeler)
QDoubleSpinBox * _pDensitySpinBox
Density spin box.
void createPropertiesDlg(bool forceOpened)
Create the properties dialog that will pop up once the user finishes the polyline creation.
TabPointsWidget * _tabPtsW
Geometry description.
void endBoundaryNoiseMap()
Build a BoundaryNoiseMap from an array of points.
void dialogConfirmed(double height, double thickness, bool closed, double density, bool forceOpened)
When the user confirms the boundary noise map creation after the properties dialog pop up.
bool checkValidity(bool &forceOpened)
Return true if the polyline is valid and can be built. It also tells if the polyline should be opened...
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:915
TYRenderWindowInteractor * getView()
TYActionManager * getActionManager()
bool askForResetResultat()
virtual void updateView(bool clipping=true, bool axesAndGrid=true)
void updateDisplayList(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:783
bool updateAltiMaillage(TYMaillageGeoNode *pMaillageGeoNode, const TYAltimetrie *pAlti)
Met a niveau l'altimetrie d'un maillage.
Definition: TYProjet.cpp:906
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()