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