GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: test/frontlist.cpp Lines: 189 191 99.0 %
Date: 2024-02-09 12:57:42 Branches: 327 642 50.9 %

Line Branch Exec Source
1
/*
2
 * Software License Agreement (BSD License)
3
 *
4
 *  Copyright (c) 2011-2014, Willow Garage, Inc.
5
 *  Copyright (c) 2014-2015, Open Source Robotics Foundation
6
 *  All rights reserved.
7
 *
8
 *  Redistribution and use in source and binary forms, with or without
9
 *  modification, are permitted provided that the following conditions
10
 *  are met:
11
 *
12
 *   * Redistributions of source code must retain the above copyright
13
 *     notice, this list of conditions and the following disclaimer.
14
 *   * Redistributions in binary form must reproduce the above
15
 *     copyright notice, this list of conditions and the following
16
 *     disclaimer in the documentation and/or other materials provided
17
 *     with the distribution.
18
 *   * Neither the name of Open Source Robotics Foundation nor the names of its
19
 *     contributors may be used to endorse or promote products derived
20
 *     from this software without specific prior written permission.
21
 *
22
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
 *  POSSIBILITY OF SUCH DAMAGE.
34
 */
35
36
/** \author Jia Pan */
37
38
#define BOOST_TEST_MODULE FCL_FRONT_LIST
39
#include <boost/test/included/unit_test.hpp>
40
41
#include <hpp/fcl/internal/traversal_node_bvhs.h>
42
#include <hpp/fcl/internal/traversal_node_setup.h>
43
#include <../src/collision_node.h>
44
#include <hpp/fcl/internal/BV_splitter.h>
45
#include "utility.h"
46
47
#include "fcl_resources/config.h"
48
#include <boost/filesystem.hpp>
49
50
using namespace hpp::fcl;
51
namespace utf = boost::unit_test::framework;
52
53
template <typename BV>
54
bool collide_front_list_Test(const Transform3f& tf1, const Transform3f& tf2,
55
                             const std::vector<Vec3f>& vertices1,
56
                             const std::vector<Triangle>& triangles1,
57
                             const std::vector<Vec3f>& vertices2,
58
                             const std::vector<Triangle>& triangles2,
59
                             SplitMethodType split_method, bool refit_bottomup,
60
                             bool verbose);
61
62
template <typename BV, typename TraversalNode>
63
bool collide_front_list_Test_Oriented(const Transform3f& tf1,
64
                                      const Transform3f& tf2,
65
                                      const std::vector<Vec3f>& vertices1,
66
                                      const std::vector<Triangle>& triangles1,
67
                                      const std::vector<Vec3f>& vertices2,
68
                                      const std::vector<Triangle>& triangles2,
69
                                      SplitMethodType split_method,
70
                                      bool verbose);
71
72
template <typename BV>
73
bool collide_Test(const Transform3f& tf, const std::vector<Vec3f>& vertices1,
74
                  const std::vector<Triangle>& triangles1,
75
                  const std::vector<Vec3f>& vertices2,
76
                  const std::vector<Triangle>& triangles2,
77
                  SplitMethodType split_method, bool verbose);
78
79
// TODO: randomly still have some runtime error
80
















4
BOOST_AUTO_TEST_CASE(front_list) {
81
4
  std::vector<Vec3f> p1, p2;
82
4
  std::vector<Triangle> t1, t2;
83
4
  boost::filesystem::path path(TEST_RESOURCES_DIR);
84

2
  loadOBJFile((path / "env.obj").string().c_str(), p1, t1);
85

2
  loadOBJFile((path / "rob.obj").string().c_str(), p2, t2);
86
87
4
  std::vector<Transform3f> transforms;   // t0
88
4
  std::vector<Transform3f> transforms2;  // t1
89
2
  FCL_REAL extents[] = {-3000, -3000, 0, 3000, 3000, 3000};
90
2
  FCL_REAL delta_trans[] = {1, 1, 1};
91
#ifndef NDEBUG  // if debug mode
92
2
  std::size_t n = 2;
93
#else
94
  std::size_t n = 20;
95
#endif
96

2
  n = getNbRun(utf::master_test_suite().argc, utf::master_test_suite().argv, n);
97
2
  bool verbose = false;
98
99
2
  generateRandomTransforms(extents, delta_trans, 0.005 * 2 * 3.1415, transforms,
100
                           transforms2, n);
101
102
  bool res, res2;
103
104
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
105
4
    res = collide_Test<AABB>(transforms2[i], p1, t1, p2, t2,
106
                             SPLIT_METHOD_MEDIAN, verbose);
107
    res2 =
108
4
        collide_front_list_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2,
109
                                      t2, SPLIT_METHOD_MEDIAN, false, verbose);
110



4
    BOOST_CHECK(res == res2);
111
4
    res = collide_Test<AABB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
