Code_TYMPAN  4.4.0
Industrial site acoustic simulation
DefaultEngine.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 #include <stack>
17 #include <list>
18 #include <algorithm>
19 #include <vector>
20 
21 #include "Geometry/mathlib.h"
22 #include "Acoustic/Event.h"
23 #include "Ray/Ray.h"
24 #include "DefaultEngine.h"
25 
26 /*struct CompareVec
27 {
28  bool operator()(std::vector<unsigned int> list1, std::vector<unsigned int> list2) const
29  {
30  //On compare jusqu'a ce qu'on atteigne le bout du plus petit vecteur
31  int minSize = min(list1.size(), list2.size());
32  for (int i = 0; i < minSize; i++)
33  {
34  if (list1.at(i) < list2.at(i))
35  {
36  return true;
37  }
38  else if (list1.at(i) == list2.at(i))
39  {
40  continue;
41  }
42  else
43  {
44  return false;
45  }
46  }
47  //Si les vecteurs ont la meme taille, c'est qu'ils sont egaux
48  if (list1.size() == list2.size())
49  {
50  return false;
51  }
52  //La list avec la plus grande taille est superieure a l'autre
53  if (list1.size() < list2.size())
54  {
55  return true;
56  }
57  return false;
58  }
59 } myCompare ;*/
60 
62 {
63  std::size_t max_size(0);
64 
65  // QTime time;
66  // time.start();
67  nbRayonsTraites = 0;
68 
69  // Throw ray from every source to every receptor
71 
72  // Loop until the end of the simulation (i.e. when the stack of rays is empty and the sources cannot
73  // generate more rays)
74  while (1)
75  {
76  // Empty stack => we generate a new ray from the sources
77  if (pile_traitement.empty())
78  {
79  Ray* newRay = genRay();
80  if (newRay)
81  {
82 
83  pile_traitement.push(newRay);
84  }
85 
86  // Sources have generated all their rays => finish the simulation
87  if (pile_traitement.empty())
88  {
89  solver->finish();
90 
91  return true;
92  }
93  }
94  else
95  {
96  // Recover the ray a the top of the stack
97  Ray* current_ray = pile_traitement.top();
98  pile_traitement.pop();
99 
100  std::list<validRay> result;
101 
102  // Process the current ray and put the resulting rays in result
103  traitementRay(current_ray, result);
104 
105  // Go through the rays in resulting from the call of traitementRay
106  for (std::list<validRay>::iterator it = result.begin(); it != result.end(); it++)
107  {
108  bool currentValid = it->valid;
109  Ray* currentValidRay = it->r;
110 
111  // If the ray is not valid we invalid it (delete or put in the debug_rays list if the
112  // KeepDebugRay option is set to true)
113  if (!currentValid)
114  {
115  solver->invalidRayon(currentValidRay);
116  }
117  else
118  {
119  // The ray is valid (but has yet to hit a receptor) => put it back in the stack for
120  // further processing
121  pile_traitement.push(currentValidRay);
122  if (pile_traitement.size() > max_size)
123  {
124  max_size = pile_traitement.size();
125  }
126  }
127  }
128  }
129  }
130 }
131 
133 {
134 
135  for (unsigned int i = 0; i < sources->size(); i++)
136  {
137  if (sources->at(i).getNbRayLeft() > 0)
138  {
139  // Generate a ray from the current source(i)
140  Ray* new_ray = new Ray();
141  new_ray->setConstructId(rayCounter);
142  rayCounter++;
143  new_ray->setSource((&(sources->at(i))));
144  new_ray->setPosition(sources->at(i).getPosition());
145  vec3 direction;
146  sources->at(i).getDirection(direction);
147  new_ray->setDirection(direction);
148  new_ray->setMint(0.);
149  new_ray->setMaxt(10000.);
150  return new_ray;
151  }
152  }
153 
154  return (Ray*)NULL;
155 }
156 
157 bool DefaultEngine::traitementRay(Ray* r, std::list<validRay>& result)
158 {
159  nbRayonsTraites++; // Number of rays processed during the simulation
160 
161  // Handle diffraction events: (reflexion events only have one possible response and it is consumed during
162  // their validation in valideIntersection) If the last event of the current ray still has reponses left,
163  // copy the ray and use the next response to generate a new direction for the copy and then add the copy
164  // to the stack. The reason rays generated by diffraction events are handled in this way instead of
165  // generating all responses when the intersection is validated is to avoid flooding the rays' stack.
166  // Indeed, in this way, each response is handled individually and needs to be processed before the next
167  // response is generated. Hence, for a particular diffraction event, only one of the rays it generates can
168  // be present in the stack at a given time.
169  if (!(r->getEvents()->empty()) && (r->getEvents()->back()->isReponseLeft()))
170  {
172  }
173 
174  decimal tmin = -1.0f;
175 
176  // Get the solver's accelerating structure
177  Accelerator* accelerator = scene->getAccelerator();
178  std::list<Intersection> foundPrims;
179 
180  // Find intersections with the scene's primitives
181  tmin = accelerator->traverse(r, foundPrims);
182 
183  // Check for intersections with receptors (and pass the ray to the selector manager for validation if it
184  // hits a receptor)
185  searchForReceptor(tmin, r);
186 
187  // Intersections' validation.
188 
189  if (foundPrims.size() == 0)
190  {
191  // if no intersection found => return the current ray 'r' as an invalid validRay;
192  validRay resultRay;
193  resultRay.r = r;
194  resultRay.valid = false;
195  result.push_back(resultRay);
196  }
197  else
198  {
199  // if some intersections have been found, iterate through them and test their validity
200  for (std::list<Intersection, std::allocator<Intersection>>::iterator it = foundPrims.begin();
201  it != foundPrims.end(); it++)
202  {
203 
204  bool valide = false;
205  Intersection* inter = NULL;
206  Ray* current_ray = NULL;
207 
208  if (next(it) != foundPrims.end())
209  {
210  // if the current intersection is NOT the last one, copy the current ray
211  current_ray = new Ray(r);
212  current_ray->setConstructId(rayCounter);
213  rayCounter++;
214  }
215  else
216  {
217  // if the current intersection is the last one, validate the current ray 'r' directly without
218  // copying it.
219  current_ray = r;
220  }
221 
222  // retrieve the intersection and validate it
223  inter = &(*(it));
224  valide = solver->valideIntersection(current_ray, inter);
225 
226  // create a validRay to return the result of the intersection validation
227  validRay resultRay;
228  resultRay.r = current_ray;
229  resultRay.valid = valide;
230  result.push_back(resultRay);
231  }
232  }
233 
234  return true;
235 }
236 
238 {
239 
240  unsigned int nbVec = 1000000;
241 
242  // Generation du buffer de vecteur
243  BBox sceneBox = scene->getGlobalBox();
244  /*std::vector<vec3> buffer = std::vector<vec3>(2*nbVec);
245  for(unsigned int i = 0; i < nbVec; i++){
246  vec3 newDir = vec3((double)rand() / (double)RAND_MAX, (double)rand() / (double)RAND_MAX,
247  (double)rand() / (double)RAND_MAX); newDir.normalize(); buffer.push_back(newDir); vec3 newPos =
248  vec3(((double)rand() / (double)RAND_MAX) * (sceneBox.pMax.x - sceneBox.pMin.x) + sceneBox.pMin.x,
249  ((double)rand() / (double)RAND_MAX) * (sceneBox.pMax.y - sceneBox.pMin.y) +
250  sceneBox.pMin.y,
251  ((double)rand() / (double)RAND_MAX) * (sceneBox.pMax.z - sceneBox.pMin.z) +
252  sceneBox.pMin.z); buffer.push_back(newPos);
253  }*/
254 
255  // QTime time;
256  // time.start();
257 
258  for (unsigned int i = 0; i < nbVec; i++)
259  {
260  Ray r;
261  r.setMint(0.00001f);
262  r.setMaxt(10000.);
263  r.setDirection(vec3((decimal)rand() / (decimal)RAND_MAX, (decimal)rand() / (decimal)RAND_MAX,
264  (decimal)rand() / (decimal)RAND_MAX));
265  r.getDirection().normalize();
266  r.setPosition(vec3(
267  ((decimal)rand() / (decimal)RAND_MAX) * (sceneBox.pMax.x - sceneBox.pMin.x) + sceneBox.pMin.x,
268  ((decimal)rand() / (decimal)RAND_MAX) * (sceneBox.pMax.y - sceneBox.pMin.y) + sceneBox.pMin.y,
269  ((decimal)rand() / (decimal)RAND_MAX) * (sceneBox.pMax.z - sceneBox.pMin.z) + sceneBox.pMin.z));
270  Accelerator* accel = scene->getAccelerator();
271  std::list<Intersection> foundPrims;
272  accel->traverse(&r, foundPrims);
273  }
274 
275  // int totalTime = time.elapsed();
276  // std::cout << "Fin du benchmark." << std::endl;
277  // std::cout << "Nombre de rayons traites : " << nbVec << std::endl;
278  // std::cout << "Temps ecoule : " << totalTime << " ms." << std::endl;
279  // std::cout << "Vitesse de traitement : " << nbVec / totalTime << " rays/ms." << std::endl;
280 }
Base class for accelerators.
Definition: Accelerator.h:27
virtual decimal traverse(Ray *r, std::list< Intersection > &result) const
Run this accelerator.
Definition: Accelerator.h:68
Definition of a bounding box which is aligned along the axis (BBox AABB).
Definition: BBox.h:32
vec3 pMax
Upper point of the BBox.
Definition: BBox.h:36
vec3 pMin
Lower point of the BBox.
Definition: BBox.h:35
virtual bool process()
If implemented, process and return true if success.
std::stack< Ray *, std::deque< Ray * > > pile_traitement
Treatment stack containing the rays to treat.
void searchForReceptor(const decimal &tmin, Ray *r)
Search if a ray intersects a receptor before traveling a tmin distance (NB: this is the only place in...
Definition: DefaultEngine.h:64
void copyRayAndAddToStack(Ray *r)
Copy a ray and use its last event to generate a response to use as the copy's direction (used to hand...
unsigned long long int nbRayonsTraites
Treated rays number.
void initialReceptorTargeting()
Initialize the rays treatment stack by a loop on the receptors.
virtual bool traitementRay(Ray *r, std::list< validRay > &result)
Ray treatment method.
virtual void runStructureBenchmark()
If implemented, run a benchmark for the engine.
Ray * genRay()
Create rays from the sources.
Scene * scene
Pointer to the scene.
Definition: Engine.h:103
Solver * solver
Pointer to the solver.
Definition: Engine.h:106
unsigned long long int rayCounter
Ray counter.
Definition: Engine.h:108
std::vector< Source > * sources
Pointer to all the receptors.
Definition: Engine.h:104
: Describes a ray by a pair of unsigned int. The first one gives the source number (in the range 0-40...
Definition: Ray.h:38
void setDirection(vec3 _direction)
set the direction if the ray
Definition: Ray.h:376
void setPosition(vec3 _position)
set the starting point ray
Definition: Ray.h:366
vec3 getDirection() const
Return direction of the ray.
Definition: Ray.h:346
void setMaxt(decimal _maxt)
set the maxt
Definition: Ray.h:406
void setSource(Source *_source)
set the pointer to the source of the ray
Definition: Ray.h:416
void setMint(decimal _mint)
set the Mint
Definition: Ray.h:396
void setConstructId(unsigned long long int _constructId)
set the ray id
Definition: Ray.h:446
std::vector< boost::shared_ptr< Event > > * getEvents()
Return the events array encountered by the ray.
Definition: Ray.h:195
Accelerator * getAccelerator() const
Get the accelerator.
Definition: Scene.h:82
BBox getGlobalBox()
Return global bounding box.
Definition: Scene.h:77
virtual bool valideIntersection(Ray *r, Intersection *inter)
Validation function for an intersection. If the intersection is validated, an event is created and ad...
Definition: Solver.cpp:43
virtual bool invalidRayon(Ray *r)
Method to arrange the invalid rays. The invalid rays are put away into a debug_ray array in order to ...
Definition: Solver.cpp:70
virtual void finish()
End the operations.
Definition: Solver.cpp:65
float decimal
Definition: mathlib.h:45
base_vec3< decimal > vec3
Definition: mathlib.h:381
Intersection struct.
Definition: Shape.h:46
bool valid
Boolean set to True if the ray is validated, which means an event occurs.
Definition: Engine.h:29
Ray * r
Pointer to a ray. Should not be NULL.
Definition: Engine.h:28