Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYFaceSelector.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/defines.h"
23 #include "TYFaceSelector.h"
24 
26 
28 
29 void TYFaceSelector::selectFaces(std::deque<TYSIntersection>& tabIntersect,
30  const std::vector<TYStructSurfIntersect>& tabPolygon,
31  const OSegment3D& rayon, const string& sourceVolumeId)
32 {
33  // Construction of cutting planes
34  TYSPlan plan[2];
35  buildPlans(plan, rayon);
36 
37  size_t nbFaces = tabPolygon.size();
38 
39  // Test faces which cut vertical plane
40  for (unsigned i = 0; i < nbFaces; i++)
41  {
42  const TYStructSurfIntersect& SI = tabPolygon[i];
43 
44  // FIX issue #18 (obstacles are not detected correctly)
45  if ((SI.volume_id.size() != 0) && (sourceVolumeId.size() != 0))
46  {
47  if ((SI.volume_id == sourceVolumeId) || (SI.tabPoint.size() == 0))
48  {
49  continue;
50  }
51  }
52 
53  // Vertical plane = 0 / Horizontal plane = 1
54  TYSIntersection intersection;
55  intersection.noIntersect = false;
56  intersection.isInfra = SI.is_infra();
57  intersection.isEcran = intersection.isInfra;
58 
59  bool bVertical = CalculSegmentCoupe(SI, intersection, plan[0].pt1, plan[0].pt2, plan[0].pt3, 0);
60  bool bHorizontal = CalculSegmentCoupe(SI, intersection, plan[1].pt1, plan[1].pt2, plan[1].pt3, 1);
61 
62  if (bVertical || bHorizontal)
63  {
64  tabIntersect.push_back(intersection);
65  }
66  }
67 
68  reorder_intersect(tabIntersect); // Put infrastructure elements on top
69 }
70 
71 void TYFaceSelector::reorder_intersect(std::deque<TYSIntersection>& tabIntersect)
72 {
73  std::deque<unsigned int> indices;
74  std::deque<TYSIntersection> temp;
75 
76  // 1 st pass : put infrastructure on top
77  for (size_t i = 0; i < tabIntersect.size(); i++)
78  {
79  if (tabIntersect[i].isInfra)
80  {
81  temp.push_back(tabIntersect[i]);
82  }
83  else
84  {
85  indices.push_back(static_cast<unsigned int>(i));
86  }
87  }
88 
89  // 2nd pass : put remainings after
90  for (size_t i = 0; i < indices.size(); i++)
91  {
92  temp.push_back(tabIntersect[indices[i]]);
93  }
94 
95  // last : replace tabIntersect
96  tabIntersect = temp;
97 }
98 
100 {
101  double planOffset = 10.0;
102  TYSPlan tmpPlan;
103  tmpPlan.pt1 = rayon._ptA;
104  tmpPlan.pt2 = rayon._ptB;
105 
106  // Construction of vertical plane
107  // 3rd point is obtained by copying 1st one and changing z coordinate
108  tmpPlan.pt3 = tmpPlan.pt1;
109  tmpPlan.pt3._z += planOffset;
110 
111  // If A and B coincide (in 2D) on the plane we want to create
112  if ((tmpPlan.pt1._x == tmpPlan.pt2._x) && (tmpPlan.pt1._y == tmpPlan.pt2._y))
113  {
114  // Then move point 2 in order to build an arbitrary valid plane
115  tmpPlan.pt2._x += planOffset;
116  tmpPlan.pt2._y += planOffset;
117  }
118 
119  plan[0] = tmpPlan;
120 
121  // Construction of horizontal plane
122  tmpPlan.pt1 = rayon._ptA;
123  tmpPlan.pt2 = rayon._ptB;
124 
125  if (tmpPlan.pt2._x != tmpPlan.pt1._x)
126  {
127  tmpPlan.pt3._z = tmpPlan.pt1._z;
128  tmpPlan.pt3._y = tmpPlan.pt1._y + planOffset;
129  tmpPlan.pt3._x =
130  ((tmpPlan.pt1._y - tmpPlan.pt2._y) * planOffset / (tmpPlan.pt2._x - tmpPlan.pt1._x)) +
131  (tmpPlan.pt1._x);
132  }
133  else if (tmpPlan.pt1._y != tmpPlan.pt2._y)
134  {
135  tmpPlan.pt3._z = tmpPlan.pt1._z;
136  tmpPlan.pt3._x = tmpPlan.pt1._x + planOffset;
137  tmpPlan.pt3._y =
138  ((tmpPlan.pt2._x - tmpPlan.pt1._x) * planOffset / (tmpPlan.pt1._y - tmpPlan.pt2._y)) +
139  (tmpPlan.pt1._y);
140  }
141  else if (tmpPlan.pt1._z != tmpPlan.pt2._z)
142  {
143  tmpPlan.pt3._y = tmpPlan.pt1._y;
144  tmpPlan.pt3._x = tmpPlan.pt1._x + planOffset;
145  tmpPlan.pt3._z =
146  ((tmpPlan.pt2._x - tmpPlan.pt1._x) * planOffset / (tmpPlan.pt1._z - tmpPlan.pt2._z)) +
147  (tmpPlan.pt1._z);
148  }
149  else
150  {
151  return false;
152  }
153 
154  plan[1] = tmpPlan;
155 
156  return true;
157 }
158 
160  OPoint3D& pt1, OPoint3D& pt2, OPoint3D& pt3, const int& indice) const
161 {
162  bool bRes = false;
163  Intersect.bIntersect[indice] = false;
164 
165  OSegment3D segInter;
166  OPlan planRayon(pt1, pt2, pt3);
167  if (planRayon.intersectsSurface(FaceCourante.tabPoint, segInter))
168  {
169  Intersect.bIntersect[indice] = true;
170  Intersect.segInter[indice] = segInter;
171  Intersect.material = FaceCourante.material;
172  bRes = true;
173  }
174 
175  return bRes;
176 }
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
Plan defined by its equation : ax+by+cz+d=0.
Definition: plan.h:31
int intersectsSurface(const TabPoint3D &contour, OSegment3D &segment) const
Compute intersection between a plan and a surface defined by his bounds.
Definition: plan.cpp:322
The 3D point class.
Definition: 3d.h:487
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
virtual void selectFaces(std::deque< TYSIntersection > &tabIntersect, const std::vector< TYStructSurfIntersect > &tabPolygon, const OSegment3D &rayon, const string &sourceVolumeId)
Build the array of intersections.
virtual ~TYFaceSelector()
bool buildPlans(TYSPlan *plan, const OSegment3D &rayon)
bool CalculSegmentCoupe(const TYStructSurfIntersect &FaceCourante, TYSIntersection &Intersect, OPoint3D &pt1, OPoint3D &pt2, OPoint3D &pt3, const int &indice) const
void reorder_intersect(std::deque< TYSIntersection > &tabIntersect)
put infrastructure faces on top
This file provides the declaration of the entities of the model, which inherit from BaseEntity.
Data structure for intersections.
bool isInfra
Flag to define if is a infrastructure face.
bool bIntersect[2]
Flag to indicate the face cuts vertical plane ([0]) or horizontal plane ([1])
bool isEcran
Flag to define if is a screen face.
OSegment3D segInter[2]
bool noIntersect
Flag to indicate that the face should not be tested for intersection.
tympan::AcousticMaterialBase * material
Pointer to a material.
Structure to describe a plan defined with 3 points.
OPoint3D pt3
OPoint3D pt1
OPoint3D pt2
Describe surface intersections.
tympan::AcousticMaterialBase * material
Reference to a material.
string volume_id
Volume id.
TabPoint3D tabPoint
Array of points used for the preselection.
bool is_infra() const
Detect if a face is on a infrastructure (has a material)