Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYGeometryNode.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 /*
17  *
18  */
19 
20 #include "Tympan/core/logging.h"
21 
23 // Implementation
24 
25 #include "TYGeometryNode.h"
26 #include "models/common/3d.h"
27 #if TY_USE_IHM
29 #endif
30 
33 
34 // acces map like a singleton to avoid bad order in static instantiation
36 {
37  if (_geoNodeMap)
38  {
39  return _geoNodeMap;
40  }
41  else
42  {
43  return _geoNodeMap = new TYMapPtrGeoNode();
44  }
45 }
46 
48 {
50  {
51  return _geoNodeDoublonsList;
52  }
53  else
54  {
56  }
57 }
58 
60 {
61  if (NULL == (TYElement*)getElement())
62  {
63  return; // ne devrait pas arriver
64  }
65  // La place est-elle deja prise ?
66  TYGeometryNode* pOldGeometryNode = GetGeoNode(getElement());
67  if (pOldGeometryNode)
68  {
69  // oui => memoriser l'ancien geoNode:
70  GetGeoNodeDoublonsList()->push_back(pOldGeometryNode);
71  }
72  (*GetGeoNodeMap())[getElement()] = this;
73 }
74 
76 {
77  if (NULL == (TYElement*)getElement())
78  {
79  return; // ne devrait pas arriver
80  }
81  // 1. supprimer toute reference a this dans la map:
82  // La place est-elle deja prise ?
83  TYGeometryNode* pOldGeometryNode = GetGeoNode(getElement());
84  if (pOldGeometryNode)
85  {
86  // oui => l'enlever de la map:
87  GetGeoNodeMap()->erase(getElement());
88  }
89  // Y a-t-il parmi la liste de doublon un geoNode pointant sur cet element ?
90  // Si c'est le cas, on l'ajoute a la map:
91  TYListPtrGeoNode::iterator ite;
92  for (ite = GetGeoNodeDoublonsList()->begin(); ite != GetGeoNodeDoublonsList()->end(); ite++)
93  {
94  TYGeometryNode* pCurrentTYGeometryNode = TYGeometryNode::safeDownCast((*ite));
95  if (pCurrentTYGeometryNode->getElement() == getElement())
96  {
97  // Oui
98  // on l'enleve de la liste:
99  GetGeoNodeDoublonsList()->erase(ite);
100  // on l'ajoute a la map:
101  pCurrentTYGeometryNode->addToTheMap();
102  break;
103  }
104  }
105 }
106 
108 {
110 
111  _hauteur = 0.0; // dt++
112  _pElement = NULL; // az++
113 }
114 
115 TYGeometryNode::TYGeometryNode(TYElement* pElt, TYElement* pParent /*=NULL*/) : TYElement(pParent)
116 {
117  _pElement = pElt;
118  addToTheMap();
119  _hauteur = 0.0;
120 
121  if (pParent && _pElement)
122  {
123  // On assigne le meme parent a l'element si celui-ci n'est pas null
124  _pElement->setParent(pParent);
125  }
126 }
127 
128 TYGeometryNode::TYGeometryNode(LPTYElement pElt, TYElement* pParent /*=NULL*/) : TYElement(pParent)
129 {
130  _pElement = pElt;
131  addToTheMap();
132  _hauteur = 0.0;
133 
134  if (pParent && _pElement)
135  {
136  // On assigne le meme parent a l'element si celui-ci n'est pas null
137  _pElement->setParent(pParent);
138  }
139 }
140 
142 {
143  _repere = repere;
144  _hauteur = 0.0;
145 
146  _pElement = pElt;
147  addToTheMap();
148 }
149 
151 {
152  _repere = repere;
153  _hauteur = 0.0;
154 
155  _pElement = pElt;
156  addToTheMap();
157 }
158 
159 TYGeometryNode::TYGeometryNode(TYElement* pElt, const OMatrix& matrix) : _repere(matrix)
160 {
161  _hauteur = 0.0;
162 
163  _pElement = pElt;
164  addToTheMap();
165 }
166 
167 TYGeometryNode::TYGeometryNode(LPTYElement pElt, const OMatrix& matrix) : _repere(matrix)
168 {
169  _hauteur = 0.0;
170 
171  _pElement = pElt;
172  addToTheMap();
173 }
174 
176 {
177  _pElement = NULL;
178  *this = other;
179 }
180 
182 {
183  if (_pElement) // ce test a ete rajoute surtout pour eviter de faire des recherches dans les map & list en
184  // fin d'application, car les map & list en static peuvent etre detruites avant le dernier
185  // GeoNode !
186  {
187  // Comme le pointeur this ne sera plus valide, le supprimer de la liste des doublons:
188  GetGeoNodeDoublonsList()->remove(this);
189  // Enlever toute reference dans le map:
191  }
192 }
193 
195 {
196  DOM_Element domNewElem = TYElement::toXML(domElement);
197 
198  // On sauvegarde la hauteur en premier
199  TYXMLTools::addElementStringValue(domNewElem, "hauteur", doubleToStrPre(_hauteur, 3).data());
200  // Puis, on sauvegarde le repere
201  _repere.toXML(domNewElem);
202 
203  if (_pElement)
204  {
205  _pElement->toXML(domNewElem);
206  }
207 
208  return domNewElem;
209 }
210 
212 {
213  TYElement::fromXML(domElement);
214 
215  int res = -1;
216  int retVal = 0;
217  bool eltFound = false;
218  bool hauteurOk = false;
219  double hauteurLue = 0;
220  DOM_Element elemCur;
221  DOM_Node nodeTmp;
222  QString str;
223 
224  QDomNodeList childs = domElement.childNodes();
225 
226  for (unsigned int i = 0; i < childs.length(); i++)
227  {
228  retVal = -1;
229  elemCur = childs.item(i).toElement();
230 
231  // La hauteur doit etre le premier element
232  TYXMLTools::getElementDoubleValue(elemCur, "hauteur", hauteurLue, hauteurOk);
233  if (hauteurOk)
234  {
235  _hauteur = hauteurLue;
236  }
237 
238  // On cherche le repere
239  if (_repere.callFromXMLIfEqual(elemCur, &retVal))
240  {
241  // Fix #115 : Si le Repere est invalide alors on ne lit pas le GeometryNode
242  if (retVal == 1)
243  {
244  // Le prochain child (node et pas '#text')
245  // doit etre le noeud de l'element
246  nodeTmp = elemCur.nextSibling();
247 
248  // problem here with count
249  // nodeTmp = nodeTmp.nextSibling();
250 
251  // Au cas oi nbChild soit faux (trop grand)
252  if (nodeTmp.isNull())
253  {
254  break;
255  }
256 
257  // Ajout du prefixe TY
258  str = "TY";
259  str += nodeTmp.nodeName();
260 
261  // Auto construction a partir du type trouve
262  //_pElement = (TYElement *) TYElement::findAndClone((char *)str.data());//az--
263  setElement((TYElement*)TYElement::findAndClone((char*)str.toLatin1().data())); // az++
264 
265  // Si la classe a ete trouve (elle doit heriter de TYElement)
266  if (_pElement)
267  {
268  // Le parent de l'element n'est pas le GeoNode mais son parent
269  // (uniquement si le champs parent du GeoNode est renseigne)
270  if (getParent())
271  {
273  }
274 
275  // Parsing
276  _pElement->fromXML(*((DOM_Element*)&nodeTmp));
277 
278  // L'element a ete trouve et traite
279  eltFound = true;
280  }
281  }
282  }
283  }
284 
285  if (eltFound)
286  {
287  res = 1;
288  }
289 
290  return res;
291 }
292 
293 void TYGeometryNode::getChilds(LPTYElementArray& childs, bool recursif /*=true*/)
294 {
295  TYElement::getChilds(childs, recursif);
296 
297  if (_pElement)
298  {
299  _pElement->getChilds(childs, recursif);
300  }
301 }
302 
304 {
305  setElement((TYElement*)pElt);
306 }
307 
309 {
311  _pElement = pElt;
312  addToTheMap();
313 
314  setIsGeometryModified(true);
315 }
316 
318 {
319  if (_pElement)
320  {
321  GetGeoNodeMap()->erase(_pElement);
322  delete _pElement;
323  _pElement = NULL;
324  }
325 
326  setIsGeometryModified(true);
327 }
328 
330 {
331  if (this != &other)
332  {
333  TYElement::operator=(other);
334  //_pElement = other._pElement;//az--
335  setElement(other._pElement); // az++
336  _repere = other._repere;
337  _hauteur = other._hauteur;
338  }
339  return *this;
340 }
341 
343 {
344  if (this != &other)
345  {
346  if (TYElement::operator!=(other))
347  {
348  return false;
349  }
350  if (_pElement != other._pElement)
351  {
352  return false;
353  }
354  if (_repere != other._repere)
355  {
356  return false;
357  }
358  if (_hauteur != other._hauteur)
359  {
360  return false;
361  }
362  }
363  return true;
364 }
365 
367 {
368  return !operator==(other);
369 }
370 
371 bool TYGeometryNode::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
372 {
373  TYElement::deepCopy(pOther, copyId);
374  TYGeometryNode* pOtherGeoNode = NULL;
375  if (pOther)
376  {
377  pOtherGeoNode = (TYGeometryNode*)pOther;
378  }
379  if (!pOtherGeoNode || !pOtherGeoNode->getElement())
380  {
381  return false;
382  }
383 
384  // Avant de faire la deep copy sur l'element il faut s'assurer
385  // qu'ils sont de meme type
386  setElement((TYElement*)pOtherGeoNode->getElement()->clone());
387 
388  // Deep copy de l'element
389  if (!_pElement->deepCopy(pOtherGeoNode->_pElement, copyId, true))
390  {
391  return false;
392  }
393 
394  // Deep copy du repere
395  if (!_repere.deepCopy(&pOtherGeoNode->_repere, copyId))
396  {
397  return false;
398  }
399 
400  _hauteur = pOtherGeoNode->_hauteur;
401 
402  setIsGeometryModified(true);
403  setIsAcousticModified(true);
404 
405  return true;
406 }
407 
408 // XXX There seems to be excessive complexity around updateMatrix and updateRepere :
409 // setMAtrix->setPrivateMatrix->updateRepere->_repere.set(_matrix)
410 // FIXME Why this double copy of matrices while it looks like
411 // _repere.getMatChangeRep(_matrix) would be simpler and more efficient ?
413 {
414  if (GetGeoNodeMap()->find(pElement) != GetGeoNodeMap()->end())
415  {
416  return ((*GetGeoNodeMap())[pElement]);
417  }
418  return NULL;
419 }
420 
422 {
423  if (GetGeoNodeMap()->find(pElement) != GetGeoNodeMap()->end())
424  {
425  return ((*GetGeoNodeMap())[pElement]);
426  }
427  return NULL;
428 }
429 
431 {
432  // 1. Element pointe par le GeoNode:
433  TYElement* pElement = getElement();
434  // 2. on s'interresse aux parents du cet element
435  TYElement* pCurrentParent = pElement->getParent();
436  while (pCurrentParent)
437  {
438  // 3. le parent est peut-etre deja un TYGeometryNode ?
439  TYGeometryNode* pPotentialGeoNode = TYGeometryNode::safeDownCast(pCurrentParent);
440  if (pPotentialGeoNode)
441  {
442  return pPotentialGeoNode;
443  }
444  // 4. le parent dispose d'un GeoNode
445  pPotentialGeoNode = GetGeoNode(pCurrentParent);
446  if (pPotentialGeoNode)
447  {
448  return pPotentialGeoNode;
449  }
450  // 5. examinons le parent du parent...
451  pCurrentParent = pCurrentParent->getParent();
452  }
453  return NULL;
454 }
455 
457 {
458  TYGeometryNode* pCurrrentGeoNodeParent = GetGeoNodeParent();
459  while (pCurrrentGeoNodeParent)
460  {
461  GetGeoNodeParents.push_back(pCurrrentGeoNodeParent);
462  pCurrrentGeoNodeParent = pCurrrentGeoNodeParent->GetGeoNodeParent();
463  }
464 }
465 
467 {
468  TYGeometryNode* pParent = GetGeoNodeParent();
469  OMatrix matrix = _repere.asMatrix();
470 
471  while (pParent != NULL)
472  {
473  matrix = pParent->getORepere3D().asMatrix() * matrix;
474  pParent = pParent->GetGeoNodeParent();
475  }
476 
477  return matrix;
478 }
479 
481 {
482  TYGeometryNode* pParent = GetGeoNodeParent();
483  OMatrix matrix = _repere.asMatrix();
484  while (pParent != NULL && pParent != pGeoNode)
485  {
486  matrix = pParent->getORepere3D().asMatrix() * matrix;
487  pParent = pParent->GetGeoNodeParent();
488  }
489  return matrix;
490 }
491 
493 {
494  return localToGlobal().getInvert();
495 }
496 
497 #if TY_USE_IHM
498 LPTYElementGraphic TYGeometryNode::getGraphicObject()
499 {
500  if (!_pGraphicObject)
501  {
503  }
504  return _pGraphicObject;
505 }
506 #endif // TY_USE_IHM
507 
509 {
510  _repere = repere;
511 #if TY_USE_IHM
512  TYGeometryNodeGraphic* geoNodeGraphic =
513  dynamic_cast<TYGeometryNodeGraphic*>(getGraphicObject().getRealPointer());
514  if (geoNodeGraphic != nullptr)
515  {
516  geoNodeGraphic->invalidateMatrix();
517  }
518 #endif
519 }
520 
522 {
523  _repere.set(matrix);
524 #if TY_USE_IHM
525  TYGeometryNodeGraphic* geoNodeGraphic =
526  dynamic_cast<TYGeometryNodeGraphic*>(getGraphicObject().getRealPointer());
527  if (geoNodeGraphic != nullptr)
528  {
529  geoNodeGraphic->invalidateMatrix();
530  }
531 #endif
532  setIsGeometryModified(true);
533 }
534 
536 {
537  ORepere3D repere = getORepere3D();
538  repere._origin._x = pos._x;
539  repere._origin._y = pos._y;
540  repere._origin._z = pos._z;
541  setRepere(repere);
542 }
543 
545 {
546  OMatrix tyMat;
547  OMatrix tyMatTmpX;
548  OMatrix tyMatTmpY;
549  OMatrix tyMatTmpZ;
550  OMatrix tyMatTmpConcat;
551 
552  // On applique la rotation
553  double dRotateX = rot._x;
554  double dRotateY = rot._y;
555  double dRotateZ = rot._z;
556 
557  tyMatTmpX.setRotationOx(-DEGTORAD(dRotateX));
558  tyMatTmpY.setRotationOy(-DEGTORAD(dRotateY));
559  tyMatTmpZ.setRotationOz(DEGTORAD(dRotateZ));
560 
561  tyMat = tyMat * tyMatTmpZ * tyMatTmpY * tyMatTmpX * tyMatTmpConcat;
562 
563  OPoint3D org = _repere._origin; // On conserve l'origine de depart
564  ORepere3D repere = getORepere3D();
565  repere.set(tyMat);
566  repere._origin = org;
567  setRepere(repere);
568 }
569 
571 {
572  OMatrix mat = getMatrix();
573  // Get rotations from transform matrix
574  OPoint3D vec;
575  vec._x = mat._m[0][1];
576  vec._y = mat._m[1][1];
577  vec._z = mat._m[2][1];
578 
579  // Get X-vector for roll calculation
580  OPoint3D xv;
581  xv._x = mat._m[0][0];
582  xv._y = mat._m[1][0];
583  xv._z = mat._m[2][0];
584 
585  // Calculate PRH (x = pitch, y = roll, z = heading)
586  OPoint3D rotTmp(-atan2(vec._z, sqrt(vec._x * vec._x + vec._y * vec._y)), xv._z, -atan2(-vec._x, vec._y));
587 
588  // Set up vars
589  double pitch = RADTODEG(rotTmp._x); // Pitch
590  double yaw = -RADTODEG(rotTmp._z); // Heading
591  double roll = RADTODEG(rotTmp._y); // Roll
592 
593  // Affiche la boite de dialogue
594  return OPoint3D(pitch, roll, yaw);
595 }
All base classes related to 3D manipulation.
double RADTODEG(double a)
Converts an angle from radians to degrees.
Definition: 3d.h:137
double DEGTORAD(double a)
Converts an angle from degrees to radians.
Definition: 3d.h:126
QDomNode DOM_Node
Definition: QT2DOM.h:32
QDomElement DOM_Element
Definition: QT2DOM.h:30
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:344
Representation graphique d'un GeometryNode (fichier header)
std::map< const TYElement *, TYGeometryNode * > TYMapPtrGeoNode
std::list< TYGeometryNode * > TYListPtrGeoNode
Liste ordonnee de pointeurs de TYElement.
double _y
y coordinate of OCoord3D
Definition: 3d.h:283
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
double _x
x coordinate of OCoord3D
Definition: 3d.h:282
The 4x4 matrix class.
Definition: 3d.h:625
int setRotationOz(double a)
Update a rotation matrix (Oz axis).
Definition: 3d.cpp:688
int setRotationOy(double a)
Update a rotation matrix (Oy axis).
Definition: 3d.cpp:676
OMatrix getInvert(int *ok=0) const
Return the inverse matrix of this matrix.
Definition: 3d.cpp:813
int setRotationOx(double a)
Update a rotation matrix (Ox axis).
Definition: 3d.cpp:664
double _m[4][4]
The 4x4 matrix array.
Definition: 3d.h:974
The 3D point class.
Definition: 3d.h:487
virtual OPrototype * clone() const =0
virtual const char * getClassName() const
Definition: TYElement.h:248
static OPrototype * safeDownCast(OPrototype *pObject)
Definition: TYElement.cpp:71
static OPrototype * findAndClone(const char *className)
Definition: TYElement.cpp:37
3D frame with a point and 3 vectors.
Definition: 3d.h:1263
void set(const OPoint3D &origin, const OVector3D &vecI, const OVector3D &vecJ, const OVector3D &vecK)
Sets with a point and 3 vectors.
Definition: 3d.cpp:1427
OPoint3D _origin
The origin point.
Definition: 3d.h:1331
OMatrix asMatrix() const
return the transformation matrix from unity to this pose such as this = transform * unity
Definition: 3d.cpp:1462
TYElement * getParent() const
Definition: TYElement.h:697
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:305
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:366
QString _name
Nom courant de l'element.
Definition: TYElement.h:956
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:263
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:545
LPTYElementGraphic _pGraphicObject
L'object graphique metier associe a cet element.
Definition: TYElement.h:974
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:530
void setParent(TYElement *pParent)
Definition: TYElement.h:690
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:379
virtual void setIsAcousticModified(bool isModified)
Definition: TYElement.cpp:248
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
classe graphique pour un GeometryNode
static TYListPtrGeoNode * GetGeoNodeDoublonsList()
const ORepere3D & getORepere3D() const
void setMatrix(const OMatrix &matrix)
static TYMapPtrGeoNode * GetGeoNodeMap()
OMatrix localToGlobal() const
OMatrix globalToLocal() const
virtual DOM_Element toXML(DOM_Element &domElement)
void setRotation(const OPoint3D &rot)
Set the rotation angle along axis x, y & z represented as an OPoint3D.
TYGeometryNode & operator=(const TYGeometryNode &other)
LPTYElement _pElement
L'instance de l'element geometrique.
TYRepere _repere
Le repere definissant la position et l'orientation de l'element.
static TYMapPtrGeoNode * _geoNodeMap
bool operator!=(const TYGeometryNode &other) const
virtual int fromXML(DOM_Element domElement)
TYGeometryNode * GetGeoNodeParent() const
void GetGeoNodeParentList(TYListPtrGeoNode &GetGeoNodeParents)
void setElement(LPTYElement pElt)
double _hauteur
Hauteur de l'element par rapport au sol.
static TYListPtrGeoNode * _geoNodeDoublonsList
bool operator==(const TYGeometryNode &other) const
OMatrix localToGeoNode(const TYGeometryNode *pGeoNode) const
TYElement * getElement() const
virtual ~TYGeometryNode()
OPoint3D rotation()
Get the rotation angle along axis x, y & z represented as an OPoint3D.
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
OMatrix getMatrix() const
static TYGeometryNode * GetGeoNode(TYElement *pElement)
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
void setPosition(const OPoint3D &pos)
Set the position of the element.
void setRepere(const ORepere3D &repere)
QString generateName(const char *classname)
Retourne le nom de la classe associe a un nombre.
static TYNameManager * get()
Retourne l'instance singleton.
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYRepere.cpp:102
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYRepere.cpp:85
static bool getElementDoubleValue(DOM_Element parentElem, DOMString nodeName, double &nodeValue)
Definition: TYXMLTools.cpp:243
static void addElementStringValue(DOM_Element &parentElem, DOMString nodeName, DOMString nodeValue)
Definition: TYXMLTools.cpp:24
std::string doubleToStrPre(double val, int precision=2)
Definition: macros.h:205