112
                             verbose);
113
    res2 =
114
4
        collide_front_list_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2,
115
                                      t2, SPLIT_METHOD_MEAN, false, verbose);
116



4
    BOOST_CHECK(res == res2);
117
4
    res = collide_Test<AABB>(transforms2[i], p1, t1, p2, t2,
118
                             SPLIT_METHOD_BV_CENTER, verbose);
119
4
    res2 = collide_front_list_Test<AABB>(transforms[i], transforms2[i], p1, t1,
120
                                         p2, t2, SPLIT_METHOD_BV_CENTER, false,
121
                                         verbose);
122



4
    BOOST_CHECK(res == res2);
123
  }
124
125
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
126
4
    res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN,
127
                            verbose);
128
    res2 =
129
4
        collide_front_list_Test<OBB>(transforms[i], transforms2[i], p1, t1, p2,
130
                                     t2, SPLIT_METHOD_MEDIAN, false, verbose);
131



4
    BOOST_CHECK(res == res2);
132
4
    res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
133
                            verbose);
134
    res2 =
135
4
        collide_front_list_Test<OBB>(transforms[i], transforms2[i], p1, t1, p2,
136
                                     t2, SPLIT_METHOD_MEAN, false, verbose);
137



4
    BOOST_CHECK(res == res2);
138
4
    res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2,
139
                            SPLIT_METHOD_BV_CENTER, verbose);
140
4
    res2 = collide_front_list_Test<OBB>(transforms[i], transforms2[i], p1, t1,
141
                                        p2, t2, SPLIT_METHOD_BV_CENTER, false,
142
                                        verbose);
143



4
    BOOST_CHECK(res == res2);
144
  }
145
146
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
147
    // Disabled broken test lines. Please see #25.
148
    // res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2,
149
    // SPLIT_METHOD_MEDIAN, verbose); res2 =
150
    // collide_front_list_Test<RSS>(transforms[i], transforms2[i], p1, t1, p2,
151
    // t2, SPLIT_METHOD_MEDIAN, false, verbose); BOOST_CHECK(res == res2);
152
4
    res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
153
                            verbose);
154
    res2 =
155
4
        collide_front_list_Test<RSS>(transforms[i], transforms2[i], p1, t1, p2,
156
                                     t2, SPLIT_METHOD_MEAN, false, verbose);
157



4
    BOOST_CHECK(res == res2);
158
4
    res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2,
159
                            SPLIT_METHOD_BV_CENTER, verbose);
160
4
    res2 = collide_front_list_Test<RSS>(transforms[i], transforms2[i], p1, t1,
161
                                        p2, t2, SPLIT_METHOD_BV_CENTER, false,
162
                                        verbose);
163



4
    BOOST_CHECK(res == res2);
164
  }
165
166
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
167
4
    res = collide_Test<KDOP<16> >(transforms2[i], p1, t1, p2, t2,
168
                                  SPLIT_METHOD_MEDIAN, verbose);
169
4
    res2 = collide_front_list_Test<KDOP<16> >(transforms[i], transforms2[i], p1,
170
                                              t1, p2, t2, SPLIT_METHOD_MEDIAN,
171
                                              false, verbose);
172



4
    BOOST_CHECK(res == res2);
173
4
    res = collide_Test<KDOP<16> >(transforms2[i], p1, t1, p2, t2,
174
                                  SPLIT_METHOD_MEAN, verbose);
175
4
    res2 = collide_front_list_Test<KDOP<16> >(transforms[i], transforms2[i], p1,
176
                                              t1, p2, t2, SPLIT_METHOD_MEAN,
177
                                              false, verbose);
178



4
    BOOST_CHECK(res == res2);
179
4
    res = collide_Test<KDOP<16> >(transforms2[i], p1, t1, p2, t2,
180
                                  SPLIT_METHOD_BV_CENTER, verbose);
181
4
    res2 = collide_front_list_Test<KDOP<16> >(
182
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER,
183
        false, verbose);
184



4
    BOOST_CHECK(res == res2);
185
  }
186
187
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
188
4
    res = collide_Test<KDOP<18> >(transforms2[i], p1, t1, p2, t2,
189
                                  SPLIT_METHOD_MEDIAN, verbose);
190
4
    res2 = collide_front_list_Test<KDOP<18> >(transforms[i], transforms2[i], p1,
191
                                              t1, p2, t2, SPLIT_METHOD_MEDIAN,
192
                                              false, verbose);
193



4
    BOOST_CHECK(res == res2);
194
4
    res = collide_Test<KDOP<18> >(transforms2[i], p1, t1, p2, t2,
195
                                  SPLIT_METHOD_MEAN, verbose);
196
4
    res2 = collide_front_list_Test<KDOP<18> >(transforms[i], transforms2[i], p1,
197
                                              t1, p2, t2, SPLIT_METHOD_MEAN,
198
                                              false, verbose);
