Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYAltimetrie.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 <cmath>
19 #include <limits>
20 #include <algorithm>
21 
22 #include <boost/current_function.hpp>
23 #include <boost/foreach.hpp>
24 
25 #include "Tympan/core/logging.h"
30 #if TY_USE_IHM
33 #endif
34 #include "TYAltimetrie.h"
35 
36 #include <math.h>
38 
39 #undef min
40 #undef max
41 
42 static inline double grid_step(double nb_triangles)
43 {
44  return sqrt(nb_triangles) / 2;
45 }
46 
47 struct triangle
48 {
49  double pts[3][3];
50 };
51 
54 
55 const double TYAltimetrie::invalid_altitude = -1E5;
56 
57 TYAltimetrie::TYAltimetrie() : _isUpToDate(false)
58 {
60  initNullGrid();
61 }
62 
64 {
65  initNullGrid();
66  *this = other;
67 }
68 
70 {
71  _listFaces.clear();
73 }
74 
76 {
77  if (this != &other)
78  {
79  TYElement::operator=(other);
80  _listFaces = other._listFaces;
81  _bbox = other._bbox;
82  _isUpToDate = other._isUpToDate;
83  copyAcceleratingGrid(other);
84  }
85  return *this;
86 }
87 
88 bool TYAltimetrie::operator==(const TYAltimetrie& other) const
89 {
90  if (this != &other)
91  {
92  if (TYElement::operator!=(other))
93  {
94  return false;
95  }
96  if (!(_listFaces == other._listFaces))
97  {
98  return false;
99  }
100  }
101  return true;
102 }
103 
104 bool TYAltimetrie::operator!=(const TYAltimetrie& other) const
105 {
106  return !operator==(other);
107 }
108 
109 bool TYAltimetrie::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
110 {
111  if (!TYElement::deepCopy(pOther, copyId))
112  {
113  return false;
114  }
115 
116  const TYAltimetrie* pOtherAlt = dynamic_cast<const TYAltimetrie*>(pOther);
117  assert(pOtherAlt && "The TYElement given was no TYAltimetry.");
118 
119  _listFaces.clear();
120 
121  for (unsigned int i = 0; i < _listFaces.size(); i++)
122  {
123  TYPolygon* pNewChild = (TYPolygon*)pOtherAlt->getFace(i)->clone();
124  pNewChild->deepCopy(pOtherAlt->getFace(i), copyId);
125  addFace(pNewChild);
126  }
127 
128  _bbox = pOtherAlt->_bbox;
129 
130  copyAcceleratingGrid(*pOtherAlt);
131  for (int k = 0; k < _gridSX; k++)
132  for (int l = 0; l < _gridSY; l++)
133  {
134  size_t nbFaces = _pSortedFaces[k][l].size();
135  _pSortedFaces[k][l].reserve(nbFaces);
136  for (unsigned int m = 0; m < nbFaces; m++)
137  {
138  TYPolygon* pPolygon = _pSortedFaces[k][l].at(m).getRealPointer();
139  // We break the sharing of the TYPolygon with other
140  LPTYPolygon pNewPoly = new TYPolygon(*pPolygon);
141  _pSortedFaces[k][l].push_back(pNewPoly);
142  }
143  }
144  return true;
145 }
146 
147 std::string TYAltimetrie::toString() const
148 {
149  return "TYAltimetrie";
150 }
151 
153 {
154  DOM_Element domNewElem = TYElement::toXML(domElement);
155 
156  return domNewElem;
157 }
158 
160 {
161  TYElement::fromXML(domElement);
162 
163  return 1;
164 }
165 
166 void TYAltimetrie::exportMesh(std::deque<OPoint3D>& vertices, std::deque<OTriangle>& faces,
167  std::deque<LPTYSol>& materials)
168 {
169  assert(vertices.empty() && "'vertices' output argument must be passed empty to TYAltimetrie::exportMesh");
170  assert(faces.empty() && "'faces' output argument must be passed empty to TYAltimetrie::exportMesh");
171  assert(materials.empty() &&
172  "'materials' output argument must be passed empty to TYAltimetrie::exportMesh");
173  vertices = _vertices;
174  faces = _faces;
175  materials = _materials;
176 }
177 
178 void TYAltimetrie::plugBackTriangulation(const std::deque<OPoint3D>& vertices,
179  std::deque<OTriangle>& triangles,
180  const std::deque<LPTYSol>& materials)
181 {
182  const size_t nbTriangles = triangles.size();
183  unsigned i = 0; // Index over triangles
184  unsigned j = 0; // Index over {0, 1, 2} for vertices of triangles
185 
186  _vertices = vertices;
187  _faces = triangles;
188  _materials = materials;
189 
190  // Purge de la liste des faces
191  _listFaces.clear();
192  // Reserve le nombre d'emplacements pour les triangles
193  _listFaces.reserve(nbTriangles);
194 
195  /*
196  * This section seems to have two functions :
197  * - getting the actual coordinates of the vertices (from their indices)
198  * - computing their bounding box
199  * both of which can be better fullfiled by a preprocessing from the AltimetryBuilder
200  *
201  * TODO suppress the mesh and access directly to triangles holding BOTH
202  * their indices and vertices (by reference instead of by value ?)
203  *
204  * TODO What is the sorting for ?
205  */
206  for (i = 0; i < nbTriangles; i++)
207  {
208  // We fetch the ith triangle
209  OTriangle& oTriangle = triangles[i];
210 
211  // compute global bounding box by adding each points
212  oTriangle._A = vertices[oTriangle._p1];
213  _bbox.Enlarge(oTriangle._A);
214  oTriangle._B = vertices[oTriangle._p2];
215  _bbox.Enlarge(oTriangle._B);
216  oTriangle._C = vertices[oTriangle._p3];
217  _bbox.Enlarge(oTriangle._C);
218  }
219 
220  // Reset the grid to its new size
222 
223  if (nbTriangles == 0)
224  {
225  // TODO Is this a logic_error, invalid_data or a do-nothing degenerate case ?
226  // For now we throw after having cleaned the data structure.
227  throw tympan::invalid_data("Empty triangulation") << tympan_source_loc;
228  }
229 
230  // compute density
231  float fsx = grid_step(nbTriangles);
232  _gridSX = _gridSY = ceil(fsx);
233  assert(_gridSX > 0);
234  assert(_gridSY > 0);
238 
239  for (i = 0; i < nbTriangles; i++)
240  {
241  // Making a TYPolygon from the OTriangle
242  OTriangle& oTriangle = triangles[i];
243  // Definition du tableau de faces.
244  TYTabPoint tabPt;
245  tabPt.resize(3);
246  for (j = 0; j < 3; j++)
247  {
248  tabPt[j] = oTriangle.vertex(j);
249  }
250  LPTYPolygon pPolygon = new TYPolygon(tabPt);
251  assert(pPolygon != NULL);
252 
253  pPolygon->setConvex(true);
254  pPolygon->setParent(this);
255  _listFaces.push_back(pPolygon);
256 
257  // On rempli la grille de tri des triangles
258  // On trouve les min, max des indices des carres intersectes par le
259  // triangle sur la grille.
260  unsigned int ipmin = 0, ipmax = 0, iqmin = 0, iqmax = 0;
261  ipmin = iqmin = std::numeric_limits<unsigned int>::max();
262  ipmax = iqmax = std::numeric_limits<unsigned int>::min(); // Yes : zero for unsigned
263  for (j = 0; j < 3; j++)
264  {
265  grid_index idx;
266  // idx is an output argument
267  if (!getGridIndices(oTriangle.vertex(j), idx))
268  {
269  throw tympan::logic_error("Point out of the altimetry's bounding box")
271  };
272 
273  ipmax = std::max(ipmax, idx.pi);
274  iqmax = std::max(iqmax, idx.qi);
275  ipmin = std::min(ipmin, idx.pi);
276  iqmin = std::min(iqmin, idx.qi);
277  }
278  // Pour chacun des carres, on affecte le triangle
279  // Todo: Optim: faire le test d'intersection carre/trianle avant d'ajouter.
280  for (int k = ipmin; k <= ipmax; k++)
281  for (int l = iqmin; l <= iqmax; l++)
282  {
283  assert((k >= 0) && (l >= 0) && (k < _gridSX) && (l < _gridSY));
284  _pSortedFaces[k][l].push_back(pPolygon);
285  }
286  }
287 
288  setIsGeometryModified(false);
289 }
290 
292 {
293  assert(pFace);
294 
295  pFace->setParent(this);
296  _listFaces.push_back(pFace);
297 
298  setIsGeometryModified(true);
299 
300  return true;
301 }
302 
304 {
305  assert(pFace);
306  bool ret = false;
307  TYTabLPPolygon::iterator ite;
308 
309  for (ite = _listFaces.begin(); ite != _listFaces.end(); ite++)
310  {
311  if ((*ite) == pFace)
312  {
313  _listFaces.erase(ite);
314  ret = true;
315  break;
316  }
317  }
318 
319  setIsGeometryModified(true);
320 
321  return ret;
322 }
323 
324 bool TYAltimetrie::remFace(QString idFace)
325 {
326  bool ret = false;
327  TYTabLPPolygon::iterator ite;
328 
329  for (ite = _listFaces.begin(); ite != _listFaces.end(); ite++)
330  {
331  if ((*ite)->getID() == idFace)
332  {
333  _listFaces.erase(ite);
334  ret = true;
335  break;
336  }
337  }
338 
339  setIsGeometryModified(true);
340 
341  return ret;
342 }
343 
344 inline bool TYAltimetrie::IsInsideFace(const TYTabPoint& pts, OPoint3D& pt) const
345 {
346  if (pts.size() < 3)
347  {
348  return false;
349  } // le triangle n'est pas complet!!!!
350 
351  double x = NAN, y = NAN; // coord 2D du point
352  double xa = NAN, ya = NAN, xb = NAN, yb = NAN, xc = NAN, yc = NAN; // coord 2D des sommets du triangle
353  double bx = NAN, by = NAN, cx = NAN, cy = NAN;
354  double hx = NAN, hy = NAN;
355  double a2 = NAN, a3 = NAN;
356 
357  x = pt._x;
358  y = pt._y;
359  xa = pts[0]._x;
360  ya = pts[0]._y;
361  xb = pts[1]._x;
362  yb = pts[1]._y;
363  xc = pts[2]._x;
364  yc = pts[2]._y;
365 
366  bx = xc - xa;
367  by = yc - ya;
368  cx = xb - xa;
369  cy = yb - ya;
370  hx = x - xa;
371  hy = y - ya;
372  a2 = (bx * hy - by * hx) / (bx * cy - by * cx);
373  a3 = (hx * cy - hy * cx) / (bx * cy - by * cx);
374 
375  if (a2 < 0)
376  {
377  return false;
378  }
379  if (a3 < 0)
380  {
381  return false;
382  }
383  if (a2 + a3 > 1)
384  {
385  return false;
386  }
387 
388  return true;
389 }
390 
392 {
393  // Recherche des indices de la grilles qui incluent les sommets de la boite
394  grid_index idx;
395  bool test = getGridIndices(pt, idx);
396  if (!test)
397  {
398  return 0;
399  }
400  unsigned int pi = idx.pi, qi = idx.qi;
401 
402  TYTabLPPolygon* pDivRef = &(_pSortedFaces[pi][qi]);
403  TYPolygon* pFace = NULL;
404 
405  if (pDivRef != NULL) // sanity check
406  {
407  for (size_t i = 0; i < pDivRef->size(); i++)
408  {
409  pFace = pDivRef->at(i);
410 
411  if (pFace != NULL)
412  {
413  if (IsInsideFace(pFace->getPoints(), pt))
414  {
415  return pFace;
416  }
417  }
418  }
419  }
420 
421  return pFace;
422 }
423 
424 unsigned int TYAltimetrie::getFacesInBox(const OBox2& box, TYTabLPPolygon& tabPolygon)
425 {
426  // Recherche des indices de la grilles qui incluent les sommets de la boite
427  unsigned int iMinMax[4];
428  bool test = getGridIndices(box, iMinMax);
429  if (!test)
430  {
431  return 0;
432  }
433 
434  // Rcupration des faces correspondantes
435  TYTabLPPolygon faces;
436  getFacesinIndices(iMinMax[0], iMinMax[1], iMinMax[2], iMinMax[3], faces);
437 
438  // Test des points des faces par rapport la box
439  // Si au moins un point de la face est dans la box, la face est mise dans la liste
440  unsigned int faceCount = 0; // Compteur de faces
441  for (size_t i = 0; i < faces.size(); i++)
442  {
443  TYTabPoint& pts = faces[i]->getPoints();
444  for (size_t y = 0; y < pts.size(); y++)
445  {
446  if (box.isInside(pts[y]))
447  {
448  tabPolygon.push_back(faces[i]);
449  faceCount++;
450  continue;
451  }
452  }
453  }
454 
455  if (faceCount == 0) // Aucune face trouve
456  {
457  for (size_t i = 0; i < faces.size(); i++)
458  {
459  tabPolygon.push_back(faces[i]);
460  }
461  }
462 
463  return faceCount;
464 }
465 
466 unsigned int TYAltimetrie::getPointsInBox(const OPoint3D& pt0, const OPoint3D& pt1, const OPoint3D& pt2,
467  const OPoint3D& pt3, TYTabPoint& tabPoints)
468 {
469  unsigned int pointCount = 0;
470  OPoint3D pts[4];
471  pts[0] = pt0;
472  pts[1] = pt1;
473  pts[2] = pt2;
474  pts[3] = pt3;
475 
476  unsigned int iMinMax[4];
477 
478  bool test = getGridIndices(pts, iMinMax);
479  if (!test)
480  {
481  return 0;
482  }
483 
484  // Rcupration des faces correspondantes
485  TYTabLPPolygon faces;
486  getFacesinIndices(iMinMax[0], iMinMax[1], iMinMax[2], iMinMax[3], faces);
487 
488  // Test des points des faces par rapport la box
489  // Si le point est dans le primtre, il est ajout la liste
490  for (size_t i = 0; i < faces.size(); i++)
491  {
492  TYTabPoint& ptsFaces = faces[i]->getPoints();
493  for (size_t y = 0; y < ptsFaces.size(); y++)
494  {
495  if (OGeometrie::pointInPolygonRayCasting(ptsFaces[y], pts, 4))
496  {
497  tabPoints.push_back(ptsFaces[y]);
498  pointCount++;
499  }
500  }
501  }
502 
503  return pointCount;
504 }
505 
506 bool TYAltimetrie::getGridIndices(const OPoint3D& pt, grid_index& indXY) const
507 {
508 
509  if ((_gridDX == 0) || (_gridDY == 0))
510  {
511  // This is supposed to be an error case isn't it ? Then we should NOT return SILENTLY.
512  // but raising this exception seem to causes regression in some cases...
513  throw tympan::logic_error("No face in accelerating structure of the altimetry") << tympan_source_loc;
514  }
515  // A sanity check has to be represented by an assert, not an if silencing a failure.
516  assert(_pSortedFaces != NULL && "Sanity Check...");
517 
518  if (!_bbox.isInside2D(pt)) // si le point n'est pas dans la bounding box de l'altimetrie
519  {
520  return false;
521  // The return above preserves legacy behaviour but the exception below should be prefered
522  /*
523  throw tympan::logic_error("Point out of the altimetry's bounding box")
524  << tympan_source_loc << tympan::position_errinfo(pt);
525  */
526  }
527 
528  double p = NAN, q = NAN;
529  unsigned pi = 0, qi = 0;
530  assert(_gridDX != 0);
531  assert(_gridDY != 0);
532  p = (pt._x - _bbox._min._x) / _gridDX;
533  q = (pt._y - _bbox._min._y) / _gridDY;
534  pi = floor(p);
535  qi = floor(q);
536 
537  // In case pt lies on the top-most (resp. right-most) border of the bounding box
538  // p could be exactly _gridSX (resp. q exactly _gridSY) and this needs clipping.
539  pi = std::min(pi, _gridSX - 1);
540  qi = std::min(qi, _gridSY - 1);
541 
542  assert((pi >= 0) && (qi >= 0) && (pi < _gridSX) && (qi < _gridSY));
543 
544  indXY.pi = pi;
545  indXY.qi = qi;
546 
547  return true;
548 }
549 
550 bool TYAltimetrie::getGridIndices(const OPoint3D* pts, unsigned int* iMinMax) const
551 {
552  unsigned minX = std::numeric_limits<unsigned>::max();
553  unsigned maxX = std::numeric_limits<unsigned>::min();
554  unsigned minY = std::numeric_limits<unsigned>::max();
555  unsigned maxY = std::numeric_limits<unsigned>::min();
556 
557  // Test des quatre points et rcupration des indices
558  grid_index iXY;
559 
560  bool res = true;
561 
562  for (size_t i = 0; i < 4; i++)
563  {
564  res &= getGridIndices(pts[i], iXY);
565  minX = std::min(minX, iXY.pi);
566  minY = std::min(minY, iXY.qi);
567  maxX = std::max(maxX, iXY.pi);
568  maxY = std::max(maxY, iXY.qi);
569  }
570 
571  iMinMax[0] = minX;
572  iMinMax[1] = maxX;
573  iMinMax[2] = minY;
574  iMinMax[3] = maxY;
575 
576  return res;
577 }
578 
579 bool TYAltimetrie::getGridIndices(const OBox2& box, unsigned int* iMinMax) const
580 {
581  OPoint3D pts[4];
582 
583  for (int i = 1, j = 0; i < 5; i++, j++)
584  {
585  pts[j] = box.BoxCoord(i);
586  }
587 
588  return getGridIndices(pts, iMinMax);
589 }
590 
591 void TYAltimetrie::getFacesinIndices(unsigned int& minX, unsigned int& maxX, unsigned int& minY,
592  unsigned int& maxY, TYTabLPPolygon& faces)
593 {
594  std::map<LPTYPolygon, int> mapFaces;
595  TYTabLPPolygon* pDivRef = NULL;
596 
597  // Utilisation d'un map pour filtrer les faces
598  for (unsigned int i = minX; i <= maxX; i++)
599  {
600  for (unsigned int j = minY; j <= maxY; j++)
601  {
602  pDivRef = &(_pSortedFaces[i][j]);
603  for (size_t k = 0; k < pDivRef->size(); k++)
604  {
605  mapFaces[pDivRef->at(k)] = i * j * static_cast<int>(k);
606  }
607  }
608  }
609 
610  // Remplissage du tableau
611  std::map<LPTYPolygon, int>::iterator it;
612  for (it = mapFaces.begin(); it != mapFaces.end(); it++)
613  {
614  faces.push_back(it->first);
615  }
616 }
617 
619 {
620  OPoint3D ptTest(pt);
621  ptTest._z = invalid_altitude;
622 
623  const double M_DOUBLE_INFINITE = 1e6; // CAUTION ! Numerical instability:
624  // One could prefer using `std::numeric_limits<double>::infinity()` or
625  // `std::numeric_limits<double>::max()` but both cause the call to
626  // pFace->intersects(...) below to fail silently
627  // Using this big but no too big ad hoc 1E6 seems OK...
628 
629  grid_index idx;
630  if (!getGridIndices(pt, idx))
631  {
632  // Early termination with invalid altitude generaly due to
633  // pt being out the geometrical scope of the altimetry.
634  return ptTest;
635  }
636 
637  OSegment3D segTest;
638  TYTabLPPolygon& divRef = _pSortedFaces[idx.pi][idx.qi];
639 
640  BOOST_FOREACH (const LPTYPolygon& pFace, divRef)
641  {
642  if (IsInsideFace(pFace->getPoints(), ptTest))
643  {
644  segTest._ptA = ptTest;
645  segTest._ptB = ptTest;
646  segTest._ptA._z = +M_DOUBLE_INFINITE;
647  segTest._ptB._z = -M_DOUBLE_INFINITE;
648 
649  if (pFace->intersects(segTest, ptTest, false) == INTERS_OUI)
650  {
651  assert(ptTest._z != invalid_altitude && "Successful intersection expected");
652  return ptTest;
653  }
654  }
655  }
656  assert(ptTest._z == invalid_altitude && "invalid_altitude expected to denote failure");
657  return ptTest;
658 }
659 
661 {
662  pt = projection(pt);
663  if (pt._z == invalid_altitude)
664  {
665  /* OMessageManager::get()->warning(
666  "%s Could not compute valid altitude for point at (%f, %f)",
667  BOOST_CURRENT_FUNCTION, pt._x, pt._y);*/
668  return false;
669  }
670  return true;
671 }
672 
673 void TYAltimetrie::setIsUpToDate(bool isUpToDate)
674 {
676 }
677 
679 {
680  return projection(pt)._z;
681 }
682 
684 {
685  double dHauteurMoyenne = 0;
686  OPoint3D pt;
687  bool bOK = false;
688  int nNbHauteurs = 0;
689  for (unsigned int i = 0; i < pts.size(); i++)
690  {
691  pt = pts[i];
692  bOK = updateAltitude(pt);
693  if (bOK)
694  {
695  dHauteurMoyenne += pts.at(i)._z - pt._z;
696  nNbHauteurs++;
697  }
698  }
699  if (nNbHauteurs == 0 || dHauteurMoyenne < 0) // si l'altitude de la polyligne (info z de TYTabPoint) n'est
700  // pas passee, on renvoie une hauteur nulle
701  {
702  return 0;
703  }
704  dHauteurMoyenne /= nNbHauteurs;
705  return dHauteurMoyenne;
706 }
707 
709 {
710  // On calcule la moyenne de hauteur de tous les points de la polyligne
711  double dHauteur = 0;
712  int i = 0;
713  do
714  {
715  OPoint3D courant(0.0, 0.0, 0.0);
716  courant._x = ptsIn.at(i)._x;
717  courant._y = ptsIn.at(i)._y;
718  bool bOK = updateAltitude(courant);
719  if (!bOK)
720  {
721  return 0;
722  }
723  dHauteur = ptsIn.at(i)._z - courant._z;
724  i++;
725  } while (dHauteur < 0 && i < (int)ptsIn.size());
726  if (dHauteur < 0)
727  {
728  return 0;
729  }
730  return dHauteur;
731 }
732 
734 {
735  // Initialisation of members
736  _pSortedFaces = NULL;
737  _gridSX = 0;
738  _gridSY = 0;
739  _gridDX = 0.0f;
740  _gridDY = 0.0f;
741 }
742 
744 {
745  // clear existing grid
746  if (_pSortedFaces)
747  {
748  for (int k = 0; k < _gridSX; k++)
749  {
750  for (int l = 0; l < _gridSY; l++)
751  {
752  _pSortedFaces[k][l].clear();
753  }
754  delete[] _pSortedFaces[k];
755  }
756  delete[] _pSortedFaces;
757  }
758  initNullGrid();
759 }
760 
761 void TYAltimetrie::initAcceleratingGrid(unsigned to_be_reserved)
762 {
763  assert(_pSortedFaces == NULL && "The accelerating grid must have been cleared.");
764  assert(_gridSX && _gridSY && "The size of the grid must be positive.");
765 
767  for (int k = 0; k < _gridSX; k++)
768  {
770  for (int l = 0; l < _gridSY; l++)
771  {
772  _pSortedFaces[k][l].reserve(to_be_reserved);
773  }
774  }
775 }
776 
778 {
780 
781  _gridSX = other._gridSX;
782  _gridSY = other._gridSY;
783  _gridDX = other._gridDX;
784  _gridDY = other._gridDY;
786 
787  for (int k = 0; k < _gridSX; k++)
788  for (int l = 0; l < _gridSY; l++)
789  {
790  // This is a copy of a STL vector/deque of SmartPtr
791  _pSortedFaces[k][l] = other._pSortedFaces[k][l];
792  }
793 }
All base classes related to 3D manipulation.
#define INTERS_OUI
The intersection exists.
Definition: 3d.h:33
QDomElement DOM_Element
Definition: QT2DOM.h:30
Representation graphique de l'altimetrie (fichier header)
outil IHM pour une altimetrie (fichier header)
TY_EXTENSION_INST(TYAltimetrie)
TY_EXT_GRAPHIC_INST(TYAltimetrie)
#define min(a, b)
std::vector< TYPoint > TYTabPoint
Collection de TYPoint.
Definition: TYDefines.h:340
std::vector< LPTYPolygon > TYTabLPPolygon
Collection de pointeurs de TYPolygon.
Definition: TYDefines.h:349
Class to define a box (not necessary parallel to the axis as OBox)
Definition: 3d.h:1432
virtual bool isInside(const OPoint3D &pt) const
Test whether the point is inside the box or not.
Definition: 3d.cpp:1887
OPoint3D BoxCoord(int N) const
Returns the coordinates of one of the box corner. \ We consider that the first corner is the one on t...
Definition: 3d.cpp:1859
virtual bool isInside2D(const OPoint3D &pt) const
Test whether the point is inside the box or not (from upper point of view).
Definition: 3d.cpp:1564
virtual void Enlarge(const OPoint3D &pt)
Enlarge the box with the point if the point is outside the box.
Definition: 3d.cpp:1614
OPoint3D _min
Minimal coordinates of the OBox.
Definition: 3d.h:1423
OPoint3D _max
Maximal coordinates of the OBox.
Definition: 3d.h:1424
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
static bool pointInPolygonRayCasting(const OPoint3D &ptP, const OPoint3D *pts, int nbPts)
Tests if a point is inside a polygon using ray casting algorithm.
Definition: 3d.cpp:1046
The 3D point class.
Definition: 3d.h:487
virtual OPrototype * clone() const =0
virtual const char * getClassName() const
Definition: TYElement.h:248
Class to define a segment.
Definition: 3d.h:1141
OPoint3D _ptA
Point A of the segment.
Definition: 3d.h:1253
OPoint3D _ptB
Point B of the segment.
Definition: 3d.h:1255
Triangle class.
Definition: triangle.h:28
OPoint3D _A
First OPoint3D.
Definition: triangle.h:53
int _p1
Index of the first OPoint3D _A.
Definition: triangle.h:49
int _p3
Index of the third OPoint3D _C.
Definition: triangle.h:51
OPoint3D _C
Third OPoint3D.
Definition: triangle.h:55
OPoint3D _B
Second OPoint3D.
Definition: triangle.h:54
int _p2
Index of the second OPoint3D _B.
Definition: triangle.h:50
OPoint3D & vertex(unsigned i)
Get the OPoint3D from the specific index.
Definition: triangle.cpp:26
Assigne une altitude a chaque point de l'espace.
Definition: TYAltimetrie.h:35
void copyAcceleratingGrid(const TYAltimetrie &other)
Clear the grid and reinitialise it as a copy of other.
static const double invalid_altitude
Definition: TYAltimetrie.h:42
virtual ~TYAltimetrie()
LPTYPolygon getFace(int index)
Definition: TYAltimetrie.h:163
double PremiereHauteurPositiveOuNulle(TYTabPoint &ptsIn)
void exportMesh(std::deque< OPoint3D > &vertices, std::deque< OTriangle > &faces, std::deque< LPTYSol > &materials)
bool operator!=(const TYAltimetrie &other) const
Operateur !=.
double HauteurMoyenne(TYTabPoint &pts)
std::deque< LPTYSol > _materials
Definition: TYAltimetrie.h:325
bool operator==(const TYAltimetrie &other) const
Operateur ==.
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
TYTabLPPolygon ** _pSortedFaces
Definition: TYAltimetrie.h:312
void clearAcceleratingGrid()
clean the accelerating structure
bool addFace(LPTYPolygon pFace)
double _gridDY
Definition: TYAltimetrie.h:320
void initNullGrid()
Initilise the grid related attributes for a null grid.
virtual DOM_Element toXML(DOM_Element &domElement)
void getFacesinIndices(unsigned int &minX, unsigned int &maxX, unsigned int &minY, unsigned int &maxY, TYTabLPPolygon &faces)
Select faces in the interval minX, maxX, minY, maxY.
TYAltimetrie & operator=(const TYAltimetrie &other)
Operateur =.
bool getGridIndices(const OPoint3D &pt, grid_index &indXY) const
Select indices of faces to test.
OBox _bbox
Bounding Box 2D de l'altimetrie.
Definition: TYAltimetrie.h:295
unsigned int getPointsInBox(const OPoint3D &pt0, const OPoint3D &pt1, const OPoint3D &pt2, const OPoint3D &pt3, TYTabPoint &tabPolygon)
find a list of point included in a box defined by four points
OPoint3D projection(const OPoint3D &pt) const
Calcule les coordonnees de la projection au sol d'un point de l'espace.
LPTYPolygon getFaceUnder(OPoint3D pt)
Return the face under a point.
bool isUpToDate() const
Definition: TYAltimetrie.h:176
unsigned _gridSY
Definition: TYAltimetrie.h:316
unsigned int getFacesInBox(const OBox2 &box, TYTabLPPolygon &tabPolygon)
find a list of triangle partialy or totaly included in a box
double altitude(const OPoint3D &pt)
virtual int fromXML(DOM_Element domElement)
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...
bool remFace(const LPTYPolygon pFace)
bool IsInsideFace(const TYTabPoint &pts, OPoint3D &pt) const
void plugBackTriangulation(const std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const std::deque< LPTYSol > &materials)
plug back triangulation providfed by the TYTopographie
unsigned _gridSX
Size along each dimension of the accelerating grid.
Definition: TYAltimetrie.h:315
bool _isUpToDate
Indique si l'altimétrie est cohérente avec les données du modèle.
Definition: TYAltimetrie.h:329
double _gridDX
Step along each dimension of the accelerating grid.
Definition: TYAltimetrie.h:319
std::deque< OTriangle > _faces
Definition: TYAltimetrie.h:324
void initAcceleratingGrid(unsigned to_be_reserved=0)
initialise the accelerating structure given current _bbox and _gridS{XY}
void setIsUpToDate(bool isUpToDate)
TYTabLPPolygon _listFaces
Liste des polygones correspondant aux faces de cet altimetrie.
Definition: TYAltimetrie.h:292
std::deque< OPoint3D > _vertices
Definition: TYAltimetrie.h:323
virtual std::string toString() const
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
void setParent(TYElement *pParent)
Definition: TYElement.h:690
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:379
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
QString generateName(const char *classname)
Retourne le nom de la classe associe a un nombre.
static TYNameManager * get()
Retourne l'instance singleton.
const TYTabPoint & getPoints() const
Definition: TYPolygon.h:123
void setConvex(bool bConvex)
Definition: TYPolygon.h:145
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYPolygon.cpp:112
virtual int intersects(const TYSurfaceInterface *pSurf, OSegment3D &seg) const
Definition: TYPolygon.cpp:271
#define tympan_source_loc
This macro build a source_loc object to be attached to a tympan::Exception.
Definition: exceptions.h:91
boost::error_info< struct tag_position, OPoint3D > position_errinfo
Definition: exceptions.h:31
Integer coordinates into the grid.
Definition: TYAltimetrie.h:244
double pts[3][3]
The base exception class for errors due to invalid data.
Definition: exceptions.h:75
The base exception class for internal logic / algorithmic errors.
Definition: exceptions.h:68