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 TYTrajet& rayon)
32 {
33 
34  // Construction des plans de coupe
35  TYSPlan plan[2];
36  OSegment3D seg;
37  rayon.getPtSetPtRfromOSeg3D(seg);
38  buildPlans(plan, seg);
39 
40  size_t nbFaces = _solver.getTabPolygon().size();
41 
42  // Recuperation de l'ID de la source
43  const string source_id = rayon.asrc.volume_id;
44 
45  // Test des faces qui coupent le plan vertical
46  for (unsigned i = 0; i < nbFaces; i++)
47  {
49 
50  // FIX issue #18 (obstacles are not detected correctly)
51  if ((SI.volume_id.size() != 0) && (source_id.size() != 0))
52  {
53  if ((SI.volume_id == source_id) || (SI.tabPoint.size() == 0))
54  {
55  continue;
56  }
57  }
58 
59  // Plan vertical = 0 / Plan horizontal = 1
60  TYSIntersection intersection;
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 
101 bool TYFaceSelector::buildPlans(TYSPlan* plan, const OSegment3D& rayon)
102 {
103  double planOffset = 10.0;
104  TYSPlan tmpPlan;
105  tmpPlan.pt1 = rayon._ptA;
106  tmpPlan.pt2 = rayon._ptB;
107 
108  // Construction du plan vertical
109  // 3eme point simplement en copiant le 1er et changeant l'alti
110  tmpPlan.pt3 = tmpPlan.pt1;
111  tmpPlan.pt3._z += planOffset;
112 
113  // Si A et B sont confondus (en 2D) sur le plan que l'on souhaite creer
114  if ((tmpPlan.pt1._x == tmpPlan.pt2._x) && (tmpPlan.pt1._y == tmpPlan.pt2._y))
115  {
116  // On deplace le point 2 pour choisir un plan arbitraire valide
117  tmpPlan.pt2._x += planOffset;
118  tmpPlan.pt2._y += planOffset;
119  }
120 
121  plan[0] = tmpPlan;
122 
123  // Construction du plan horizontal
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.isInfra = false;
166  Intersect.isEcran = false;
167  Intersect.noIntersect = false;
168  Intersect.bIntersect[indice] = false;
169 
170  OSegment3D segInter;
171  OPlan planRayon(pt1, pt2, pt3);
172  if (planRayon.intersectsSurface(FaceCourante.tabPoint, segInter))
173  {
174  Intersect.bIntersect[indice] = true;
175  Intersect.segInter[indice] = segInter;
176  Intersect.isInfra = FaceCourante.is_infra();
177  Intersect.isEcran = Intersect.isInfra;
178  Intersect.material = FaceCourante.material;
179  bRes = true;
180  }
181 
182  return bRes;
183 }
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
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 class TYTrajet (journey) links a couple Source-Receptor and a collection of paths,...
Definition: TYTrajet.h:35
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
Definition: TYTrajet.h:175
tympan::AcousticSource & asrc
Business source.
Definition: TYTrajet.h:225
string volume_id
Volume id.
Definition: entities.hpp:376
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)