199



4
    BOOST_CHECK(res == res2);
200
4
    res = collide_Test<KDOP<18> >(transforms2[i], p1, t1, p2, t2,
201
                                  SPLIT_METHOD_BV_CENTER, verbose);
202
4
    res2 = collide_front_list_Test<KDOP<18> >(
203
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER,
204
        false, verbose);
205



4
    BOOST_CHECK(res == res2);
206
  }
207
208
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
209
4
    res = collide_Test<KDOP<24> >(transforms2[i], p1, t1, p2, t2,
210
                                  SPLIT_METHOD_MEDIAN, verbose);
211
4
    res2 = collide_front_list_Test<KDOP<24> >(transforms[i], transforms2[i], p1,
212
                                              t1, p2, t2, SPLIT_METHOD_MEDIAN,
213
                                              false, verbose);
214



4
    BOOST_CHECK(res == res2);
215
4
    res = collide_Test<KDOP<24> >(transforms2[i], p1, t1, p2, t2,
216
                                  SPLIT_METHOD_MEAN, verbose);
217
4
    res2 = collide_front_list_Test<KDOP<24> >(transforms[i], transforms2[i], p1,
218
                                              t1, p2, t2, SPLIT_METHOD_MEAN,
219
                                              false, verbose);
220



4
    BOOST_CHECK(res == res2);
221
4
    res = collide_Test<KDOP<24> >(transforms2[i], p1, t1, p2, t2,
222
                                  SPLIT_METHOD_BV_CENTER, verbose);
223
4
    res2 = collide_front_list_Test<KDOP<24> >(
224
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER,
225
        false, verbose);
226



4
    BOOST_CHECK(res == res2);
227
  }
228
229
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
230
4
    res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN,
231
                            verbose);
232
4
    res2 = collide_front_list_Test_Oriented<RSS, MeshCollisionTraversalNodeRSS>(
233
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN,
234
        verbose);
235



4
    BOOST_CHECK(res == res2);
236
4
    res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
237
                            verbose);
238
4
    res2 = collide_front_list_Test_Oriented<RSS, MeshCollisionTraversalNodeRSS>(
239
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
240
        verbose);
241



4
    BOOST_CHECK(res == res2);
242
4
    res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2,
243
                            SPLIT_METHOD_BV_CENTER, verbose);
244
4
    res2 = collide_front_list_Test_Oriented<RSS, MeshCollisionTraversalNodeRSS>(
245
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER,
246
        verbose);
247



4
    BOOST_CHECK(res == res2);
248
  }
249
250
6
  for (std::size_t i = 0; i < transforms.size(); ++i) {
251
4
    res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN,
252
                            verbose);
253
4
    res2 = collide_front_list_Test_Oriented<OBB, MeshCollisionTraversalNodeOBB>(
254
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN,
255
        verbose);
256



4
    BOOST_CHECK(res == res2);
257
4
    res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
258
                            verbose);
259
4
    res2 = collide_front_list_Test_Oriented<OBB, MeshCollisionTraversalNodeOBB>(
260
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN,
261
        verbose);
262



4
    BOOST_CHECK(res == res2);
263
4
    res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2,
264
                            SPLIT_METHOD_BV_CENTER, verbose);
265
4
    res2 = collide_front_list_Test_Oriented<OBB, MeshCollisionTraversalNodeOBB>(
266
4
        transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER,
267
        verbose);
268



4
    BOOST_CHECK(res == res2);
269
  }
