Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYGeometryNode.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
16 /*
17  *
18  */
19 
20 #include "Tympan/core/logging.h"
22 
24 // Implementation
25 
26 #include "TYGeometryNode.h"
27 
30 
31 // acces map like a singleton to avoid bad order in static instantiation
33 {
34  if (_geoNodeMap)
35  {
36  return _geoNodeMap;
37  }
38  else
39  {
40  return _geoNodeMap = new TYMapPtrGeoNode();
41  }
42 }
43 
45 {
47  {
48  return _geoNodeDoublonsList;
49  }
50  else
51  {
53  }
54 }
55 
57 {
58  if (NULL == (TYElement*)getElement())
59  {
60  return; // ne devrait pas arriver
61  }
62  // La place est-elle deja prise ?
63  TYGeometryNode* pOldGeometryNode = GetGeoNode(getElement());
64  if (pOldGeometryNode)
65  {
66  // oui => memoriser l'ancien geoNode:
67  GetGeoNodeDoublonsList()->push_back(pOldGeometryNode);
68  }
69  (*GetGeoNodeMap())[getElement()] = this;
70 }
71 
73 {
74  if (NULL == (TYElement*)getElement())
75  {
76  return; // ne devrait pas arriver
77  }
78  // 1. supprimer toute reference a this dans la map:
79  // La place est-elle deja prise ?
80  TYGeometryNode* pOldGeometryNode = GetGeoNode(getElement());
81  if (pOldGeometryNode)
82  {
83  // oui => l'enlever de la map:
84  GetGeoNodeMap()->erase(getElement());
85  }
86  // Y a-t-il parmi la liste de doublon un geoNode pointant sur cet element ?
87  // Si c'est le cas, on l'ajoute a la map:
88  TYListPtrGeoNode::iterator ite;
89  for (ite = GetGeoNodeDoublonsList()->begin(); ite != GetGeoNodeDoublonsList()->end(); ite++)
90  {
91  TYGeometryNode* pCurrentTYGeometryNode = TYGeometryNode::safeDownCast((*ite));
92  if (pCurrentTYGeometryNode->getElement() == getElement())
93  {
94  // Oui
95  // on l'enleve de la liste:
96  GetGeoNodeDoublonsList()->erase(ite);
97  // on l'ajoute a la map:
98  pCurrentTYGeometryNode->addToTheMap();
99  break;
100  }
101  }
102 }
103 
105 {
107 
108  _hauteur = 0.0; // dt++
109  _pElement = NULL; // az++
110 }
111 
112 TYGeometryNode::TYGeometryNode(TYElement* pElt, TYElement* pParent /*=NULL*/) : TYElement(pParent)
113 {
114  _pElement = pElt;
115  addToTheMap();
116  _hauteur = 0.0;
117 
118  if (pParent && _pElement)
119  {
120  // On assigne le meme parent a l'element si celui-ci n'est pas null
121  _pElement->setParent(pParent);
122  }
123 }
124 
125 TYGeometryNode::TYGeometryNode(LPTYElement pElt, TYElement* pParent /*=NULL*/) : TYElement(pParent)
126 {
127  _pElement = pElt;
128  addToTheMap();
129  _hauteur = 0.0;
130 
131  if (pParent && _pElement)
132  {
133  // On assigne le meme parent a l'element si celui-ci n'est pas null
134  _pElement->setParent(pParent);
135  }
136 }
137 
139 {
140  _repere = repere;
141  _hauteur = 0.0;
142 
143  _pElement = pElt;
144  addToTheMap();
145 }
146 
148 {
149  _repere = repere;
150  _hauteur = 0.0;
151 
152  _pElement = pElt;
153  addToTheMap();
154 }
155 
156 TYGeometryNode::TYGeometryNode(TYElement* pElt, const OMatrix& matrix) : _repere(matrix)
157 {
158  _hauteur = 0.0;
159 
160  _pElement = pElt;
161  addToTheMap();
162 }
163 
164 TYGeometryNode::TYGeometryNode(LPTYElement pElt, const OMatrix& matrix) : _repere(matrix)
165 {
166  _hauteur = 0.0;
167 
168  _pElement = pElt;
169  addToTheMap();
170 }
171 
173 {
174  _pElement = NULL;
175  *this = other;
176 }
177 
179 {
180  if (_pElement) // ce test a ete rajoute surtout pour eviter de faire des recherches dans les map & list en
181  // fin d'application, car les map & list en static peuvent etre detruites avant le dernier
182  // GeoNode !
183  {
184  // Comme le pointeur this ne sera plus valide, le supprimer de la liste des doublons:
185  GetGeoNodeDoublonsList()->remove(this);
186  // Enlever toute reference dans le map:
188  }
189 }
190 
192 {
193  DOM_Element domNewElem = TYElement::toXML(domElement);
194 
195  // On sauvegarde la hauteur en premier
196  TYXMLTools::addElementStringValue(domNewElem, "hauteur", doubleToStrPre(_hauteur, 3).data());
197  // Puis, on sauvegarde le repere
198  _repere.toXML(domNewElem);
199 
200  if (_pElement)
201  {
202  _pElement->toXML(domNewElem);
203  }
204 
205  return domNewElem;
206 }
207 
209 {
210  TYElement::fromXML(domElement);
211 
212  int res = -1;
213  int retVal = 0;
214  bool eltFound = false;
215  bool hauteurOk = false;
216  double hauteurLue = 0;
217  DOM_Element elemCur;
218  DOM_Node nodeTmp;
219  QString str;
220 
221  QDomNodeList childs = domElement.childNodes();
222 
223  for (unsigned int i = 0; i < childs.length(); i++)
224  {
225  retVal = -1;
226  elemCur = childs.item(i).toElement();
227 
228  // La hauteur doit etre le premier element
229  TYXMLTools::getElementDoubleValue(elemCur, "hauteur", hauteurLue, hauteurOk);
230  if (hauteurOk)
231  {
232  _hauteur = hauteurLue;
233  }
234 
235  // On cherche le repere
236  if (_repere.callFromXMLIfEqual(elemCur, &retVal))
237  {
238  // Fix #115 : Si le Repere est invalide alors on ne lit pas le GeometryNode
239  if (retVal == 1)
240  {
241  // Le prochain child (node et pas '#text')
242  // doit etre le noeud de l'element
243  nodeTmp = elemCur.nextSibling();
244 
245  // problem here with count
246  // nodeTmp = nodeTmp.nextSibling();
247 
248  // Au cas oi nbChild soit faux (trop grand)
249  if (nodeTmp.isNull())
250  {
251  break;
252  }
253 
254  // Ajout du prefixe TY
255  str = "TY";
256  str += nodeTmp.nodeName();
257 
258  // Auto construction a partir du type trouve
259  //_pElement = (TYElement *) TYElement::findAndClone((char *)str.data());//az--
260  setElement((TYElement*)TYElement::findAndClone((char*)str.toLatin1().data())); // az++
261 
262  // Si la classe a ete trouve (elle doit heriter de TYElement)
263  if (_pElement)
264  {
265  // Le parent de l'element n'est pas le GeoNode mais son parent
266  // (uniquement si le champs parent du GeoNode est renseigne)
267  if (getParent())
268  {
270  }
271 
272  // Parsing
273  _pElement->fromXML(*((DOM_Element*)&nodeTmp));
274 
275  // L'element a ete trouve et traite
276  eltFound = true;
277  }
278  }
279  }
280  }
281 
282  if (eltFound)
283  {
284  res = 1;
285  }
286 
287  return res;
288 }
289 
290 void TYGeometryNode::getChilds(LPTYElementArray& childs, bool recursif /*=true*/)
291 {
292  TYElement::getChilds(childs, recursif);
293 
294  if (_pElement)
295  {
296  _pElement->getChilds(childs, recursif);
297  }
298 }
299 
301 {
302  setElement((TYElement*)pElt);
303 }
304 
306 {
308  _pElement = pElt;
309  addToTheMap();
310 
311  setIsGeometryModified(true);
312 }
313 
315 {
316  if (_pElement)
317  {
318  GetGeoNodeMap()->erase(_pElement);
319  delete _pElement;
320  _pElement = NULL;
321  }
322 
323  setIsGeometryModified(true);
324 }
325 
327 {
328  if (this != &other)
329  {
330  TYElement::operator=(other);
331  //_pElement = other._pElement;//az--
332  setElement(other._pElement); // az++
333  _repere = other._repere;
334  _hauteur = other._hauteur;
335  }
336  return *this;
337 }
338 
340 {
341  if (this != &other)
342  {
343  if (TYElement::operator!=(other))
344  {
345  return false;
346  }
347  if (_pElement != other._pElement)
348  {
349  return false;
350  }
351  if (_repere != other._repere)
352  {
353  return false;
354  }
355  if (_hauteur != other._hauteur)
356  {
357  return false;
358  }
359  }
360  return true;
361 }
362 
364 {
365  return !operator==(other);
366 }
367 
368 bool TYGeometryNode::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
369 {
370  TYElement::deepCopy(pOther, copyId);
371  TYGeometryNode* pOtherGeoNode = NULL;
372  if (pOther)
373  {
374  pOtherGeoNode = (TYGeometryNode*)pOther;
375  }
376  if (!pOtherGeoNode || !pOtherGeoNode->getElement())
377  {
378  return false;
379  }
380 
381  // Avant de faire la deep copy sur l'element il faut s'assurer
382  // qu'ils sont de meme type
383  setElement((TYElement*)pOtherGeoNode->getElement()->clone());
384 
385  // Deep copy de l'element
386  if (!_pElement->deepCopy(pOtherGeoNode->_pElement, copyId, true))
387  {
388  return false;
389  }
390 
391  // Deep copy du repere
392  if (!_repere.deepCopy(&pOtherGeoNode->_repere, copyId))
393  {
394  return false;
395  }
396 
397  _hauteur = pOtherGeoNode->_hauteur;
398 
399  setIsGeometryModified(true);
400  setIsAcousticModified(true);
401 
402  return true;
403 }
404 
405 // XXX There seems to be excessive complexity around updateMatrix and updateRepere :
406 // setMAtrix->setPrivateMatrix->updateRepere->_repere.set(_matrix)
407 // FIXME Why this double copy of matrices while it looks like
408 // _repere.getMatChangeRep(_matrix) would be simpler and more efficient ?
410 {
411  if (GetGeoNodeMap()->find(pElement) != GetGeoNodeMap()->end())
412  {
413  return ((*GetGeoNodeMap())[pElement]);
414  }
415  return NULL;
416 }
417 
419 {
420  // 1. Element pointe par le GeoNode:
421  TYElement* pElement = getElement();
422  // 2. on s'interresse aux parents du cet element
423  TYElement* pCurrentParent = pElement->getParent();
424  while (pCurrentParent)
425  {
426  // 3. le parent est peut-etre deja un TYGeometryNode ?
427  TYGeometryNode* pPotentialGeoNode = TYGeometryNode::safeDownCast(pCurrentParent);
428  if (pPotentialGeoNode)
429  {
430  return pPotentialGeoNode;
431  }
432  // 4. le parent dispose d'un GeoNode
433  pPotentialGeoNode = GetGeoNode(pCurrentParent);
434  if (pPotentialGeoNode)
435  {
436  return pPotentialGeoNode;
437  }
438  // 5. examinons le parent du parent...
439  pCurrentParent = pCurrentParent->getParent();
440  }
441  return NULL;
442 }
443 
445 {
446  TYGeometryNode* pCurrrentGeoNodeParent = GetGeoNodeParent();
447  while (pCurrrentGeoNodeParent)
448  {
449  GetGeoNodeParents.push_back(pCurrrentGeoNodeParent);
450  pCurrrentGeoNodeParent = pCurrrentGeoNodeParent->GetGeoNodeParent();
451  }
452 }
453 
455 {
456  TYGeometryNode* pParent = GetGeoNodeParent();
457  OMatrix matrix = _repere.asMatrix();
458 
459  while (pParent != NULL)
460  {
461  matrix = pParent->getORepere3D().asMatrix() * matrix;
462  pParent = pParent->GetGeoNodeParent();
463  }
464 
465  return matrix;
466 }
467 
469 {
470  TYGeometryNode* pParent = GetGeoNodeParent();
471  OMatrix matrix = _repere.asMatrix();
472  while (pParent != NULL && pParent != pGeoNode)
473  {
474  matrix = pParent->getORepere3D().asMatrix() * matrix;
475  pParent = pParent->GetGeoNodeParent();
476  }
477  return matrix;
478 }
479 
481 {
482  return localToGlobal().getInvert();
483 }
484 
485 #if TY_USE_IHM
486 LPTYElementGraphic TYGeometryNode::getGraphicObject()
487 {
488  if (!_pGraphicObject)
489  {
491  }
492  return _pGraphicObject;
493 }
494 #endif // TY_USE_IHM
495 
497 {
498  _repere.set(matrix);
499  setIsGeometryModified(true);
500 }
501 
503 {
504  ORepere3D repere = getORepere3D();
505  repere._origin._x = pos._x;
506  repere._origin._y = pos._y;
507  repere._origin._z = pos._z;
508  setRepere(repere);
509 }
510 
512 {
513  OMatrix tyMat;
514  OMatrix tyMatTmpX;
515  OMatrix tyMatTmpY;
516  OMatrix tyMatTmpZ;
517  OMatrix tyMatTmpConcat;
518 
519  // On applique la rotation
520  double dRotateX = rot._x;
521  double dRotateY = rot._y;
522  double dRotateZ = rot._z;
523 
524  tyMatTmpX.setRotationOx(-DEGTORAD(dRotateX));
525  tyMatTmpY.setRotationOy(-DEGTORAD(dRotateY));
526  tyMatTmpZ.setRotationOz(DEGTORAD(dRotateZ));
527 
528  tyMat = tyMat * tyMatTmpZ * tyMatTmpY * tyMatTmpX * tyMatTmpConcat;
529 
530  OPoint3D org = _repere._origin; // On conserve l'origine de depart
531  _repere.set(tyMat);
532  _repere._origin = org;
533 }
534 
536 {
537  OMatrix mat = getMatrix();
538  // Get rotations from transform matrix
539  OPoint3D vec;
540  vec._x = mat._m[0][1];
541  vec._y = mat._m[1][1];
542  vec._z = mat._m[2][1];
543 
544  // Get X-vector for roll calculation
545  OPoint3D xv;
546  xv._x = mat._m[0][0];
547  xv._y = mat._m[1][0];
548  xv._z = mat._m[2][0];
549 
550  // Calculate PRH (x = pitch, y = roll, z = heading)
551  OPoint3D rotTmp(-atan2(vec._z, sqrt(vec._x * vec._x + vec._y * vec._y)), xv._z, -atan2(-vec._x, vec._y));
552 
553  // Set up vars
554  double pitch = RADTODEG(rotTmp._x); // Pitch
555  double yaw = -RADTODEG(rotTmp._z); // Heading
556  double roll = RADTODEG(rotTmp._y); // Roll
557 
558  // Affiche la boite de dialogue
559  return OPoint3D(pitch, roll, yaw);
560 }
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:345
std::map< 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:922
The 3D point class.
Definition: 3d.h:487
virtual OPrototype * clone() const =0
virtual const char * getClassName() const
Definition: TYElement.h:249
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:1211
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:1279
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:699
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:307
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:368
QString _name
Nom courant de l'element.
Definition: TYElement.h:966
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:265
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:544
LPTYElementGraphic _pGraphicObject
L'object graphique metier associe a cet element.
Definition: TYElement.h:987
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:532
void setParent(TYElement *pParent)
Definition: TYElement.h:692
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:381
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.
OMatrix localToGeoNode(TYGeometryNode *pGeoNode) const
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
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