Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYSiteNode.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 
16 #include <cstdlib>
17 #include <cassert>
18 #include <locale.h>
19 
20 #if TY_USE_IHM
23 #endif
24 
33 #include "Tympan/core/logging.h"
34 #include "Tympan/core/config.h"
35 #include <QDir>
36 
37 #include "TYSiteNode.h"
38 
39 #define TR(id) OLocalizator::getString("OMessageManager", (id))
40 
43 
44 bool almost_equal(double a, double b, double precision);
45 
46 #include <cstdio>
47 #include <QString>
48 
49 /*static*/ const QString& TYSiteNode::getTopoFilePath()
50 {
51  return _topoFilePath;
52 }
53 
54 /*static*/ void TYSiteNode::setTopoFilePath(const QString& path)
55 {
56  _topoFilePath = path;
57 }
58 
60 {
61  return _meshFilePath;
62 }
63 
64 void TYSiteNode::setMeshFilePath(const QString& path)
65 {
66  _meshFilePath = path;
67 }
68 
69 QString TYSiteNode::_topoFilePath = "";
70 
72  : _pProjet(NULL), _bEmpriseAsCrbNiv(false), _altiEmprise(0.0), _useTopoFile(0), _topoFileName(""),
73  _meshFilePath(""), _topoFileExtension(""), _echelle(1.0f), _nbFaceInfra(0), _root(false),
74  _SIGType(TYMPAN), _SIG_X(0.0), _SIG_Y(0.0), _SIG_OFFSET(0.0), _isTopoFileModified(false)
75 {
77 
78 #ifdef _WIN32
79  // CLM-NT35: Pb en debug avec string cast
80  QByteArray id = getStringID().toLatin1();
81  _topoFile = getTopoFilePath() + "/image_" + id.constData();
82 #else
83  _topoFile = getTopoFilePath() + "/image_" + getStringID().toLatin1().data();
84 #endif
85 
87  _pTopographie->setParent(this);
90 }
91 
93 {
94  *this = other;
95 }
96 
98 {
99  _listSiteNode.clear();
100 }
101 
103 {
104  if (this != &other)
105  {
106  TYElement::operator=(other);
107  _echelle = other._echelle;
109  _altiEmprise = other._altiEmprise;
111  _topoFile = other._topoFile;
115  _useTopoFile = other._useTopoFile;
118  _orientation = other._orientation;
119  _position = other._position;
120  _root = other._root;
122  _SIGType = other._SIGType;
123  _SIG_X = other._SIG_X;
124  _SIG_Y = other._SIG_Y;
125  _SIG_OFFSET = other._SIG_OFFSET;
126  }
127  return *this;
128 }
129 
130 bool TYSiteNode::operator==(const TYSiteNode& other) const
131 {
132  if (this != &other)
133  {
134  if (TYElement::operator!=(other))
135  {
136  return false;
137  }
138  if (_echelle != other._echelle)
139  {
140  return false;
141  }
143  {
144  return false;
145  }
146  if (_altiEmprise != other._altiEmprise)
147  {
148  return false;
149  }
150  if (_pTopographie != other._pTopographie)
151  {
152  return false;
153  }
154  if (_topoFile != other._topoFile)
155  {
156  return false;
157  }
158  if (_topoFileName != other._topoFileName)
159  {
160  return false;
161  }
162  if (_meshFilePath != other._meshFilePath)
163  {
164  return false;
165  }
167  {
168  return false;
169  }
170  if (_useTopoFile != other._useTopoFile)
171  {
172  return false;
173  }
175  {
176  return false;
177  }
178  if (_pInfrastructure != other._pInfrastructure)
179  {
180  return false;
181  }
182  if (_orientation != other._orientation)
183  {
184  return false;
185  }
186  if (_position != other._position)
187  {
188  return false;
189  }
190  if (_root != other._root)
191  {
192  return false;
193  }
194  if (!(_listSiteNode == other._listSiteNode))
195  {
196  return false;
197  }
198  if (_SIGType != other._SIGType)
199  {
200  return false;
201  }
202  if (_SIG_X != other._SIG_X)
203  {
204  return false;
205  }
206  if (_SIG_Y != other._SIG_Y)
207  {
208  return false;
209  }
210  if (_SIG_OFFSET != other._SIG_OFFSET)
211  {
212  return false;
213  }
214  }
215  return true;
216 }
217 
218 bool TYSiteNode::operator!=(const TYSiteNode& other) const
219 {
220  return !operator==(other);
221 }
222 
223 bool TYSiteNode::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
224 {
225  if (!TYElement::deepCopy(pOther, copyId))
226  {
227  return false;
228  }
229 
230  TYSiteNode* pOtherSite = (TYSiteNode*)pOther;
231 
232  _echelle = pOtherSite->_echelle;
233  _bEmpriseAsCrbNiv = pOtherSite->_bEmpriseAsCrbNiv;
234  _altiEmprise = pOtherSite->_altiEmprise;
235  _topoFile = pOtherSite->_topoFile;
236  _topoFileName = pOtherSite->_topoFileName;
237  _meshFilePath = pOtherSite->_meshFilePath;
239  _useTopoFile = pOtherSite->_useTopoFile;
241  _pTopographie->deepCopy(pOtherSite->_pTopographie, copyId);
242  _pTopographie->setParent(this);
243  _pInfrastructure->deepCopy(pOtherSite->_pInfrastructure, copyId);
245  _orientation.deepCopy(&pOtherSite->_orientation, copyId);
246  _position.deepCopy(&pOtherSite->_position, copyId);
247  _root = pOtherSite->_root;
248  _SIGType = pOtherSite->_SIGType;
249  _SIG_X = pOtherSite->_SIG_X;
250  _SIG_Y = pOtherSite->_SIG_Y;
251  _SIG_OFFSET = pOtherSite->_SIG_OFFSET;
252 
253  _listSiteNode.clear();
254  for (unsigned int i = 0; i < pOtherSite->_listSiteNode.size(); i++)
255  {
256  LPTYSiteNodeGeoNode pSiteNodeGeoNode = new TYSiteNodeGeoNode(NULL, this);
257  pSiteNodeGeoNode->deepCopy(pOtherSite->_listSiteNode[i], copyId);
258  pSiteNodeGeoNode->getElement()->setParent(this);
259  pSiteNodeGeoNode->setParent(this);
260  _listSiteNode.push_back(pSiteNodeGeoNode);
261  }
262 
263  return true;
264 }
265 
266 std::string TYSiteNode::toString() const
267 {
268  return "TYSiteNode";
269 }
270 
272 {
273  DOM_Element domNewElem = TYElement::toXML(domElement);
274 
275  TYXMLTools::addElementFloatValue(domNewElem, "echelle", _echelle);
276  TYXMLTools::addElementBoolValue(domNewElem, "useEmpriseAsCrbNiv", _bEmpriseAsCrbNiv);
277  TYXMLTools::addElementBoolValue(domNewElem, "useTopoFile", _useTopoFile);
278 
279  if (TYXMLManager::getSavedFileName() == QString(""))
280  {
281  TYXMLTools::addElementStringValue(domNewElem, "topoFile", _topoFileName);
282  TYXMLTools::addElementStringValue(domNewElem, "meshFile", _meshFilePath);
283  }
284  else // si non, on ecrit le chemin relatif
285  {
286  QString xmlFile = TYXMLManager::getSavedFileName().replace('\\', '/');
287  QDir xmlFileDir = QDir(xmlFile.left(xmlFile.lastIndexOf('/')));
288  if (xmlFileDir.exists())
289  {
290  TYXMLTools::addElementStringValue(domNewElem, "topoFile",
291  xmlFileDir.relativeFilePath(_topoFileName));
292  TYXMLTools::addElementStringValue(domNewElem, "meshFile",
293  xmlFileDir.relativeFilePath(_meshFilePath));
294  }
295  else
296  {
297  TYXMLTools::addElementStringValue(domNewElem, "topoFile", _topoFileName);
298  TYXMLTools::addElementStringValue(domNewElem, "topoFile", _meshFilePath);
299  }
300  }
301 
302  TYXMLTools::addElementDoubleValue(domNewElem, "altiEmprise", _altiEmprise);
303 
304  _orientation.toXML(domNewElem);
305  _position.toXML(domNewElem);
306 
307  _pTopographie->toXML(domNewElem);
308  _pInfrastructure->toXML(domNewElem);
309 
310  TYXMLTools::addElementIntValue(domNewElem, "root", _root);
311  TYXMLTools::addElementIntValue(domNewElem, "repere", _SIGType);
312  TYXMLTools::addElementDoubleValue(domNewElem, "SIG_X", _SIG_X);
313  TYXMLTools::addElementDoubleValue(domNewElem, "SIG_Y", _SIG_Y);
314  TYXMLTools::addElementDoubleValue(domNewElem, "SIG_OFFSET", _SIG_OFFSET);
315 
316  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
317  {
318  _listSiteNode[i]->toXML(domNewElem);
319  }
320 
321  return domNewElem;
322 }
323 
325 {
326  TYElement::fromXML(domElement);
327 
328  bool echelleOk = false;
329  QString topoFile;
330  QString meshFile;
331  bool topoFileOk = false;
332  bool meshFileOk = false;
333  bool empriseAsCrbNivOk = false;
334  bool altiEmpriseOk = false;
335  bool useTopoFileOk = false;
336  DOM_Element elemCur;
337 
338  QDomNodeList childs = domElement.childNodes();
339  unsigned int childcount = childs.length();
340  for (unsigned int i = 0; i < childcount; i++)
341  {
342  elemCur = childs.item(i).toElement();
343  OMessageManager::get()->info("Charge element de site %d/%d.", i + 1, childcount);
344 
345  TYXMLTools::getElementFloatValue(elemCur, "echelle", _echelle, echelleOk);
346  TYXMLTools::getElementBoolValue(elemCur, "useEmpriseAsCrbNiv", _bEmpriseAsCrbNiv, empriseAsCrbNivOk);
347  TYXMLTools::getElementBoolValue(elemCur, "useTopoFile", _useTopoFile, useTopoFileOk);
348  TYXMLTools::getElementStringValue(elemCur, "topoFile", topoFile, topoFileOk);
349  TYXMLTools::getElementStringValue(elemCur, "meshFile", meshFile, meshFileOk);
350  TYXMLTools::getElementDoubleValue(elemCur, "altiEmprise", _altiEmprise, altiEmpriseOk);
351 
353  _position.callFromXMLIfEqual(elemCur);
354 
357  }
358 
359  purge(); // On vide le tableau des sous-sites
360 
361  bool rootOk = false;
362  bool repereOk = false;
363  bool SIG_XOk = false;
364  bool SIG_YOk = false;
365  bool SIG_OFFSETOk = false;
366  int SIGType = 0;
367 
368  LPTYSiteNodeGeoNode pSiteNodeGeoNode = new TYSiteNodeGeoNode(NULL, this);
369  // DOM_Element elemCur;
370 
371  // QDomNodeList childs = domElement.childNodes();
372  for (unsigned int i = 0; i < childs.length(); i++)
373  {
374  elemCur = childs.item(i).toElement();
375  TYXMLTools::getElementBoolValue(elemCur, "root", _root, rootOk);
376  TYXMLTools::getElementIntValue(elemCur, "repere", SIGType, repereOk);
377  TYXMLTools::getElementDoubleValue(elemCur, "SIG_X", _SIG_X, SIG_XOk);
378  TYXMLTools::getElementDoubleValue(elemCur, "SIG_Y", _SIG_Y, SIG_YOk);
379  TYXMLTools::getElementDoubleValue(elemCur, "SIG_OFFSET", _SIG_OFFSET, SIG_OFFSETOk);
380 
381  if (pSiteNodeGeoNode->callFromXMLIfEqual(elemCur))
382  {
383  addSiteNode(pSiteNodeGeoNode);
384  pSiteNodeGeoNode = new TYSiteNodeGeoNode(NULL, this);
385  }
386  }
387 
388  _SIGType = (systemSIG)SIGType;
389 
390  if (_useTopoFile && topoFileOk)
391  {
392  _topoFileName = topoFile;
395  }
397  if (meshFileOk)
398  {
399  // 1) Normalisation et traces d’entrée
400  const QString meshFileNorm = QDir::fromNativeSeparators(meshFile);
401 
402  // 2) Récupération du dossier du XML
403  QString xmlDir;
404  const QString saved = QDir::fromNativeSeparators(TYXMLManager::getSavedFileName());
405 
406  if (!saved.isEmpty())
407  {
408  const QFileInfo sfi(saved);
409  const bool savedIsDir = sfi.isDir();
410  const QString candidate = savedIsDir ? sfi.absoluteFilePath() : sfi.absolutePath();
411  const bool candidateExists = QDir(candidate).exists();
412 
413  if (candidateExists)
414  {
415  xmlDir = candidate;
416  }
417  }
418 
419  // 3) Décision du chemin mesh : absolu VS relatif
420  const QFileInfo mfi(meshFileNorm);
421  const bool isAbs = mfi.isAbsolute();
422  if (isAbs)
423  {
424  _meshFilePath = mfi.absoluteFilePath();
425  }
426  else if (!xmlDir.isEmpty())
427  {
428  _meshFilePath = QDir(xmlDir).filePath(meshFileNorm);
429  }
430  else
431  {
432  _meshFilePath = meshFileNorm;
433  }
434 
435  // 4) Lancement de la lecture + traces tailles
436  std::deque<OPoint3D> points;
437  std::deque<OTriangle> triangles;
438  std::deque<LPTYSol> materials;
439 
440  logger->debug("[DBG][fromXML] Appel readMesh(...) avec _meshFilePath = %s",
441  qUtf8Printable(_meshFilePath));
442  if (readMesh(points, triangles, materials, _meshFilePath))
443  {
444  logger->debug("[DBG][fromXML] readMesh terminé: points=%zu, triangles=%zu, materials=%zu",
445  points.size(), triangles.size(), materials.size());
446 
447  // 5) Suite du pipeline + traces d’état
448  getAltimetry()->plugBackTriangulation(points, triangles, materials);
449  setIsGeometryModified(false);
450  getAltimetry()->setIsUpToDate(true);
451  }
452  else
453  {
454  logger->debug("[DBG][fromXML] Echec readMesh(...) avec _meshFilePath = %s",
455  qUtf8Printable(_meshFilePath));
456  _meshFilePath = QString{};
457  getAltimetry()->setIsUpToDate(false);
458  }
459  }
460  else
461  {
462  if (_root)
463  {
464  logger->info("[DBG][fromXML] meshFileOk=false -> pas de lecture");
465  _meshFilePath = QString{};
466  getAltimetry()->setIsUpToDate(false);
467  }
468  }
469 
470  return 1;
471 }
472 
473 void TYSiteNode::getChilds(LPTYElementArray& childs, bool recursif /*=true*/)
474 {
475  TYElement::getChilds(childs, recursif);
476 
477  childs.push_back(_pTopographie);
478  childs.push_back(_pInfrastructure);
479 
480  if (recursif)
481  {
482  _pTopographie->getChilds(childs, recursif);
483  _pInfrastructure->getChilds(childs, recursif);
484  }
485 
486  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
487  {
488  childs.push_back(_listSiteNode[i]);
489  childs.push_back(_listSiteNode[i]->getElement());
490  }
491 
492  if (recursif)
493  {
494  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
495  {
496  _listSiteNode[i]->getChilds(childs, recursif);
497  }
498  }
499 }
500 
502 {
504 
505  if (!_root && _pParent)
506  {
507  _pParent->setIsGeometryModified(isModified);
508  }
509 }
510 
512 {
513  bool res = _pInfrastructure->addToCalcul(); // Ajoute les elements du site lui-meme dans le calcul
514  res = res && (_pInfrastructure->addToCalcul());
515 
516  if (res && _listSiteNode.size())
517  {
518  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
519  {
520  res = res && (TYSiteNode::safeDownCast(_listSiteNode[i]->getElement()))->addToCalcul();
521  }
522  }
523 
524  return res;
525 }
526 
528 {
529  bool res = _pInfrastructure->remFromCalcul();
530  res = res && _pInfrastructure->remFromCalcul();
531  ;
532 
533  if (res && _listSiteNode.size())
534  {
535  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
536  {
537  res = res && (TYSiteNode::safeDownCast(_listSiteNode[i]->getElement()))->remFromCalcul();
538  }
539  }
540 
541  return res;
542 }
543 
544 void TYSiteNode::updateCurrentCalcul(TYListID& listID, bool recursif) //=true
545 {
546  if (recursif) // On parcours les enfants si besoin est...
547  {
548  // Collecte des childs
549  LPTYElementArray childs;
550  getChilds(childs, false);
551  for (int i = 0; i < childs.size(); i++)
552  {
553  childs[i]->updateCurrentCalcul(listID, recursif);
554  }
555  }
556 
557  TYElement::updateCurrentCalcul(listID, false);
558 }
559 
561 {
562  _pProjet = pProjet;
563  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
564  {
565  TYSiteNode::safeDownCast(_listSiteNode[i]->getElement())->setProjet(pProjet);
566  }
567 }
568 
570 {
573 
574  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
575  {
576  TYSiteNode::safeDownCast(_listSiteNode[i]->getElement())->reparent();
577  }
578 }
579 
580 void TYSiteNode::loadTopoFile(const QString& fileName)
581 {
582  _topoFileName = fileName;
583  loadTopoFile();
584 }
585 
587 {
588  QFile file(_topoFileName);
590  logger.info("Charge fichier topographique %s", qUtf8Printable(_topoFileName));
591 
592  // Open the file
593  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
594  {
595  logger.error("Erreur durant l'ouverture du fichier %s", qUtf8Printable(_topoFileName));
596  return;
597  }
598 
599  // Read all data from the file
600  QByteArray buffer = file.readAll();
601 
602  // Close the file
603  file.close();
604 
605  // Check if the file read was successful
606  if (buffer.isEmpty())
607  {
608  logger.error("Erreur durant la lecture du fichier %s", qUtf8Printable(_topoFileName));
609  return;
610  }
611 
612  // Convert QByteArray to char*
613  const char* data = buffer.constData();
614  size_t dataSize = buffer.size();
615 
616  /* the whole file is now loaded in the memory buffer. */
617 
618  // Mise a jour du flag.
619  _isTopoFileModified = true;
620 
621  // On conserve l'extension de l'image = son type
622  QFileInfo topoFileInfo(_topoFileName);
623  _topoFileExtension = topoFileInfo.suffix();
624 
625  setIsGeometryModified(true);
626 }
627 
628 /*virtual*/ bool TYSiteNode::updateAltimetrie(QString resultMeshFilePath)
629 {
630  std::ostringstream msg;
632  try
633  {
634  do_updateAltimetrie(resultMeshFilePath);
635  return true;
636  }
637  catch (const tympan::exception& exc)
638  {
639  msg << boost::diagnostic_information(exc);
640  logger.error("An error prevented to update the altimetry (set log level to debug for diagnostic)");
641  logger.debug(msg.str().c_str());
642  return false;
643  }
644 }
645 
646 /*virtual*/ void TYSiteNode::do_updateAltimetrie(QString resultMeshFilePath)
647 {
649 
650  // disables element names automatic generation (subsites fusion etc)
651  TYNameManager::get()->enable(false);
652 
653  logger.info("Mise a jour altimetrie...");
654 
655  // Is the debug option "TYMPAN_DEBUG=keep_tmp_files" enabled?
656  bool keep_tmp_files = must_keep_tmp_files();
657  // Will be used to export the current site topography/infrastructure
658  QTemporaryFile current_project;
659  current_project.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.xml"));
660  // Here will go the mesh result in a PLY Polygon formatted file
661  //(see http://www.cs.virginia.edu/~gfx/Courses/2001/Advanced.spring.01/plylib/Ply.txt)
662  if (!init_tmp_file(current_project, keep_tmp_files))
663  {
664  logger.error(
665  "Creation de fichier temporaire impossible. Veuillez verifier l'espace disque disponible.");
667  }
668  try
669  {
670  tympan::save_project(current_project.fileName().toUtf8().data(), _pProjet);
671  }
672  catch (const tympan::invalid_data& exc)
673  {
674  std::ostringstream msg;
675  msg << boost::diagnostic_information(exc);
676  logger.error("Impossible d'exporter le projet courant pour calculer l'altimetrie.");
677  TYNameManager::get()->enable(true);
678  throw;
679  }
680  if (keep_tmp_files)
681  {
682  logger.debug("Le calcul va s'executer en mode debug.\nLes fichiers temporaires ne seront pas "
683  "supprimes une fois le calcul termine.\nProjet courant non calcule: %s",
684  current_project.fileName().toStdString().c_str());
685  }
686 
687  // Call python script "process_site_altimetry.py" with: the name of the file
688  // containing the site description, and the name of the file where to record
689  // the result
690  QStringList args;
691  QString absolute_pyscript_path(QCoreApplication::applicationDirPath());
692  absolute_pyscript_path.append("/");
693  absolute_pyscript_path.append(ALTIMETRY_PYSCRIPT);
694  args << absolute_pyscript_path << current_project.fileName() << resultMeshFilePath;
695 
696  // Altimetry parameters
697  QString parameters = _pProjet->getCurrentCalcul()->solverParams;
698  QRegularExpression altimetry_size_criterion_reg("(MeshElementSizeMax\\s?=\\s?)([0-9]+.[0-9]*)");
699  QRegularExpression altimetry_refine_mesh_reg("(RefineMesh\\s?=\\s?)(True|False)");
700  QRegularExpression altimetry_use_volumes_landtakes_reg("(UseVolumesLandtake\\s?=\\s?)(True|False)");
701  QRegularExpressionMatch match_size = altimetry_size_criterion_reg.match(parameters);
702  QRegularExpressionMatch match_refi = altimetry_refine_mesh_reg.match(parameters);
703  QRegularExpressionMatch match_land = altimetry_use_volumes_landtakes_reg.match(parameters);
704  if (match_size.hasMatch() && match_refi.hasMatch() && match_land.hasMatch())
705  {
706  QString altimetry_size_criterion = match_size.captured(2);
707  QString altimetry_refine_mesh = match_refi.captured(2);
708  QString altimetry_use_volumes_landtakes = match_land.captured(2);
709  args << altimetry_size_criterion << altimetry_refine_mesh << altimetry_use_volumes_landtakes;
710  }
711 
712  logger.info("Lancement d'un sous-processus python pour calculer l'altimetrie avec le script: %s",
713  absolute_pyscript_path.toStdString().c_str());
714  std::string error_msg;
715  if (!python(args, error_msg))
716  {
717  logger.error("Echec du calcul de l'altimetrie: %s", error_msg.c_str());
718  TYNameManager::get()->enable(true);
720  }
721  std::deque<OPoint3D> points;
722  std::deque<OTriangle> triangles;
723  std::deque<LPTYSol> materials;
724  readMesh(points, triangles, materials, resultMeshFilePath);
725  setMeshFilePath(resultMeshFilePath);
726  getAltimetry()->plugBackTriangulation(points, triangles, materials);
727  setIsGeometryModified(false); // L'altimetrie est a jour
729  OMessageManager::get()->info("Mise a jour altimetrie terminee.");
730  TYNameManager::get()->enable(true);
731 }
732 
733 bool TYSiteNode::readMesh(std::deque<OPoint3D>& points, std::deque<OTriangle>& triangles,
734  std::deque<LPTYSol>& materials, const QString& meshFilePath)
735 {
736  // CAUTION: reader uses rply C library which calls strtod (stdlib) to read float
737  // and double values. strtod is locale dependent. It means that if decimal
738  // separator is set to ',' instead of '.' in LC_NUMERIC, float values from
739  // the ply file won't be read. To make sure this doesn't happen, temporarily
740  // set the locale and then put back the original value after file reading.
741  char* saved_locale = setlocale(LC_NUMERIC, "C");
742  FILE* fp = tympan::AltimetryPLYReader::openFileForReading(meshFilePath);
744  if (!fp)
745  {
746  logger.error("Echec d'ouverture du fichier ply : %s", qUtf8Printable(meshFilePath));
747  return false;
748  }
749  logger.debug("Ouverture du fichier ply reussie : %s", qUtf8Printable(meshFilePath));
750  tympan::AltimetryPLYReader reader(fp);
751  reader.read();
752  setlocale(LC_NUMERIC, saved_locale);
753  points = reader.points();
754  triangles = reader.faces();
755  std::deque<std::string> material_ids = reader.materials();
756  uuid2tysol(material_ids, materials);
757  return true;
758 }
759 
760 void TYSiteNode::uuid2tysol(const std::deque<std::string>& material_ids, std::deque<LPTYSol>& materials)
761 {
763  TYSol* ground = nullptr;
764  for (int i = 0; i < material_ids.size(); i++)
765  {
766  ground = dynamic_cast<TYSol*>(TYElement::getInstance(OGenID(QString(material_ids[i].c_str()))));
767  if (ground != NULL)
768  {
769  materials.push_back(ground);
770  }
771  else
772  {
773  logger.debug(
774  "Unknown material retrieved from altimetry mesh: id = %s. Using default material instead",
775  material_ids[i].c_str());
776  materials.push_back(_pTopographie->getDefTerrain()->getSol());
777  }
778  }
779 }
780 
782 {
783  // Collect childs
784  LPTYElementArray childs;
785  LPTYElement currentChild;
786  getChilds(childs, true);
787 
788  // Check site is linked to a project
789  if (!_pProjet)
790  {
791  return;
792  }
793 
794  // Get current computation
795  LPTYCalcul pCurrentCalcul = _pProjet->getCurrentCalcul();
796  if (!pCurrentCalcul)
797  {
798  return;
799  }
800 
801  // Add level curves to current computation
802  TYTabCourbeNiveauGeoNode listCrbNivGeoNode = getTopographie()->getListCrbNiv();
803  for (const LPTYCourbeNiveauGeoNode pCrbNivGeoNode : listCrbNivGeoNode)
804  {
805  TYCourbeNiveau* pCrbNiv = dynamic_cast<TYCourbeNiveau*>(pCrbNivGeoNode->getElement());
806  if (pCrbNiv)
807  {
808  pCurrentCalcul->addToSelection(pCrbNiv);
809  }
810  }
811 
812  // Add water bodies to current computation
813  TYTabPlanEauGeoNode listPlanEauGeoNode = getTopographie()->getListPlanEau();
814  for (const LPTYPlanEauGeoNode pPlanEauGeoNode : listPlanEauGeoNode)
815  {
816  TYPlanEau* pPlanEau = dynamic_cast<TYPlanEau*>(pPlanEauGeoNode->getElement());
817  if (pPlanEau)
818  {
819  pCurrentCalcul->addToSelection(pPlanEau);
820  }
821  }
822 
823  // Recurisive call to select level curve and water bodies for all sub-sites selected in current
824  // computation
825  TYSiteNode* pSiteNode;
826  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
827  {
828  pSiteNode = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
829  if (pCurrentCalcul->isInSelection(pSiteNode))
830  {
831  pSiteNode->selectCourbeNiveauAndPlanEau();
832  }
833  }
834 }
835 
836 // TODO : Split the huge method based on the type of infrastructure
837 // See https://extranet.logilab.fr/ticket/1508248
839 {
840  TYNameManager::get()->enable(false);
841 
842  TYAltimetrie* pAlti = getAltimetry();
843  bool modified = false;
844  OPoint3D pt;
845  unsigned int i = 0, j = 0;
846 
847  bool bNoPbAlti = true;
848 
849  // If the site node isn't a root site, compute its global transform matrix
850  // to look for the altitudes at the right place
851  OMatrix globalMatrix = getGlobalMatrix();
852 
853 #if WITH_NMPB
854  // Mise a jour de l'altitude pour les points des routes
855  for (j = 0; j < _pInfrastructure->getListRoute().size(); j++)
856  {
857  // La route
858  LPTYRouteGeoNode pGeoNode = _pInfrastructure->getListRoute()[j];
859  TYRoute* pRoute = _pInfrastructure->getRoute(j);
860 
861  bNoPbAlti &= pRoute->updateAltitudes(*pAlti, pGeoNode, globalMatrix);
862  modified = true; // As long as there is a road, it will be updated anyways.
863  }
864 #endif
865  // Mise a jour de l'altitude pour les points des reseaux transport
866  for (j = 0; j < _pInfrastructure->getListResTrans().size(); j++)
867  {
869 
870  // Hauteur au sol du reseau de transport
871  double hauteur = pResTrans->getHauteurMoyenne();
872 
873  // Matrice pour la position de cette element
874  OMatrix matrix = globalMatrix * _pInfrastructure->getListResTrans()[j]->getMatrix();
875  OMatrix matrixinv = matrix.getInvert();
876 
877  for (i = 0; i < pResTrans->getTabPoint().size(); i++)
878  {
879  // Passage au repere du site
880  pt = matrix * pResTrans->getTabPoint()[i];
881 
882  // Init
883  pt._z = 0.0;
884 
885  // Recherche de l'altitude
886  bNoPbAlti &= pAlti->updateAltitude(pt);
887 
888  // Ajout de la hauteur du reseau de transport
889  pt._z += hauteur;
890 
891  // Retour au repere d'origine
892  pResTrans->getTabPoint()[i] = matrixinv * pt;
893 
894  modified = true;
895  }
896 
897  pResTrans->setIsGeometryModified(false);
898  }
899 
900  // Mise a jour de l'altitude pour les batiments
901  for (j = 0; j < _pInfrastructure->getListBatiment().size(); j++)
902  {
904  TYBatiment* pBat = TYBatiment::safeDownCast(pBatGeoNode->getElement());
905 
906  // Recuperation de l'origine de l'element
907  pt = globalMatrix * pBatGeoNode->getORepere3D()._origin;
908 
909  // Hauteur par rapport au sol
910  double hauteur = pBatGeoNode->getHauteur();
911 
912  // Init
913  pt._z = 0.0;
914 
915  // Recherche de l'altitude
916  bNoPbAlti &= pAlti->updateAltitude(pt);
917 
918  pBatGeoNode->getORepere3D()._origin._z = pt._z + hauteur;
919 
920  pBat->setIsGeometryModified(false);
921  pBat = NULL;
922  modified = true;
923  }
924 
925  // Mise a jour de l'altitude pour les machines
926  for (j = 0; j < _pInfrastructure->getListMachine().size(); j++)
927  {
928  TYMachineGeoNode* pMachineGeoNode = _pInfrastructure->getListMachine()[j];
929  TYMachine* pMachine = TYMachine::safeDownCast(pMachineGeoNode->getElement());
930 
931  // Recuperation de l'origine de l'element
932  pt = globalMatrix * pMachineGeoNode->getORepere3D()._origin;
933 
934  // Hauteur par rapport au sol
935  double hauteur = pMachineGeoNode->getHauteur();
936 
937  // Init
938  pt._z = 0.0;
939 
940  // Recherche de l'altitude
941  bNoPbAlti &= pAlti->updateAltitude(pt);
942 
943  pMachineGeoNode->getORepere3D()._origin._z = pt._z + hauteur;
944 
945  pMachine->setIsGeometryModified(false);
946  pMachine = NULL;
947  modified = true;
948  }
949 
950  // Mise a jour de l'altitude pour les sources utilisateur
951  for (j = 0; j < _pInfrastructure->getSrcs().size(); j++)
952  {
953  // La source
956 
957  // Matrice pour la position de cette element
958  OMatrix matrix = globalMatrix * _pInfrastructure->getSrcs()[j]->getMatrix();
959  OMatrix matrixinv = matrix.getInvert();
960 
961  // Passage au repere du site
962  pt = matrix * *pSrc->getPos();
963 
964  // Init
965  pt._z = 0.0;
966 
967  // Recherche de l'altitude
968  bNoPbAlti &= pAlti->updateAltitude(pt);
969 
970  // Ajout de la hauteur
971  pt._z += pSrc->getHauteur();
972 
973  // Retour au repere d'origine
974  pt = matrixinv * pt;
975  pSrc->getPos()->_z = pt._z;
976 
977  // On va modifier la route (l'altitude seulement)
978  pSrc->setIsGeometryModified(false);
979 
980  modified = true;
981  }
982 
983  // Mise a jour de l'altitude pour les points des cours d'eau
984  for (j = 0; j < _pTopographie->getListCrsEau().size(); j++)
985  {
986  TYCoursEau* pCrsEau = _pTopographie->getCrsEau(j);
987 
988  // Matrice pour la position de cette element
989  OMatrix matrix = globalMatrix * _pTopographie->getListCrsEau()[j]->getMatrix();
990  OMatrix matrixinv = matrix.getInvert();
991 
992  for (i = 0; i < pCrsEau->getTabPoint().size(); i++)
993  {
994  // Passage au repere du site
995  pt = matrix * pCrsEau->getTabPoint()[i];
996 
997  // Init
998  pt._z = 0.0;
999 
1000  // Recherche de l'altitude
1001  bNoPbAlti &= pAlti->updateAltitude(pt);
1002 
1003  // Retour au repere d'origine
1004  pCrsEau->getTabPoint()[i] = matrixinv * pt;
1005 
1006  modified = true;
1007  }
1008 
1009  pCrsEau->setIsGeometryModified(false);
1010  }
1011 
1012  // Mise a jour de l'altitude pour les points des terrains
1013  for (j = 0; j < _pTopographie->getListTerrain().size(); j++)
1014  {
1015  TYTerrain* pTerrain = _pTopographie->getTerrain(j);
1016 
1017  // Matrice pour la position de cette element
1018  OMatrix matrix = globalMatrix * _pTopographie->getListTerrain()[j]->getMatrix();
1019  OMatrix matrixinv = matrix.getInvert();
1020 
1021  for (i = 0; i < pTerrain->getListPoints().size(); i++)
1022  {
1023  // Passage au repere du site
1024  pt = matrix * pTerrain->getListPoints()[i];
1025 
1026  // Init
1027  pt._z = 0.0;
1028 
1029  // Recherche de l'altitude
1030  bNoPbAlti &= pAlti->updateAltitude(pt);
1031 
1032  // Retour au repere d'origine
1033  pTerrain->getListPoints()[i] = matrixinv * pt;
1034 
1035  modified = true;
1036  }
1037 
1038  pTerrain->setIsGeometryModified(false);
1039  }
1040 
1041  // Warning if an object is not correctly altimetrized
1042  if (!bNoPbAlti)
1043  {
1044  OMessageManager::get()->info(TR("msg_pbalti"));
1045  }
1046 
1047  if (modified)
1048  {
1051  setIsGeometryModified(false);
1052  }
1053 
1054  OMessageManager::get()->info("Mise a jour altimetrie des infrastructures terminee.");
1055 
1056  TYNameManager::get()->enable(true);
1057 }
1058 
1059 void TYSiteNode::updateAcoustique(const bool& force)
1060 {
1061  if (_pProjet)
1062  {
1063  TYCalcul* pCalcul = _pProjet->getCurrentCalcul()._pObj;
1064  assert(pCalcul);
1065  _pInfrastructure->updateAcoustic(pCalcul, force);
1066  }
1067 
1068  for (unsigned short i = 0; i < _listSiteNode.size(); i++)
1069  {
1070  TYSiteNode* pSite = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
1071 
1072  if (pSite && pSite->isInCurrentCalcul())
1073  {
1074  pSite->updateAcoustique(force);
1075  }
1076  }
1077 }
1078 
1080 {
1081  if (_pProjet)
1082  {
1083  return _pProjet->getDelaunayTolerence();
1084  }
1085 
1086  double delaunay(0.0001);
1087 #if TY_USE_IHM
1088  if (TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "DelaunayTolerance"))
1089  {
1090  delaunay = TYPreferenceManager::getDouble(TYDIRPREFERENCEMANAGER, "DelaunayTolerance");
1091  }
1092  else
1093  {
1094  TYPreferenceManager::setDouble(TYDIRPREFERENCEMANAGER, "DelaunayTolerance", delaunay);
1095  }
1096 #endif
1097 
1098  delaunay = delaunay <= 0.0 ? 0.0001 : delaunay;
1099  return delaunay > 0.05 ? 0.05 : delaunay;
1100 }
1101 
1102 // az++ (revoir les faces des ecrans; il vaudrait mieux en ajouter proprement):
1103 // tableau d'index des faces ecrans
1104 // According to ticket https://extranet.logilab.fr/ticket/1459658 the notion
1105 // of ecran is obsolete
1106 // TODO remove cleanly related stuff
1107 std::vector<bool> EstUnIndexDeFaceEcran;
1108 
1109 void TYSiteNode::getListFacesWithoutFloor(TYTabAcousticSurfaceGeoNode& tabFaces, unsigned int& nbFaceInfra,
1110  std::vector<bool>& EstUnIndexDeFaceEcran,
1111  std::vector<std::pair<int, int>>& indices,
1112  std::vector<int>& etages) const
1113 {
1114  std::ofstream file;
1115  file.open("logsChargement.txt", std::ios::out | std::ios::trunc);
1116  file << "Chargement de la liste des faces." << std::endl;
1117 
1118  EstUnIndexDeFaceEcran.clear();
1119 
1120  unsigned int j = 0, i = 0;
1121  int compteurFace = 0;
1122  int compteurInfra = 0;
1124 
1125  tabFaces.clear();
1126 
1127  // Batiments
1128  for (i = 0; i < _pInfrastructure->getListBatiment().size(); i++)
1129  {
1130  file << "Chargement du batiment " << i << std::endl;
1131  // Si ce batiment est actif pour le calcul
1132  LPTYBatiment pBatiment = TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement());
1133 
1134  if (pBatiment && pBatiment->isInCurrentCalcul())
1135  {
1136  tabTmp.clear();
1137 
1138  // Matrice de changement de repere pour ce batiment
1139  OMatrix matrix = _pInfrastructure->getListBatiment()[i]->getMatrix();
1140 
1141  for (j = 0; j < pBatiment->getTabAcousticVol().size(); j++)
1142  {
1143  // Attempt to cast volume to a TYEtage
1144  LPTYEtage pEtage = TYEtage::safeDownCast(pBatiment->getAcousticVol(j));
1145  OMatrix matriceEtage = pBatiment->getTabAcousticVol().at(j)->getMatrix();
1146  if (pEtage)
1147  {
1148  // Récupération des faces des murs
1149  for (unsigned int k = 0; k < pEtage->getTabMur().size(); k++)
1150  {
1151  TYMur* mur = TYMur::safeDownCast(pEtage->getTabMur().at(k)->getElement());
1152  OMatrix matriceMur = pEtage->getTabMur().at(k)->getMatrix();
1153  if (mur)
1154  {
1155  file << "Récupération d'un mur rectangulaire." << std::endl;
1157  mur->getTabAcousticSurf().at(0)->getElement());
1158  if (pRect)
1159  {
1160  // Conversion de la face du mur en AcousticSurfaceGeoNode
1161  file << "Récupération d'un rectangle." << std::endl;
1162  file << "Ajout de la face " << compteurFace << ", etage " << j
1163  << ", batiment " << i << std::endl;
1165  new TYAcousticSurfaceGeoNode(pRect, matriceEtage * matriceMur));
1166  tabTmp.push_back(newNode);
1167  indices.push_back(std::pair<int, int>(compteurFace++, compteurInfra));
1168  etages.push_back(j);
1169  }
1170  }
1171  }
1172 
1173  // Recovery of the upper floor only
1175  LPTYAcousticSurfaceGeoNode newNode =
1176  LPTYAcousticSurfaceGeoNode(new TYAcousticSurfaceGeoNode(poly, matriceEtage));
1177  tabTmp.push_back(newNode);
1178  indices.push_back(std::pair<int, int>(compteurFace++, (int)i));
1179  etages.push_back(j);
1180  }
1181  else
1182  {
1183  // try to cast as a screen (TYEcran)
1184  LPTYEcran pEcran = TYEcran::safeDownCast(pBatiment->getAcousticVol(j));
1185 
1186  if (pEcran)
1187  {
1189  tabTmp2 = pEcran->acousticFaces();
1190  for (unsigned k = 0; k < tabTmp2.size(); k++)
1191  {
1192  tabTmp2[k]->setMatrix(matriceEtage * tabTmp2[k]->getMatrix());
1193  tabTmp.push_back(tabTmp2[k]);
1194  indices.push_back(std::pair<int, int>(compteurFace++, compteurInfra));
1195  etages.push_back(j);
1196  }
1197  }
1198  }
1199  }
1200 
1201  LPTYEtage pEtage = TYEtage::safeDownCast(pBatiment->getAcousticVol(0));
1202  bool bEtageEcran = false;
1203  if (pEtage)
1204  {
1205  bEtageEcran = !pEtage->getClosed();
1206  }
1207  if (bEtageEcran)
1208  {
1209  pEtage->setacousticFacesPourCalcul(true);
1210  }
1211 
1212  // L'ensemble des faces de ce batiment
1213  // tabTmp =
1214  // TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement())->acousticFaces();
1215 
1216  bool bEcran = false; // element de type TYEcran
1217  // Next 3 lines commented, may be invalid (a building can't be a floor)
1218  // if (_pInfrastructure->getBatiment(i)->getElement()->isA("TYEcran"))
1219  //{
1220  // bEcran = true;
1221  //}
1222 
1223  // Pour chacune de ces faces
1224  for (j = 0; j < tabTmp.size(); j++)
1225  {
1226  // On concatene les matrices
1227  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1228 
1229  // Ajout de la face
1230  tabFaces.push_back(tabTmp[j]);
1231  EstUnIndexDeFaceEcran.push_back(bEtageEcran || bEcran);
1232  }
1233  if (bEtageEcran)
1234  {
1235  pEtage->setacousticFacesPourCalcul(false);
1236  }
1237  }
1238 
1239  compteurInfra++;
1240  }
1241 
1242  // Machines
1243  for (i = 0; i < _pInfrastructure->getListMachine().size(); i++)
1244  {
1245  // Si cette machine est active pour le calcul
1247  if (pMachine && pMachine->isInCurrentCalcul())
1248  {
1249  tabTmp.clear();
1250 
1251  // Matrice de changement de repere pour cette machine
1252  OMatrix matrix = _pInfrastructure->getListMachine()[i]->getMatrix();
1253 
1254  // L'ensemble des faces de cette machine
1255  tabTmp = TYMachine::safeDownCast(_pInfrastructure->getMachine(i)->getElement())->acousticFaces();
1256 
1257  // Pour chacune de ces faces
1258  for (j = 0; j < tabTmp.size(); j++)
1259  {
1260  // On concatene les matrices
1261  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1262 
1263  // Ajout de la face
1264  tabFaces.push_back(tabTmp[j]);
1265  indices.push_back(std::pair<int, int>(compteurFace++, compteurInfra));
1266  EstUnIndexDeFaceEcran.push_back(false);
1267  etages.push_back(0);
1268  }
1269  }
1270  compteurInfra++;
1271  }
1272 
1273  nbFaceInfra =
1274  static_cast<uint32>(tabFaces.size()); // Determination du nombre de faces de l'infrastructure;
1275 
1276  // Les faces de la topographie (altimetrie) sont transformee en faces acoustiques
1277  // avec des proprietes acoustiques nulles
1278  // EstUnIndexDeFaceEcran n'est pas a affecter, car les faces d'infrastructures sont separees de celles de
1279  // l'alti, donc sachant ou commence les faces d'alti, le test "est un ecran" n'a pas de sens pour ces
1280  // dernieres
1281 
1282  // WIP here : the materials {c/sh}ould be stored in the TYAcousticPolygon
1283  // and thus be stored or exracted from the Altimetry ?
1284  // or is this data pulling from the solver to be replaced by data
1285  // pushing from the site to the model
1286  LPTYAltimetrie pAlti = getAltimetry();
1287  TYTabLPPolygon& listFacesAlti = pAlti->getListFaces();
1288  unsigned int nbFacesAlti = static_cast<uint32>(listFacesAlti.size());
1289 
1290  for (i = 0; i < nbFacesAlti; i++)
1291  {
1292  LPTYAcousticPolygon pAccPolygon = new TYAcousticPolygon();
1293  pAccPolygon->setParent(pAlti);
1294 
1295  // Geomtrie
1296  *pAccPolygon->getPolygon() = *listFacesAlti.at(i);
1297 
1298  // Ajout
1300  tabFaces.push_back(pNode);
1301  indices.push_back(std::pair<int, int>(compteurFace++, -1));
1302  etages.push_back(-1);
1303  }
1304 
1305  file.close();
1306 }
1307 
1309 {
1310  // As there is one only altimetry for all the subsites of the root site,
1311  // retrieve the altimetry from the root site and not from the current site.
1312  TYSiteNode const* rootsite = this;
1313  while (rootsite != nullptr && !rootsite->getRoot())
1314  {
1315  rootsite = dynamic_cast<TYSiteNode*>(rootsite->getParent());
1316  }
1317  if (rootsite != nullptr)
1318  return rootsite->getTopographie()->getAltimetrie();
1319  throw tympan::invalid_data("No root site node in current TYMPAN objects hierarchy.");
1320 }
1321 
1323 {
1324  if (getRoot())
1325  {
1326  return OMatrix(); // identity matrix at the root site
1327  }
1328  TYSiteNode const* parentsite = dynamic_cast<TYSiteNode*>(getParent());
1329  if (parentsite == nullptr)
1330  {
1331  return OMatrix();
1332  // should throw an exception
1333  }
1334 
1335  for (int i = 0; i < parentsite->_listSiteNode.size(); i++)
1336  {
1337  TYSiteNode const* subsite = dynamic_cast<TYSiteNode*>(parentsite->_listSiteNode[i]->getElement());
1338  if (subsite->getID() == getID())
1339  {
1340  return parentsite->getGlobalMatrix() * parentsite->_listSiteNode[i]->getMatrix();
1341  }
1342  }
1343  return OMatrix(); // this should not happen
1344 }
1345 
1346 bool almost_equal(double a, double b, double precision)
1347 {
1348  return abs(a - b) < abs(precision);
1349 }
1350 
1351 void TYSiteNode::groundBasedFaces(const TYTabAcousticVolumeGeoNode& volumes, const OMatrix& global_matrix,
1352  std::map<TYUUID, std::deque<TYTabPoint3D>>& contours) const
1353 {
1354  // Go through all the faces of the all the input volumes
1355  for (unsigned int i = 0; i < volumes.size(); i++)
1356  {
1357  OMatrix matrix = volumes[i]->getMatrix();
1358  matrix = global_matrix * matrix;
1359  TYAcousticVolume* volume = dynamic_cast<TYAcousticVolume*>(volumes[i]->getElement());
1360  assert(volume != nullptr &&
1361  "found an object which isn't a TYAcousticVolume in a TYTabAcousticVolumeGeoNode");
1362  TYTabAcousticSurfaceGeoNode faces = volume->acousticFaces();
1363  TYTabPoint3D contour;
1364  double tol = 10e-6;
1365  for (unsigned int j = 0; j < faces.size(); j++)
1366  {
1367  // Compute global matrix for the current face (do NOT modify the object)
1368  OMatrix face_matrix = matrix * faces[j]->getMatrix();
1369  TYAcousticSurface* pFace = dynamic_cast<TYAcousticSurface*>(faces[j]->getElement());
1370 
1371  // Take the contour of the acoustic face, move the points to a global scale
1372  // and make a polygon with them
1373  contour = pFace->getOContour();
1374  TYPolygon poly;
1375  for (unsigned int k = 0; k < contour.size(); k++)
1376  {
1377  contour[k] = face_matrix * contour[k];
1378  poly.getPoints().push_back(TYPoint(contour[k]));
1379  }
1380  // Compute polygon' normal
1381  poly.updateNormal();
1382  OVector3D normal = poly.normal();
1383  // We are looking for the floor-based face of the volumes. We keep the
1384  // current face if it is parallel to the ground
1385  if (!almost_equal(abs(normal.scalar(OVector3D(0., 0., 1.))), 1., tol))
1386  continue;
1387  // only keep the face if it is on or below the ground
1388  if (contour[0]._z < tol)
1389  {
1390  contours[volume->getID()].push_back(contour);
1391  }
1392  }
1393  }
1394 }
1395 
1396 void TYSiteNode::getFacesOnGround(std::map<TYUUID, std::deque<TYTabPoint3D>>& contours) const
1397 {
1398  assert(contours.empty() &&
1399  "Output argument 'contours' is supposed to be empty when calling 'TYSiteNode::getFacesOnGround'");
1400  // Buildings
1401  for (unsigned int i = 0; i < _pInfrastructure->getListBatiment().size(); i++)
1402  {
1403  // We get the geonode information : position and height of the building
1405  // If the building is not supposed to touch the ground, there is no need to get its contour
1406  if (gBatiment->getHauteur() != 0)
1407  {
1408  continue;
1409  }
1410  // If it does touch the ground, we force z=0 for the computation only,
1411  // without modifying the model (no setPosition side effects).
1412  else
1413  {
1414  LPTYBatiment pBuilding = dynamic_cast<TYBatiment*>(gBatiment->getElement());
1415  assert(pBuilding != nullptr &&
1416  "found an object which is not a TYBatiment in _pInfrastructure->getListBatiment()");
1417  // If this building is active in the current simulation
1418  if (pBuilding->isInCurrentCalcul())
1419  {
1420  // Building transform matrix
1421  OMatrix matrix = _pInfrastructure->getBatiment(i)->getMatrix();
1422  matrix._m[2][3] = 0.0; // Force Z translation to 0 for computation only
1423 
1424  TYTabAcousticVolumeGeoNode& building_volumes = pBuilding->getTabAcousticVol();
1425  // 1 TYTabPoint3D per volume face on the ground. Indeed there may be several,
1426  // since buildings and machines are volume nodes wghich means they
1427  // are made of one or more volumes.
1428  std::deque<TYTabPoint3D> base_faces;
1429  // Get the base of the building
1430  groundBasedFaces(building_volumes, matrix, contours);
1431  }
1432  }
1433  }
1434  // Machines
1435  for (int i = 0; i < _pInfrastructure->getListMachine().size(); i++)
1436  {
1437  // We get the geonode information : position and height of the building
1439  // If the machine is not supposed to touch the ground, there is no need to get its contour
1440  if (gMachine->getHauteur() != 0)
1441  {
1442  continue;
1443  }
1444  // If it does touch the ground, we force z=0 for the computation only,
1445  // without modifying the model (no setPosition side effects).
1446  else
1447  {
1448  // Si cette machine est active pour le calcul
1449  LPTYMachine pMachine = dynamic_cast<TYMachine*>(gMachine->getElement());
1450  assert(pMachine != nullptr &&
1451  "found an object which is not a TYMachine in _pInfrastructure->getListMachine()");
1452  if (pMachine->isInCurrentCalcul())
1453  {
1454  // Matrice de changement de repere pour cette machine
1455  OMatrix matrix = _pInfrastructure->getMachine(i)->getMatrix();
1456  matrix._m[2][3] = 0.0; // Force Z translation to 0 for computation only
1457 
1458  TYTabAcousticVolumeGeoNode machine_volumes = pMachine->getTabAcousticVol();
1459  std::deque<TYTabPoint3D> base_faces;
1460  // Get the base of the machine
1461  groundBasedFaces(machine_volumes, matrix, contours);
1462  }
1463  }
1464  }
1465 }
1466 
1467 void TYSiteNode::getListFaces(TYTabAcousticSurfaceGeoNode& tabFaces, unsigned int& nbFaceInfra,
1468  std::vector<bool>& EstUnIndexDeFaceEcran) const
1469 {
1470  EstUnIndexDeFaceEcran.clear();
1471 
1472  unsigned int j = 0, i = 0;
1474 
1475  tabFaces.clear();
1476 
1477  // Batiments
1478  for (i = 0; i < _pInfrastructure->getListBatiment().size(); i++)
1479  {
1480  // Si ce batiment est actif pour le calcul
1481  LPTYBatiment pBatiment = TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement());
1482  if (pBatiment && pBatiment->isInCurrentCalcul())
1483  {
1484  tabTmp.clear();
1485 
1486  // Matrice de changement de repere pour ce batiment
1487  OMatrix matrix = _pInfrastructure->getListBatiment()[i]->getMatrix();
1488 
1489  // LPTYBatiment pBatiment =
1490  // TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement());
1491  LPTYEtage pEtage = TYEtage::safeDownCast(pBatiment->getAcousticVol(0));
1492 
1493  // Old Code_TYMPAN version could use a floor as a screen so, that case should be treated
1494  bool bEtageEcran = false;
1495  if (pEtage)
1496  {
1497  bEtageEcran = !pEtage->getClosed();
1498  }
1499  if (bEtageEcran)
1500  {
1501  pEtage->setacousticFacesPourCalcul(true);
1502  }
1503 
1504  // L'ensemble des faces de ce batiment
1505  tabTmp = pBatiment->acousticFaces();
1506 
1507  // Pour chacune de ces faces
1508  for (j = 0; j < tabTmp.size(); j++)
1509  {
1510  // On concatene les matrices
1511  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1512 
1513  // Ajout de la face
1514  tabFaces.push_back(tabTmp[j]);
1515  EstUnIndexDeFaceEcran.push_back(bEtageEcran);
1516  }
1517  if (bEtageEcran)
1518  {
1519  pEtage->setacousticFacesPourCalcul(false);
1520  }
1521  }
1522  }
1523 
1524  // Machines
1525  for (i = 0; i < _pInfrastructure->getListMachine().size(); i++)
1526  {
1527  // Si cette machine est active pour le calcul
1529  if (pMachine && pMachine->isInCurrentCalcul())
1530  {
1531  tabTmp.clear();
1532 
1533  // Matrice de changement de repere pour cette machine
1534  OMatrix matrix = _pInfrastructure->getListMachine()[i]->getMatrix();
1535 
1536  // L'ensemble des faces de cette machine
1537  tabTmp = TYMachine::safeDownCast(_pInfrastructure->getMachine(i)->getElement())->acousticFaces();
1538 
1539  // Pour chacune de ces faces
1540  for (j = 0; j < tabTmp.size(); j++)
1541  {
1542  // On concatene les matrices
1543  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1544 
1545  // Ajout de la face
1546  tabFaces.push_back(tabTmp[j]);
1547  EstUnIndexDeFaceEcran.push_back(false);
1548  }
1549  }
1550  }
1551 
1552  nbFaceInfra =
1553  static_cast<uint32>(tabFaces.size()); // Determination du nombre de faces de l'infrastructure;
1554 
1555  // Les faces de la topographie (altimetrie) sont transformee en faces acoustiques
1556  // avec des proprietes acoustiques nulles
1557  // EstUnIndexDeFaceEcran n'est pas a affecter, car les faces d'infrastructures sont separees de celles de
1558  // l'alti, donc sachant ou commence les faces d'alti, le test "est un ecran" n'a pas de sens pour ces
1559  // dernieres
1560 
1561  TYTabLPPolygon& listFacesAlti = getAltimetry()->getListFaces();
1562  unsigned int nbFacesAlti = static_cast<uint32>(listFacesAlti.size());
1563 
1564  for (i = 0; i < nbFacesAlti; i++)
1565  {
1566  LPTYAcousticPolygon pAccPolygon = new TYAcousticPolygon();
1567  pAccPolygon->setParent(getAltimetry());
1568 
1569  // Geomtrie
1570  *pAccPolygon->getPolygon() = *listFacesAlti.at(i);
1571 
1572  // Ajout
1574  tabFaces.push_back(pNode);
1575  }
1576 }
1577 
1579 {
1580  TYTabSiteNodeGeoNode& tabGeoNode = getListSiteNode();
1581  TYSiteNode* pSite = NULL;
1582 
1583  for (unsigned int i = 0; i < tabGeoNode.size(); i++)
1584  {
1585  pSite = TYSiteNode::safeDownCast(tabGeoNode[i]->getElement());
1586  pSite->setInCurrentCalcul(false, true, false);
1587  }
1588 }
1589 
1590 TYTabSiteNodeGeoNode TYSiteNode::collectSites(bool include /*=true*/) const
1591 {
1592  TYTabSiteNodeGeoNode sites;
1593 
1594  if (include)
1595  {
1596  sites.push_back(new TYSiteNodeGeoNode((TYSiteNode*)this));
1597  }
1598 
1599  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
1600  {
1601  // On inclut forcement les sites sinon sans interet
1602  TYSiteNode* pSite = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
1603  if (pSite && pSite->isInCurrentCalcul()) // Uniquement si le sous-site est dans le calcul
1604  {
1605  TYTabSiteNodeGeoNode tabChild = pSite->collectSites(true);
1606 
1607  // Concatenation des matrices
1608  OMatrix matrix = _listSiteNode[i]->getMatrix();
1609  for (unsigned int j = 0; j < tabChild.size(); j++)
1610  {
1611  tabChild[j]->setMatrix(matrix * tabChild[j]->getMatrix());
1612  }
1613 
1614  //...et ajoute au tableau a retourner
1615  sites.insert(sites.end(), tabChild.begin(), tabChild.end());
1616  }
1617  }
1618 
1619  return sites;
1620 }
1621 
1623 {
1624  bool ret = false;
1625 
1626  TYSourcePonctuelle* pSource = dynamic_cast<TYSourcePonctuelle*>(pElem);
1627  if (pSource != nullptr)
1628  {
1629  return true; // Pas de mise à jour nécessaire
1630  }
1631  TYAcousticLine* pLine = dynamic_cast<TYAcousticLine*>(pElem);
1632  if (pLine != nullptr) // Cas 1 : un objet de type source linéique
1633  {
1634  pLine->updateAcoustic(true);
1635  }
1636  else // Autres cas, recherche de parent et traitement approprié
1637  {
1638  TYElement* pParent = pElem; // On commencera par tester l'objet lui-meme
1639  do
1640  {
1641  TYAcousticVolumeNode* pVolNode = dynamic_cast<TYAcousticVolumeNode*>(pParent);
1642  if (pVolNode != nullptr)
1643  {
1644  ret = pVolNode->updateAcoustic(true);
1645  break; // On a trouvé, on peut sortir
1646  }
1647  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(pParent);
1648  if (pSite != nullptr)
1649  {
1650  pSite->updateAcoustique();
1651  ret = true;
1652  break; // On a trouvé, on peut sortir
1653  }
1654 
1655  pParent = pParent->getParent();
1656  } while (pParent);
1657  }
1658 
1659  return ret;
1660 }
1661 
1662 void TYSiteNode::update(const bool& force) // Force = false
1663 {
1664  // Altimetrisation des infrastructures du site
1665  updateAltiInfra();
1666 
1667  // Mise a jour de l'acoustique des elements du site
1668  updateAcoustique(force);
1669 
1670  // Et celle des sites inclus
1671  for (unsigned short i = 0; i < _listSiteNode.size(); i++)
1672  {
1673  TYSiteNode* pSite = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
1674 
1675  if (pSite && pSite->isInCurrentCalcul())
1676  {
1677  pSite->update(force);
1678  }
1679  }
1680 
1681  // Si le site est dans un projet, on altimétrise les points de controle
1682  if (_pProjet && getRoot())
1683  {
1685  }
1686 }
1687 
1689 {
1690  assert(pSiteNodeGeoNode);
1691 
1692  LPTYSiteNode pSite = TYSiteNode::safeDownCast(pSiteNodeGeoNode->getElement());
1693 
1694  assert(pSite);
1695 
1696  pSiteNodeGeoNode->setParent(this);
1697  pSite->setParent(this);
1698  pSite->setProjet(_pProjet); // Informe du projet cadre
1699 
1700  _listSiteNode.push_back(pSiteNodeGeoNode);
1701  getAltimetry()->setIsUpToDate(false); // Invalide l'altimétrie lors de l'ajout d'un sous-site
1702 
1703 #if TY_USE_IHM
1704  pSite->updateGraphicTree();
1705 #endif
1706  setIsGeometryModified(true);
1707 
1708  return true;
1709 }
1710 
1712 {
1713  return addSiteNode(new TYSiteNodeGeoNode((LPTYElement)pSiteNode));
1714 }
1715 
1716 bool TYSiteNode::remSiteNode(const LPTYSiteNodeGeoNode pSiteNodeGeoNode)
1717 {
1718  assert(pSiteNodeGeoNode);
1719  bool ret = false;
1720  TYTabSiteNodeGeoNode::iterator ite;
1721 
1722  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1723  {
1724  if ((*ite) == pSiteNodeGeoNode)
1725  {
1726  // Suppression des calcul
1727  if (_pProjet)
1728  {
1729  _pProjet->remElmtFromCalculs((*ite)->getElement());
1730  }
1731 
1732  _listSiteNode.erase(ite);
1733  ret = true;
1734  break;
1735  }
1736  }
1737 
1738  setIsGeometryModified(true);
1739 
1740  return ret;
1741 }
1742 
1744 {
1745  assert(pSiteNode);
1746  bool ret = false;
1747  TYTabSiteNodeGeoNode::iterator ite;
1748 
1749  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1750  {
1751  if (TYSiteNode::safeDownCast((*ite)->getElement()) == pSiteNode)
1752  {
1753  // Suppression des calcul
1754  if (_pProjet)
1755  {
1756  _pProjet->remElmtFromCalculs((*ite)->getElement());
1757  }
1758 
1759  _listSiteNode.erase(ite);
1760  ret = true;
1761  break;
1762  }
1763  }
1764 
1765  setIsGeometryModified(true);
1766 
1767  return ret;
1768 }
1769 
1770 bool TYSiteNode::remSiteNode(QString idSiteNode)
1771 {
1772  bool ret = false;
1773  TYTabSiteNodeGeoNode::iterator ite;
1774 
1775  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1776  {
1777  if (TYSiteNode::safeDownCast((*ite)->getElement())->getID().toString() == idSiteNode)
1778  {
1779  // Suppression des calcul
1780  if (_pProjet)
1781  {
1782  _pProjet->remElmtFromCalculs((*ite)->getElement());
1783  }
1784 
1785  _listSiteNode.erase(ite);
1786  ret = true;
1787  break;
1788  }
1789  }
1790 
1791  setIsGeometryModified(true);
1792 
1793  return ret;
1794 }
1795 
1797 {
1798  assert(pSiteNode);
1799  TYTabSiteNodeGeoNode::iterator ite;
1800 
1801  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1802  {
1803  if (TYSiteNode::safeDownCast((*ite)->getElement()) == pSiteNode)
1804  {
1805  return (*ite);
1806  }
1807  }
1808 
1809  return NULL;
1810 }
1811 
1813 {
1814  LPTYSiteNode pSite = new TYSiteNode();
1815  pSite->getTopographie()
1816  ->getListTerrain()
1817  .clear(); // On vide car un terrain par defaut a ete cree dans le site cible
1818 
1819  unsigned int j = 0;
1820 
1821  // On copie les elements de ce site
1822  appendSite(this, OMatrix(), pSite);
1823  pSite->getTopographie()->setDefTerrainIdx(getTopographie()->getDefTerrainIdx());
1824  pSite->setEmprise(getTopographie()->getEmprise());
1825  pSite->getTopographie()->setDefTerrain(getTopographie()->getDefTerrainIdx());
1826 
1827  // Merge des sites enfants
1828  for (j = 0; j < _listSiteNode.size(); j++)
1829  {
1830  // Site enfant courant
1831  LPTYSiteNodeGeoNode pSiteNodeGeoNode = _listSiteNode[j];
1832 
1833  // Appel recursif
1834  TYSiteNode* pSiteChild = TYSiteNode::safeDownCast(pSiteNodeGeoNode->getElement());
1835  assert(pSiteChild);
1836  if (pSiteChild && !(pSiteChild->isInCurrentCalcul()))
1837  {
1838  continue;
1839  }
1840 
1841  LPTYSiteNode pSiteTmp = pSiteChild->merge();
1842 
1843  // On copie les elements du site enfant en prenant compte le changement de repere
1844  appendSite(pSiteTmp, pSiteNodeGeoNode->getMatrix(), pSite);
1845  }
1846 
1848  pSite->setProjet(_pProjet);
1849 
1850  return pSite;
1851 }
1852 
1853 void TYSiteNode::appendSite(LPTYSiteNode pSiteFrom, const OMatrix& matrix, LPTYSiteNode pSiteTo)
1854 {
1855  assert(pSiteFrom);
1856  assert(pSiteTo);
1857  unsigned int i = 0;
1858  OMatrix newMatrix;
1859 
1860  // Ajout des elements de topo
1861  LPTYTopographie pTopoFrom = pSiteFrom->getTopographie();
1862  LPTYTopographie pTopoTo = pSiteTo->getTopographie();
1863 
1864  // TODO BUG #0008309 : Courbe de niveau pas prise en compte dans l'altimétrie
1865  if (pSiteFrom->getUseEmpriseAsCrbNiv())
1866  {
1867  pTopoTo->addCrbNiv(new TYCourbeNiveau(pTopoFrom->getEmprise(), pSiteFrom->getAltiEmprise()));
1868  }
1869  // This scope is here to make p_ground local
1870  {
1871  // Add the 'emprise' as a Terrain with its defaultTErrain as Sol attribute.
1872  TYTerrain* p_ground = new TYTerrain();
1873  p_ground->setSol(pTopoFrom->getDefTerrain()->getSol());
1874  p_ground->setListPoints(pTopoFrom->getEmprise());
1875  pTopoTo->addTerrain(new TYTerrainGeoNode(p_ground, matrix));
1876  }
1877  for (i = 0; i < pTopoFrom->getListCrbNiv().size(); i++)
1878  {
1879  newMatrix = matrix * pTopoFrom->getListCrbNiv()[i]->getMatrix();
1880  pTopoTo->addCrbNiv(new TYCourbeNiveauGeoNode(pTopoFrom->getListCrbNiv()[i]->getElement(), newMatrix));
1881  }
1882 
1883  for (i = 0; i < pTopoFrom->getListTerrain().size(); i++)
1884  {
1885  newMatrix = matrix * pTopoFrom->getListTerrain()[i]->getMatrix();
1886  pTopoTo->addTerrain(new TYTerrainGeoNode(pTopoFrom->getListTerrain()[i]->getElement(), newMatrix));
1887  }
1888 
1889  for (i = 0; i < pTopoFrom->getListCrsEau().size(); i++)
1890  {
1891  newMatrix = matrix * pTopoFrom->getListCrsEau()[i]->getMatrix();
1892  pTopoTo->addCrsEau(new TYCoursEauGeoNode(pTopoFrom->getListCrsEau()[i]->getElement(), newMatrix));
1893  }
1894 
1895  for (i = 0; i < pTopoFrom->getListPlanEau().size(); i++)
1896  {
1897  newMatrix = matrix * pTopoFrom->getListPlanEau()[i]->getMatrix();
1898  pTopoTo->addPlanEau(new TYPlanEauGeoNode(pTopoFrom->getListPlanEau()[i]->getElement(), newMatrix));
1899  }
1900 
1901  // Ajout des elements d'infra
1902  LPTYInfrastructure pInfraFrom = pSiteFrom->getInfrastructure();
1903  LPTYInfrastructure pInfraTo = pSiteTo->getInfrastructure();
1904 
1905 #if WITH_NMPB
1906  for (i = 0; i < pInfraFrom->getListRoute().size(); i++)
1907  {
1908  newMatrix = matrix * pInfraFrom->getListRoute()[i]->getMatrix();
1909  pInfraTo->addRoute(new TYRouteGeoNode(pInfraFrom->getListRoute()[i]->getElement(), newMatrix));
1910  }
1911 #endif
1912  for (i = 0; i < pInfraFrom->getListResTrans().size(); i++)
1913  {
1914  newMatrix = matrix * pInfraFrom->getListResTrans()[i]->getMatrix();
1915  pInfraTo->addResTrans(
1916  new TYReseauTransportGeoNode(pInfraFrom->getListResTrans()[i]->getElement(), newMatrix));
1917  }
1918 
1919  for (i = 0; i < pInfraFrom->getListBatiment().size(); i++)
1920  {
1921  newMatrix = matrix * pInfraFrom->getListBatiment()[i]->getMatrix();
1922  TYBatimentGeoNode* pBatNode =
1923  new TYBatimentGeoNode(pInfraFrom->getListBatiment()[i]->getElement(), newMatrix);
1924  pBatNode->setHauteur(pInfraFrom->getListBatiment()[i]->getHauteur());
1925  pInfraTo->addBatiment(pBatNode);
1926  }
1927 
1928  for (i = 0; i < pInfraFrom->getListMachine().size(); i++)
1929  {
1930  newMatrix = matrix * pInfraFrom->getListMachine()[i]->getMatrix();
1931  TYMachineGeoNode* pMachineNode =
1932  new TYMachineGeoNode(pInfraFrom->getListMachine()[i]->getElement(), newMatrix);
1933  pMachineNode->setHauteur(pInfraFrom->getListMachine()[i]->getHauteur());
1934  pInfraTo->addMachine(pMachineNode);
1935  }
1936 
1937  for (i = 0; i < pInfraFrom->getSrcs().size(); i++)
1938  {
1939  newMatrix = matrix * pInfraFrom->getSrcs()[i]->getMatrix();
1940  pInfraTo->addSrc(new TYSourcePonctuelleGeoNode(pInfraFrom->getSrcs()[i]->getElement(), newMatrix));
1941  }
1942 }
1943 
1944 void TYSiteNode::exportCSV(std::ofstream& ofs)
1945 {
1946  // Export du nom de l'objet
1947  ofs << getName().toLatin1().data() << '\n';
1948 
1949  // Export du type de l'objet
1950  ofs << toString() << '\n';
1951  // Export des donnees acoustiques
1952  LPTYElementArray childs;
1953  getChilds(childs);
1954 
1955  for (int i = 0; i < childs.size(); i++)
1956  {
1957  TYElement* pElement = childs[i];
1958  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(pElement);
1959  if (pSite != nullptr)
1960  {
1961  // Export du nom de l'objet
1962  ofs << pElement->getName().toLatin1().data() << '\n';
1963  continue;
1964  }
1965  LPTYAcousticVolumeNode pVolNode = dynamic_cast<TYAcousticVolumeNode*>(pElement);
1966  if (pVolNode != nullptr)
1967  {
1968  pVolNode->exportCSV(ofs);
1969  continue;
1970  }
1971  LPTYAcousticLine pAcLine = dynamic_cast<TYAcousticLine*>(pElement);
1972  if (pAcLine != nullptr)
1973  {
1974  pAcLine->exportCSV(ofs);
1975  continue;
1976  }
1977  LPTYUserSourcePonctuelle pSource = dynamic_cast<TYUserSourcePonctuelle*>(pElement);
1978  if (pSource != nullptr)
1979  {
1980  pSource->exportCSV(ofs);
1981  }
1982  }
1983 
1984  ofs << '\n';
1985 }
QDomElement DOM_Element
Definition: QT2DOM.h:30
std::vector< LPTYAcousticFaceSetGeoNode > TYTabAcousticVolumeGeoNode
Collection de noeuds geometriques de type TYAcousticFaceSet.
TYGeometryNode TYAcousticSurfaceGeoNode
Noeud geometrique de type TYAcousticSurface.
std::vector< LPTYAcousticSurfaceGeoNode > TYTabAcousticSurfaceGeoNode
Collection de noeuds geometriques de type TYAcousticSurface.
SmartPtr< TYAcousticSurfaceGeoNode > LPTYAcousticSurfaceGeoNode
Smart Pointer sur TYAcousticSurfaceGeoNode.
TYGeometryNode TYBatimentGeoNode
Noeud geometrique de type TYBatiment.
Definition: TYBatiment.h:90
std::vector< LPTYCourbeNiveauGeoNode > TYTabCourbeNiveauGeoNode
Collection de noeuds geometriques de type TYCourbeNiveau.
TYGeometryNode TYCourbeNiveauGeoNode
Noeud geometrique de type TYCourbeNiveau.
TYGeometryNode TYCoursEauGeoNode
Noeud geometrique de type TYCoursEau.
Definition: TYCoursEau.h:66
class OGenID TYUUID
Definition: TYDefines.h:59
std::deque< OPoint3D > TYTabPoint3D
Collection de OPoint3D.
Definition: TYDefines.h:403
std::vector< LPTYPolygon > TYTabLPPolygon
Collection de pointeurs de TYPolygon.
Definition: TYDefines.h:349
std::list< TYUUID > TYListID
Collection d'identifiants.
Definition: TYDefines.h:331
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:344
#define TYDIRPREFERENCEMANAGER
Definition: TYElement.h:51
TYGeometryNode TYMachineGeoNode
Noeud geometrique de type TYMachine.
Definition: TYMachine.h:164
TYGeometryNode TYPlanEauGeoNode
Noeud geometrique de type TYPlanEau.
Definition: TYPlanEau.h:198
std::vector< LPTYPlanEauGeoNode > TYTabPlanEauGeoNode
Collection de noeuds geometriques de type TYPlanEau.
Definition: TYPlanEau.h:202
TYGeometryNode TYReseauTransportGeoNode
Noeud geometrique de type TYReseauTransport.
TYGeometryNode TYRouteGeoNode
Geometrical node of type TYRoute.
Definition: TYRoute.h:33
Representation graphique d'un ensemble de sites (fichier header)
outil IHM pour un ensemble de sites (fichier header)
std::vector< bool > EstUnIndexDeFaceEcran
bool almost_equal(double a, double b, double precision)
TY_EXTENSION_INST(TYSiteNode)
TY_EXT_GRAPHIC_INST(TYSiteNode)
#define TR(id)
Definition: TYSiteNode.cpp:39
systemSIG
Systeme SIG.
Definition: TYSiteNode.h:29
@ TYMPAN
Definition: TYSiteNode.h:30
TYGeometryNode TYSiteNodeGeoNode
Noeud geometrique de type TYSiteNode.
Definition: TYSiteNode.h:36
std::vector< LPTYSiteNodeGeoNode > TYTabSiteNodeGeoNode
Collection de noeuds geometriques de type TYSiteNode.
Definition: TYSiteNode.h:40
TYGeometryNode TYSourcePonctuelleGeoNode
Noeud geometrique de type TYSourcePonctuelle.
TYGeometryNode TYTerrainGeoNode
Noeud geometrique de type TYTerrain.
Definition: TYTerrain.h:177
Implementation details header for altimetry_reader.cpp.
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
Definition: idgen.h:28
The 4x4 matrix class.
Definition: 3d.h:625
OMatrix getInvert(int *ok=0) const
Return the inverse matrix of this matrix.
Definition: 3d.cpp:813
double _m[4][4]
The 4x4 matrix array.
Definition: 3d.h:974
virtual void debug(const char *message,...)
Definition: logging.cpp:151
virtual void error(const char *message,...)
Definition: logging.cpp:127
static OMessageManager * get()
Definition: logging.cpp:108
virtual void info(const char *message,...)
Definition: logging.cpp:143
The 3D point class.
Definition: 3d.h:487
virtual const char * getClassName() const
Definition: TYElement.h:248
static OPrototype * safeDownCast(OPrototype *pObject)
Definition: TYElement.cpp:71
OPoint3D _origin
The origin point.
Definition: 3d.h:1331
The 3D vector class.
Definition: 3d.h:298
double scalar(const OVector3D &vector) const
Performs the scalar product between this object and another vector.
Definition: 3d.cpp:210
T * _pObj
The real pointer, must derived IRefCount.
Definition: smartptr.h:307
TYTabPoint & getTabPoint()
virtual bool updateAcoustic(const bool &force=false)
TYTabAcousticSurfaceGeoNode & getTabAcousticSurf()
virtual TYTabPoint3D getOContour(int n=-1) const
virtual TYTabAcousticSurfaceGeoNode acousticFaces()
virtual void exportCSV(std::ofstream &ofs)
Export au format csv sur un flux transmis.
virtual bool updateAcoustic(const bool &force=false)
LPTYAcousticVolume getAcousticVol(int index)
TYTabAcousticVolumeGeoNode & getTabAcousticVol()
virtual TYTabAcousticSurfaceGeoNode acousticFaces()
Assigne une altitude a chaque point de l'espace.
Definition: TYAltimetrie.h:35
bool updateAltitude(OPoint3D &pt) const
Modifie l'altitude d'un point donn�. Si le point est hors de la zone dans laquelle l'altim�trie e...
void plugBackTriangulation(const std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const std::deque< LPTYSol > &materials)
plug back triangulation providfed by the TYTopographie
void setIsUpToDate(bool isUpToDate)
TYTabLPPolygon & getListFaces()
Definition: TYAltimetrie.h:124
Calculation program.
Definition: TYCalcul.h:50
QString solverParams
Definition: TYCalcul.h:482
bool isInSelection(TYUUID id)
Tests if the element is present in the selection of this Calculation.
Definition: TYCalcul.cpp:1004
bool addToSelection(TYUUID id)
Adds the item to the selection of this Calculation.
Definition: TYCalcul.cpp:873
TYElement * getParent() const
Definition: TYElement.h:706
virtual bool isInCurrentCalcul()
Definition: TYElement.h:539
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:305
static void setIsSavedOk(const bool &toSave)
Definition: TYElement.h:914
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:366
QString _name
Nom courant de l'element.
Definition: TYElement.h:965
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:263
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:542
const TYUUID & getID() const
Definition: TYElement.cpp:176
virtual QString getName() const
Definition: TYElement.h:691
TYElement * _pParent
Reference sur l'element parent.
Definition: TYElement.h:968
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYElement.cpp:458
virtual void setInCurrentCalcul(bool state, bool recurschild=true, bool recursparent=true)
Definition: TYElement.cpp:408
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:530
void setParent(TYElement *pParent)
Definition: TYElement.h:699
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:379
QString getStringID() const
Definition: TYElement.h:660
static TYElement * getInstance(TYUUID uuid)
Definition: TYElement.cpp:158
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
LPTYDalle getPlafond()
Definition: TYEtage.h:229
void setacousticFacesPourCalcul(bool bPourCalculTrajet)
Definition: TYEtage.cpp:2022
TYTabMurGeoNode & getTabMur()
Definition: TYEtage.h:143
bool getClosed()
Definition: TYEtage.h:206
const ORepere3D & getORepere3D() const
void setHauteur(const double &hauteur)
Set the heigth above the ground.
double getHauteur()
Get the height above the ground.
TYElement * getElement() const
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
OMatrix getMatrix() const
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
TYTabBatimentGeoNode & getListBatiment()
bool addToCalcul(TYGeometryNode *pNode)
LPTYUserSourcePonctuelleGeoNode getSrc(int index)
LPTYMachineGeoNode getMachine(int index)
virtual void reparent()
LPTYReseauTransport getResTrans(int index)
TYTabUserSourcePonctuelleGeoNode & getSrcs()
LPTYBatimentGeoNode getBatiment(int index)
TYTabReseauTransportGeoNode & getListResTrans()
virtual DOM_Element toXML(DOM_Element &domElement)
bool addBatiment(LPTYBatimentGeoNode pBatimentGeoNode)
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
bool addMachine(LPTYMachineGeoNode pMachineGeoNode)
bool addSrc(LPTYUserSourcePonctuelle pSrc)
bool updateAcoustic(const TYCalcul *pCalcul, const bool &force=false)
TYTabMachineGeoNode & getListMachine()
bool addResTrans(LPTYReseauTransportGeoNode pResTransGeoNode)
Definition: TYMur.h:36
QString generateName(const char *classname)
Retourne le nom de la classe associe a un nombre.
void enable(bool enable)
Active la generation de nom.
Definition: TYNameManager.h:64
static TYNameManager * get()
Retourne l'instance singleton.
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYPoint.cpp:112
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYPoint.cpp:92
const TYTabPoint & getPoints() const
Definition: TYPolygon.h:123
virtual OVector3D normal() const
Definition: TYPolygon.cpp:243
void updateNormal()
Definition: TYPolygon.cpp:523
void remElmtFromCalculs(TYElement *pElement)
Supprime un element de tous les calculs.
Definition: TYProjet.cpp:743
bool updateAltiRecepteurs()
Definition: TYProjet.cpp:653
double getDelaunayTolerence()
Definition: TYProjet.h:490
LPTYCalcul getCurrentCalcul()
Set/Get du pointeur du Calcul courant.
Definition: TYProjet.h:426
double getHauteurMoyenne() const
virtual bool updateAltitudes(const TYAltimetrie &alti, LPTYRouteGeoNode pGeoNode, OMatrix globalMatrix)
Required the road to update its altitude after altimetry changed.
Definition: TYRoute.cpp:420
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYSegment.cpp:97
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYSegment.cpp:120
TYTabSiteNodeGeoNode collectSites(bool include=true) const
const double getAltiEmprise() const
Definition: TYSiteNode.h:141
double _SIG_Y
Definition: TYSiteNode.h:709
void selectCourbeNiveauAndPlanEau()
Definition: TYSiteNode.cpp:781
void setProjet(const LPTYProjet pProjet)
Definition: TYSiteNode.cpp:560
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYSiteNode.cpp:223
void purge()
Definition: TYSiteNode.h:97
LPTYAltimetrie getAltimetry() const
void appendSite(LPTYSiteNode pSiteFrom, const OMatrix &matrix, LPTYSiteNode pSiteTo)
OMatrix getGlobalMatrix() const
LPTYTopographie getTopographie()
Definition: TYSiteNode.h:149
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYSiteNode.cpp:544
virtual void setIsGeometryModified(bool isModified)
Definition: TYSiteNode.cpp:501
bool readMesh(std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, std::deque< LPTYSol > &materials, const QString &meshFilePath)
Definition: TYSiteNode.cpp:733
virtual void do_updateAltimetrie(QString resultMeshFilePath)
Definition: TYSiteNode.cpp:646
virtual bool remFromCalcul()
Definition: TYSiteNode.cpp:527
LPTYTopographie _pTopographie
Topographie.
Definition: TYSiteNode.h:670
void setEmprise(TYTabPoint points)
Definition: TYSiteNode.h:362
QString _topoFile
Nom du fichier de topographie temporaire.
Definition: TYSiteNode.h:685
virtual void setChildsNotInCurrentCalcul()
void setTopoFileName(const QString &name)
Definition: TYSiteNode.h:248
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYSiteNode.cpp:473
LPTYSiteNode merge()
virtual void reparent()
Definition: TYSiteNode.cpp:569
bool remSiteNode(const LPTYSiteNodeGeoNode pSiteNodeGeoNode)
LPTYInfrastructure getInfrastructure()
Definition: TYSiteNode.h:174
LPTYInfrastructure _pInfrastructure
Infrastructure.
Definition: TYSiteNode.h:673
QString _topoFileName
Nom du fichier de topographie (image de fond)
Definition: TYSiteNode.h:679
virtual ~TYSiteNode()
Definition: TYSiteNode.cpp:97
double _altiEmprise
Altitude associee a l'emprise (s'il y a lieu)
Definition: TYSiteNode.h:667
float _echelle
Echelle du site.
Definition: TYSiteNode.h:691
virtual int fromXML(DOM_Element domElement)
Definition: TYSiteNode.cpp:324
systemSIG _SIGType
Coordonnees SIG.
Definition: TYSiteNode.h:706
const QString & getMeshFilePath()
Definition: TYSiteNode.cpp:59
TYTabSiteNodeGeoNode _listSiteNode
Liste des sites.
Definition: TYSiteNode.h:713
TYPoint _position
Position.
Definition: TYSiteNode.h:695
QString _meshFilePath
Chemin vers le fichier PLY d'altimétrie.
Definition: TYSiteNode.h:682
bool _useTopoFile
Flag d'utilisation d'une image de fond.
Definition: TYSiteNode.h:676
QString _topoFileExtension
Extension du fichier de topographie.
Definition: TYSiteNode.h:688
virtual void updateAcoustique(const bool &force=false)
void setMeshFilePath(const QString &path)
Definition: TYSiteNode.cpp:64
void uuid2tysol(const std::deque< std::string > &material_ids, std::deque< LPTYSol > &materials)
Definition: TYSiteNode.cpp:760
void update(const bool &force=false)
bool _root
Test si site racine.
Definition: TYSiteNode.h:703
void getListFaces(TYTabAcousticSurfaceGeoNode &tabFaces, unsigned int &nbFaceInfra, std::vector< bool > &EstUnIndexDeFaceEcran) const
static const QString & getTopoFilePath()
Definition: TYSiteNode.cpp:49
double getDelaunay()
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYSiteNode.cpp:271
TYTabSiteNodeGeoNode & getListSiteNode()
Definition: TYSiteNode.h:346
virtual std::string toString() const
Definition: TYSiteNode.cpp:266
LPTYSiteNodeGeoNode findSiteNode(const LPTYSiteNode pSiteNode)
LPTYProjet _pProjet
Projet auquel appartient (eventuellement) le site.
Definition: TYSiteNode.h:661
TYSegment _orientation
Orientation du Nord.
Definition: TYSiteNode.h:693
bool addSiteNode(LPTYSiteNodeGeoNode pSiteNodeGeoNode)
void loadTopoFile()
Definition: TYSiteNode.cpp:586
virtual TYSiteNode & operator=(const TYSiteNode &other)
Operateur =.
Definition: TYSiteNode.cpp:102
virtual bool updateAltimetrie(QString resultMeshFilePath)
Definition: TYSiteNode.cpp:628
static void setTopoFilePath(const QString &path)
Definition: TYSiteNode.cpp:54
virtual void exportCSV(std::ofstream &ofs)
Export au format csv sur un flux transmis.
void getListFacesWithoutFloor(TYTabAcousticSurfaceGeoNode &tabFaces, unsigned int &nbFaceInfra, std::vector< bool > &EstUnIndexDeFaceEcran, std::vector< std::pair< int, int >> &indices, std::vector< int > &etages) const
bool getUseEmpriseAsCrbNiv() const
Definition: TYSiteNode.h:123
virtual void updateAltiInfra()
Definition: TYSiteNode.cpp:838
void groundBasedFaces(const TYTabAcousticVolumeGeoNode &volumes, const OMatrix &global_matrix, std::map< TYUUID, std::deque< TYTabPoint3D >> &contours) const
bool getRoot() const
Definition: TYSiteNode.h:321
double _SIG_X
Definition: TYSiteNode.h:708
virtual bool addToCalcul()
Definition: TYSiteNode.cpp:511
void getFacesOnGround(std::map< TYUUID, std::deque< TYTabPoint3D >> &contours) const
bool _bEmpriseAsCrbNiv
Utilisation de l'emprise comme courbe de niveau.
Definition: TYSiteNode.h:664
virtual bool operator!=(const TYSiteNode &other) const
Operateur !=.
Definition: TYSiteNode.cpp:218
bool _isTopoFileModified
Flag de modification de l'image de fond.
Definition: TYSiteNode.h:716
double _SIG_OFFSET
Definition: TYSiteNode.h:710
virtual bool operator==(const TYSiteNode &other) const
Operateur ==.
Definition: TYSiteNode.cpp:130
static QString _topoFilePath
Chemin du dossier image temporaire.
Definition: TYSiteNode.h:657
Definition: TYSol.h:25
virtual void setListPoints(const TYTabPoint &liste)
Definition: TYTerrain.h:145
LPTYSol getSol() const
Definition: TYTerrain.h:77
virtual TYTabPoint & getListPoints()
Definition: TYTerrain.h:131
void setSol(const LPTYSol pSol)
Definition: TYTerrain.h:89
TYTerrain * getDefTerrain()
virtual void setIsGeometryModified(bool isModified)
TYTabPlanEauGeoNode & getListPlanEau()
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
bool addCrsEau(LPTYCoursEauGeoNode pCoursEauGeoNode)
LPTYCoursEau getCrsEau(int index)
virtual DOM_Element toXML(DOM_Element &domElement)
virtual void reparent()
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
LPTYAltimetrie getAltimetrie()
void setDefTerrain(int defTerrainIdx)
void setDefTerrainIdx(const int &defTerrainIdx)
TYTabCoursEauGeoNode & getListCrsEau()
bool addCrbNiv(LPTYCourbeNiveauGeoNode pCrbNivGeoNode)
bool addPlanEau(LPTYPlanEauGeoNode pPlanEauGeoNode)
LPTYTerrain getTerrain(int index)
TYTabPoint & getEmprise()
TYTabCourbeNiveauGeoNode & getListCrbNiv()
bool addTerrain(LPTYTerrainGeoNode pTerGeoNode)
TYTabTerrainGeoNode & getListTerrain()
void sortTerrainsBySurface()
void exportCSV(std::ofstream &ofs)
Export au format csv sur un flux transmis.
static QString getSavedFileName()
Definition: TYXMLManager.h:140
static void addElementDoubleValue(DOM_Element &parentElem, DOMString nodeName, double nodeValue)
Definition: TYXMLTools.cpp:87
static bool getElementBoolValue(DOM_Element parentElem, DOMString nodeName, bool &nodeValue)
Definition: TYXMLTools.cpp:179
static bool getElementStringValue(DOM_Element parentElem, DOMString nodeName, QString &nodeValue)
Definition: TYXMLTools.cpp:93
static void addElementIntValue(DOM_Element &parentElem, DOMString nodeName, int nodeValue)
Definition: TYXMLTools.cpp:72
static bool getElementFloatValue(DOM_Element parentElem, DOMString nodeName, float &nodeValue)
Definition: TYXMLTools.cpp:211
static bool getElementIntValue(DOM_Element parentElem, DOMString nodeName, int &nodeValue)
Definition: TYXMLTools.cpp:129
static bool getElementDoubleValue(DOM_Element parentElem, DOMString nodeName, double &nodeValue)
Definition: TYXMLTools.cpp:243
static void addElementBoolValue(DOM_Element &parentElem, DOMString nodeName, bool nodeValue)
Definition: TYXMLTools.cpp:77
static void addElementStringValue(DOM_Element &parentElem, DOMString nodeName, DOMString nodeValue)
Definition: TYXMLTools.cpp:24
static void addElementFloatValue(DOM_Element &parentElem, DOMString nodeName, float nodeValue)
Definition: TYXMLTools.cpp:82
read an Altimetry from a PLY file.
virtual const points_array_t & points() const
virtual void read()
read the file whose name was given at reader's construction time
virtual const materials_array_t & materials() const
Getter for the faces read.
virtual const faces_array_t & faces() const
Getter for the faces read.
static FILE * openFileForReading(const QString &filename)
#define tympan_source_loc
This macro build a source_loc object to be attached to a tympan::Exception.
Definition: exceptions.h:91
unsigned int uint32
Definition: defines.h:75
void save_project(const char *filename, const LPTYProjet &project)
save a project into an XML file
The base exception class for all exceptions specific to Code_TYMPAN.
Definition: exceptions.h:63
The base exception class for errors due to invalid data.
Definition: exceptions.h:75
bool python(QStringList args, std::string &error_msg)
Launch a Python subprocess and wait for it using a non-blocking UI loop.
bool must_keep_tmp_files()
Tell whether temporary files should be preserved (debug mode).
bool init_tmp_file(QTemporaryFile &tmp_file, bool keep_file)
Create and initialize a QTemporaryFile according to the current policy.
Utilities to interact with Python subprocesses from the Tympan application.
Utilities to load a project and a solver.