270
2
}
271
272
template <typename BV>
273
68
bool collide_front_list_Test(const Transform3f& tf1, const Transform3f& tf2,
274
                             const std::vector<Vec3f>& vertices1,
275
                             const std::vector<Triangle>& triangles1,
276
                             const std::vector<Vec3f>& vertices2,
277
                             const std::vector<Triangle>& triangles2,
278
                             SplitMethodType split_method, bool refit_bottomup,
279
                             bool verbose) {
280
136
  BVHModel<BV> m1;
281
136
  BVHModel<BV> m2;
282

68
  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
283

68
  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
284
285
136
  BVHFrontList front_list;
286
287
136
  std::vector<Vec3f> vertices1_new(vertices1.size());
288
444788
  for (std::size_t i = 0; i < vertices1_new.size(); ++i) {
289
444720
    vertices1_new[i] = tf1.transform(vertices1[i]);
290
  }
291
292
68
  m1.beginModel();
293
68
  m1.addSubModel(vertices1_new, triangles1);
294
68
  m1.endModel();
295
296
68
  m2.beginModel();
297
68
  m2.addSubModel(vertices2, triangles2);
298
68
  m2.endModel();
299
300

68
  Transform3f pose1, pose2;
301
302
136
  CollisionResult local_result;
303
68
  CollisionRequest request(NO_REQUEST, (std::numeric_limits<int>::max)());
304
136
  MeshCollisionTraversalNode<BV> node(request);
305
306
68
  bool success = initialize<BV>(node, m1, pose1, m2, pose2, local_result);
307



68
  BOOST_REQUIRE(success);
308
309
68
  node.enable_statistics = verbose;
310
311
68
  collide(&node, request, local_result, &front_list);
312
313
68
  if (verbose)
314
    std::cout << "front list size " << front_list.size() << std::endl;
315
316
  // update the mesh
317
444788
  for (std::size_t i = 0; i < vertices1.size(); ++i) {
318
444720
    vertices1_new[i] = tf2.transform(vertices1[i]);
319
  }
320
321
68
  m1.beginReplaceModel();
322
68
  m1.replaceSubModel(vertices1_new);
323
68
  m1.endReplaceModel(true, refit_bottomup);
324
325
68
  m2.beginReplaceModel();
326
68
  m2.replaceSubModel(vertices2);
327
68
  m2.endReplaceModel(true, refit_bottomup);
328
329
68
  local_result.clear();
330
68
  collide(&node, request, local_result, &front_list);
331
332
68
  if (local_result.numContacts() > 0)
333
34
    return true;
334
  else
335
34
    return false;
336
}
337
338
template <typename BV, typename TraversalNode>
339
24
bool collide_front_list_Test_Oriented(const Transform3f& tf1,
340
                                      const Transform3f& tf2,
341
                                      const std::vector<Vec3f>& vertices1,
342
                                      const std::vector<Triangle>& triangles1,
343
                                      const std::vector<Vec3f>& vertices2,
344
                                      const std::vector<Triangle>& triangles2,
345
                                      SplitMethodType split_method,
346
                                      bool verbose) {
347
48
  BVHModel<BV> m1;
348
48
  BVHModel<BV> m2;
349

24
  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
350

24
  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
351
352
48
  BVHFrontList front_list;
353
354
24
  m1.beginModel();
355
24
  m1.addSubModel(vertices1, triangles1);
356
24
  m1.endModel();
357
358
24
  m2.beginModel();
359
24
  m2.addSubModel(vertices2, triangles2);
360
24
  m2.endModel();
361
362

24
  Transform3f pose1(tf1), pose2;
363
364
48
  CollisionResult local_result;
365
24
  CollisionRequest request(NO_REQUEST, (std::numeric_limits<int>::max)());
366
48
  TraversalNode node(request);
367
368
24
  bool success = initialize(node, (const BVHModel<BV>&)m1, pose1,
369
                            (const BVHModel<BV>&)m2, pose2, local_result);
370



24
  BOOST_REQUIRE(success);
371
372
24
  node.enable_statistics = verbose;
373
374
24
  collide(&node, request, local_result, &front_list);
375
376
24
  if (verbose)
377
    std::cout << "front list size " << front_list.size() << std::endl;
378
379
  // update the mesh
380
24
  pose1 = tf2;
381
24
  success = initialize(node, (const BVHModel<BV>&)m1, pose1,
382
                       (const BVHModel<BV>&)m2, pose2, local_result);
383



24
  BOOST_REQUIRE(success);
384
385
24
  local_result.clear();
386
24
  collide(&node, request, local_result, &front_list);
387
388
24
  if (local_result.numContacts() > 0)
389
12
    return true;
390
  else
391
12
    return false;
392
}
393
394
template <typename BV>
395
46
bool collide_Test(const Transform3f& tf, const std::vector<Vec3f>& vertices1,
396
                  const std::vector<Triangle>& triangles1,
397
                  const std::vector<Vec3f>& vertices2,
398
                  const std::vector<Triangle>& triangles2,
399
                  SplitMethodType split_method, bool verbose) {
400
92
  BVHModel<BV> m1;
401
92
  BVHModel<BV> m2;
402
46
  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
403
46
  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
404
405
46
  m1.beginModel();
406
46
  m1.addSubModel(vertices1, triangles1);
407
46
  m1.endModel();
408
409
46
  m2.beginModel();
410
46
  m2.addSubModel(vertices2, triangles2);
411
46
  m2.endModel();
412
413
46
  Transform3f pose1(tf), pose2;
414
415
92
  CollisionResult local_result;
416
46
  CollisionRequest request(NO_REQUEST, (std::numeric_limits<int>::max)());
417
92
  MeshCollisionTraversalNode<BV> node(request);
418
419
46
  bool success = initialize<BV>(node, m1, pose1, m2, pose2, local_result);
420
46
  BOOST_REQUIRE(success);
421
422
46
  node.enable_statistics = verbose;
423
424
46
  collide(&node, request, local_result);
425
426
46
  if (local_result.numContacts() > 0)
427
23
    return true;
428
  else
429
23
    return false;
430
}