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