Helios++
Helios software for LiDAR simulations
GroveTest.h
1 #pragma once
2 
3 #include <BaseTest.h>
4 #include <KDGrove.h>
5 #include <GroveKDTreeRaycaster.h>
6 #include <Primitive.h>
7 #include <Triangle.h>
8 #include <FastSAHKDTreeFactory.h>
9 
10 #include <vector>
11 #include <memory>
12 
13 namespace HeliosTests{
14 
20 class GroveTest : public BaseTest{
21 protected:
22  // *** ATTRIBUTES *** //
23  // ******************** //
31  std::vector<std::shared_ptr<GroveKDTreeRaycaster>> trees;
35  std::vector<std::vector<Primitive *>> primitives;
36 
37 
38 public:
39  // *** CONSTRUCTOR *** //
40  // ********************* //
41  GroveTest() : BaseTest("Grove test"){}
42  virtual ~GroveTest(){
43  // Release primitives
44  for(std::vector<Primitive *> &triangles : primitives){
45  for(Primitive * triangle : triangles){
46  delete ((Triangle *)triangle);
47  }
48  }
49  }
50 
51  // *** R U N *** //
52  // *************** //
56  bool run() override;
57 
58 protected:
59  // *** SUB-TESTS *** //
60  // ******************* //
65  bool testLoops();
70  bool testObserving();
71 
72  // *** UTILS *** //
73  // *************** //
78  void buildPrimitives();
83  void buildTrees();
88  void buildGrove();
89 };
90 
91 // *** R U N *** //
92 // *************** //
94  // Prepare tests
96  buildTrees();
97  buildGrove();
98 
99  // Do tests
100  if(!testLoops()) return false;
101  if(!testObserving()) return false;
102 
103  // All tests were successful
104  return true;
105 }
106 
107 // *** SUB-TESTS *** //
108 // ******************* //
110  // Prepare tests
111  size_t i, j, iMax, m;
112 
113  // For loop test
114  m = kdg.getNumTrees();
115  for(j = 0 ; j < 3 ; ++j){ // Loop 3 times over grove
116  for(i = 0, iMax = 0 ; i < m ; ++i){ // For loop over grove
117  if(trees[i] != kdg[i]) return false;
118  if(i > iMax) iMax = i;
119  }
120  }
121  if(iMax!=m-1 || m!=trees.size()) return false;
122 
123  // While loop test
124  for(j=0 ; j < 3 ; ++j){ // Loop 3 times over grove
125  i = 0;
126  kdg.toZeroTree(); // Start/restart while loop over grove
127  while(kdg.hasNextTree()){ // While loop over grove
128  if(trees[i] != kdg.nextTreeShared()) return false;
129  ++i;
130  }
131  }
132  if(i!=m) return false;
133 
134  // For-each loop test
135  for(j=0 ; j < 3 ; ++j){ // Loop 3 times over grove
136  i = 0;
137  for(std::shared_ptr<GroveKDTreeRaycaster> gkdt : kdg){ // For-each grov
138  if(trees[i] != gkdt) return false;
139  ++i;
140  }
141  }
142  if(i!=m) return false;
143 
144  // Loop tests passed
145  return true;
146 }
147 
149  // Prepare
150  std::shared_ptr<GroveKDTreeRaycaster> tree = kdg.getTreeShared(0);
151  DynMovingObject dmo1("dmo1");
152  DynMovingObject dmo2("dmo2");
153 
154  // Add dmo1, dmo2 and validate
155  kdg.addSubject(&dmo1, tree);
156  kdg.addSubject(&dmo2, tree);
157  if(((DynMovingObject *)kdg.getSubjects()[4])->getId() != "dmo1")
158  return false;
159  if(((DynMovingObject *)kdg.getSubjects()[5])->getId() != "dmo2")
160  return false;
161 
162  // Remove dmo1 and validate
163  kdg.removeSubject(&dmo1);
164  if(((DynMovingObject *)kdg.getSubjects()[4])->getId() != "dmo2")
165  return false;
166 
167  // Remove dmo2 and validate
168  kdg.removeSubject(&dmo2);
169  if(kdg.getSubjects().size() > 4) return false;
170 
171  // Observing test passed
172  return true;
173 }
174 
175 // *** UTILS *** //
176 // *************** //
178  // Primitives for first tree
179  std::vector<Primitive *> triangles1;
180  triangles1.push_back(new Triangle(
181  Vertex(-1, -1, -1),
182  Vertex(1, -1, -1),
183  Vertex(0, 1, -1)
184  ));
185  triangles1.push_back(new Triangle(
186  Vertex(-1, -1, -1),
187  Vertex(1, -1, -1),
188  Vertex(0, 0, 1)
189  ));
190  triangles1.push_back(new Triangle(
191  Vertex(1, -1, -1),
192  Vertex(0, 0, 1),
193  Vertex(0, 1, -1)
194  ));
195  triangles1.push_back(new Triangle(
196  Vertex(0, 1, -1),
197  Vertex(0, 0, 1),
198  Vertex(-1,-1, -1)
199  ));
200  primitives.push_back(triangles1);
201 
202  // Primitives for second tree
203  std::vector<Primitive *> triangles2;
204  triangles2.push_back(new Triangle(
205  Vertex(0, 0, -1),
206  Vertex(2, 0, -1),
207  Vertex(1, 2, -1)
208  ));
209  triangles2.push_back(new Triangle(
210  Vertex(0, 0, -1),
211  Vertex(2, 0, -1),
212  Vertex(1, 1, 1)
213  ));
214  triangles2.push_back(new Triangle(
215  Vertex(2, 0, -1),
216  Vertex(1, 1, 1),
217  Vertex(1, 2, -1)
218  ));
219  triangles2.push_back(new Triangle(
220  Vertex(1, 2, -1),
221  Vertex(1, 1, 1),
222  Vertex(0, 0, -1)
223  ));
224  primitives.push_back(triangles2);
225 
226  // Primitives for third tree
227  std::vector<Primitive *> triangles3;
228  triangles3.push_back(new Triangle(
229  Vertex(4, 4, -1),
230  Vertex(6, 4, -1),
231  Vertex(5, 6, -1)
232  ));
233  triangles3.push_back(new Triangle(
234  Vertex(4, 4, -1),
235  Vertex(6, 4, -1),
236  Vertex(5, 5, 1)
237  ));
238  triangles3.push_back(new Triangle(
239  Vertex(6, 4, -1),
240  Vertex(5, 5, 1),
241  Vertex(5, 6, -1)
242  ));
243  triangles3.push_back(new Triangle(
244  Vertex(5, 6, -1),
245  Vertex(5, 5, 1),
246  Vertex(4, 4, -1)
247  ));
248  primitives.push_back(triangles3);
249 
250  // Primitives for fourth tree
251  std::vector<Primitive *> triangles4;
252  triangles4.push_back(new Triangle(
253  Vertex(9, 9, 0),
254  Vertex(11, 9, 0),
255  Vertex(10, 11, 0)
256  ));
257  triangles4.push_back(new Triangle(
258  Vertex(9, 9, 0),
259  Vertex(11, 9, 0),
260  Vertex(10, 10, -3)
261  ));
262  triangles4.push_back(new Triangle(
263  Vertex(11, 9, 0),
264  Vertex(10, 10, -3),
265  Vertex(10, 11, 0)
266  ));
267  triangles4.push_back(new Triangle(
268  Vertex(10, 11, 0),
269  Vertex(10, 10, -3),
270  Vertex(9, 9, 0)
271  ));
272  primitives.push_back(triangles4);
273 }
275  FastSAHKDTreeFactory kdtf(32, 1, 1, 1);
276  std::shared_ptr<LightKDTreeNode> tree1(
277  kdtf.makeFromPrimitives(primitives[0], true, false)
278  );
279  trees.push_back(std::make_shared<GroveKDTreeRaycaster>(tree1));
280  std::shared_ptr<LightKDTreeNode> tree2(
281  kdtf.makeFromPrimitives(primitives[1], true, false)
282  );
283  trees.push_back(std::make_shared<GroveKDTreeRaycaster>(tree2));
284  std::shared_ptr<LightKDTreeNode> tree3(
285  kdtf.makeFromPrimitives(primitives[2], true, false)
286  );
287  trees.push_back(std::make_shared<GroveKDTreeRaycaster>(tree3));
288  std::shared_ptr<LightKDTreeNode> tree4(
289  kdtf.makeFromPrimitives(primitives[3], true, false)
290  );
291  trees.push_back(std::make_shared<GroveKDTreeRaycaster>(tree4));
292 }
294  for(std::shared_ptr<GroveKDTreeRaycaster> gkdtrc : trees){
295  kdg.addTree(gkdtrc);
296  }
297 }
298 
299 }
virtual std::vector< BasicDynGroveSubject< Tree, Subject > * > const & getSubjects() const
Obtain a read-only reference to vector of subjects.
Definition: BasicDynGrove.h:93
void addTree(std::shared_ptr< Tree > tree) override
std::shared_ptr< Tree > nextTreeShared() override
size_t getNumTrees() const override
std::shared_ptr< Tree > getTreeShared(size_t const index) const override
void toZeroTree() override
bool hasNextTree() const override
Implementation of a dynamic object which supports dynamic motions (extended rigid motions)
Definition: DynMovingObject.h:39
Class providing building methods for k-dimensional trees with a fast strategy to approximate Surface ...
Definition: FastSAHKDTreeFactory.h:42
BaseTest class.
Definition: BaseTest.h:20
Test for grove of trees.
Definition: GroveTest.h:20
void buildPrimitives()
Build the primitives that will be used to define trees.
Definition: GroveTest.h:177
void buildGrove()
Build the grove of trees to be tested.
Definition: GroveTest.h:293
std::vector< std::shared_ptr< GroveKDTreeRaycaster > > trees
Trees defining.
Definition: GroveTest.h:31
void buildTrees()
Build the trees that will be contained in the grove.
Definition: GroveTest.h:274
bool run() override
Definition: GroveTest.h:93
std::vector< std::vector< Primitive * > > primitives
Primitives for each tree.
Definition: GroveTest.h:35
bool testObserving()
Test observer pattern mechanics are working as expected.
Definition: GroveTest.h:148
KDGrove kdg
The K-Dimensional Grove for testing purposes.
Definition: GroveTest.h:27
bool testLoops()
Test the for, while and for-each loops of the grove.
Definition: GroveTest.h:109
Grove of KDTrees. It supports both static and dynamic KDTrees, handling each accordingly.
Definition: KDGrove.h:20
void removeSubject(KDGroveSubject *subject)
Workaround to redirect calls from KDGrove::removeSubject(KDGroveSubject *) to BasicDynGrove::removeSu...
Definition: KDGrove.h:66
void addSubject(KDGroveSubject *subject, std::shared_ptr< GroveKDTreeRaycaster > tree)
Workaround to redirect calls from KDGrove::addSubject(KDGroveSubject *, shared_ptr<GroveKDTreeRaycast...
Definition: KDGrove.h:50
virtual KDTreeNodeRoot * makeFromPrimitives(vector< Primitive * > const &primitives, bool const computeStats=false, bool const reportStats=false)
Safe wrapper from makeFromPrimitivesUnsafe which handles a copy to make from primitives by default....
Definition: KDTreeFactory.h:111
Abstract class defining the common behavior for all primitives.
Definition: Primitive.h:24
Class representing triangle primitive.
Definition: Triangle.h:13
Class representing a vertex.
Definition: Vertex.h:14