GCC Code Coverage Report


Directory: ./
File: include/coal/internal/traversal_node_setup.h
Date: 2025-04-01 09:23:31
Exec Total Coverage
Lines: 164 321 51.1%
Branches: 71 590 12.0%

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 #ifndef COAL_TRAVERSAL_NODE_SETUP_H
39 #define COAL_TRAVERSAL_NODE_SETUP_H
40
41 /// @cond INTERNAL
42
43 #include "coal/internal/tools.h"
44 #include "coal/internal/traversal_node_shapes.h"
45
46 #include "coal/internal/traversal_node_bvhs.h"
47 #include "coal/internal/traversal_node_bvh_shape.h"
48
49 // #include <hpp/fcl/internal/traversal_node_hfields.h>
50 #include "coal/internal/traversal_node_hfield_shape.h"
51
52 #ifdef COAL_HAS_OCTOMAP
53 #include "coal/internal/traversal_node_octree.h"
54 #endif
55
56 #include "coal/BVH/BVH_utility.h"
57
58 namespace coal {
59
60 #ifdef COAL_HAS_OCTOMAP
61 /// @brief Initialize traversal node for collision between two octrees, given
62 /// current object transform
63 inline bool initialize(OcTreeCollisionTraversalNode& node, const OcTree& model1,
64 const Transform3s& tf1, const OcTree& model2,
65 const Transform3s& tf2, const OcTreeSolver* otsolver,
66 CollisionResult& result) {
67 node.result = &result;
68
69 node.model1 = &model1;
70 node.model2 = &model2;
71
72 node.otsolver = otsolver;
73
74 node.tf1 = tf1;
75 node.tf2 = tf2;
76
77 return true;
78 }
79
80 /// @brief Initialize traversal node for distance between two octrees, given
81 /// current object transform
82 inline bool initialize(OcTreeDistanceTraversalNode& node, const OcTree& model1,
83 const Transform3s& tf1, const OcTree& model2,
84 const Transform3s& tf2, const OcTreeSolver* otsolver,
85 const DistanceRequest& request, DistanceResult& result)
86
87 {
88 node.request = request;
89 node.result = &result;
90
91 node.model1 = &model1;
92 node.model2 = &model2;
93
94 node.otsolver = otsolver;
95
96 node.tf1 = tf1;
97 node.tf2 = tf2;
98
99 return true;
100 }
101
102 /// @brief Initialize traversal node for collision between one shape and one
103 /// octree, given current object transform
104 template <typename S>
105 bool initialize(ShapeOcTreeCollisionTraversalNode<S>& node, const S& model1,
106 const Transform3s& tf1, const OcTree& model2,
107 const Transform3s& tf2, const OcTreeSolver* otsolver,
108 CollisionResult& result) {
109 node.result = &result;
110
111 node.model1 = &model1;
112 node.model2 = &model2;
113
114 node.otsolver = otsolver;
115
116 node.tf1 = tf1;
117 node.tf2 = tf2;
118
119 return true;
120 }
121
122 /// @brief Initialize traversal node for collision between one octree and one
123 /// shape, given current object transform
124 template <typename S>
125 2000 bool initialize(OcTreeShapeCollisionTraversalNode<S>& node,
126 const OcTree& model1, const Transform3s& tf1, const S& model2,
127 const Transform3s& tf2, const OcTreeSolver* otsolver,
128 CollisionResult& result) {
129 2000 node.result = &result;
130
131 2000 node.model1 = &model1;
132 2000 node.model2 = &model2;
133
134 2000 node.otsolver = otsolver;
135
136 2000 node.tf1 = tf1;
137 2000 node.tf2 = tf2;
138
139 2000 return true;
140 }
141
142 /// @brief Initialize traversal node for distance between one shape and one
143 /// octree, given current object transform
144 template <typename S>
145 bool initialize(ShapeOcTreeDistanceTraversalNode<S>& node, const S& model1,
146 const Transform3s& tf1, const OcTree& model2,
147 const Transform3s& tf2, const OcTreeSolver* otsolver,
148 const DistanceRequest& request, DistanceResult& result) {
149 node.request = request;
150 node.result = &result;
151
152 node.model1 = &model1;
153 node.model2 = &model2;
154
155 node.otsolver = otsolver;
156
157 node.tf1 = tf1;
158 node.tf2 = tf2;
159
160 return true;
161 }
162
163 /// @brief Initialize traversal node for distance between one octree and one
164 /// shape, given current object transform
165 template <typename S>
166 bool initialize(OcTreeShapeDistanceTraversalNode<S>& node, const OcTree& model1,
167 const Transform3s& tf1, const S& model2, const Transform3s& tf2,
168 const OcTreeSolver* otsolver, const DistanceRequest& request,
169 DistanceResult& result) {
170 node.request = request;
171 node.result = &result;
172
173 node.model1 = &model1;
174 node.model2 = &model2;
175
176 node.otsolver = otsolver;
177
178 node.tf1 = tf1;
179 node.tf2 = tf2;
180
181 return true;
182 }
183
184 /// @brief Initialize traversal node for collision between one mesh and one
185 /// octree, given current object transform
186 template <typename BV>
187 200 bool initialize(MeshOcTreeCollisionTraversalNode<BV>& node,
188 const BVHModel<BV>& model1, const Transform3s& tf1,
189 const OcTree& model2, const Transform3s& tf2,
190 const OcTreeSolver* otsolver, CollisionResult& result) {
191 200 node.result = &result;
192
193 200 node.model1 = &model1;
194 200 node.model2 = &model2;
195
196 200 node.otsolver = otsolver;
197
198 200 node.tf1 = tf1;
199 200 node.tf2 = tf2;
200
201 200 return true;
202 }
203
204 /// @brief Initialize traversal node for collision between one octree and one
205 /// mesh, given current object transform
206 template <typename BV>
207 bool initialize(OcTreeMeshCollisionTraversalNode<BV>& node,
208 const OcTree& model1, const Transform3s& tf1,
209 const BVHModel<BV>& model2, const Transform3s& tf2,
210 const OcTreeSolver* otsolver, CollisionResult& result) {
211 node.result = &result;
212
213 node.model1 = &model1;
214 node.model2 = &model2;
215
216 node.otsolver = otsolver;
217
218 node.tf1 = tf1;
219 node.tf2 = tf2;
220
221 return true;
222 }
223
224 /// @brief Initialize traversal node for collision between one octree and one
225 /// height field, given current object transform
226 template <typename BV>
227 2000 bool initialize(OcTreeHeightFieldCollisionTraversalNode<BV>& node,
228 const OcTree& model1, const Transform3s& tf1,
229 const HeightField<BV>& model2, const Transform3s& tf2,
230 const OcTreeSolver* otsolver, CollisionResult& result) {
231 2000 node.result = &result;
232
233 2000 node.model1 = &model1;
234 2000 node.model2 = &model2;
235
236 2000 node.otsolver = otsolver;
237
238 2000 node.tf1 = tf1;
239 2000 node.tf2 = tf2;
240
241 2000 return true;
242 }
243
244 /// @brief Initialize traversal node for collision between one height field and
245 /// one octree, given current object transform
246 template <typename BV>
247 2000 bool initialize(HeightFieldOcTreeCollisionTraversalNode<BV>& node,
248 const HeightField<BV>& model1, const Transform3s& tf1,
249 const OcTree& model2, const Transform3s& tf2,
250 const OcTreeSolver* otsolver, CollisionResult& result) {
251 2000 node.result = &result;
252
253 2000 node.model1 = &model1;
254 2000 node.model2 = &model2;
255
256 2000 node.otsolver = otsolver;
257
258 2000 node.tf1 = tf1;
259 2000 node.tf2 = tf2;
260
261 2000 return true;
262 }
263
264 /// @brief Initialize traversal node for distance between one mesh and one
265 /// octree, given current object transform
266 template <typename BV>
267 bool initialize(MeshOcTreeDistanceTraversalNode<BV>& node,
268 const BVHModel<BV>& model1, const Transform3s& tf1,
269 const OcTree& model2, const Transform3s& tf2,
270 const OcTreeSolver* otsolver, const DistanceRequest& request,
271 DistanceResult& result) {
272 node.request = request;
273 node.result = &result;
274
275 node.model1 = &model1;
276 node.model2 = &model2;
277
278 node.otsolver = otsolver;
279
280 node.tf1 = tf1;
281 node.tf2 = tf2;
282
283 return true;
284 }
285
286 /// @brief Initialize traversal node for collision between one octree and one
287 /// mesh, given current object transform
288 template <typename BV>
289 bool initialize(OcTreeMeshDistanceTraversalNode<BV>& node, const OcTree& model1,
290 const Transform3s& tf1, const BVHModel<BV>& model2,
291 const Transform3s& tf2, const OcTreeSolver* otsolver,
292 const DistanceRequest& request, DistanceResult& result) {
293 node.request = request;
294 node.result = &result;
295
296 node.model1 = &model1;
297 node.model2 = &model2;
298
299 node.otsolver = otsolver;
300
301 node.tf1 = tf1;
302 node.tf2 = tf2;
303
304 return true;
305 }
306
307 #endif
308
309 /// @brief Initialize traversal node for collision between two geometric shapes,
310 /// given current object transform
311 template <typename S1, typename S2>
312 bool initialize(ShapeCollisionTraversalNode<S1, S2>& node, const S1& shape1,
313 const Transform3s& tf1, const S2& shape2,
314 const Transform3s& tf2, const GJKSolver* nsolver,
315 CollisionResult& result) {
316 node.model1 = &shape1;
317 node.tf1 = tf1;
318 node.model2 = &shape2;
319 node.tf2 = tf2;
320 node.nsolver = nsolver;
321
322 node.result = &result;
323
324 return true;
325 }
326
327 /// @brief Initialize traversal node for collision between one mesh and one
328 /// shape, given current object transform
329 template <typename BV, typename S>
330 bool initialize(MeshShapeCollisionTraversalNode<BV, S>& node,
331 BVHModel<BV>& model1, Transform3s& tf1, const S& model2,
332 const Transform3s& tf2, const GJKSolver* nsolver,
333 CollisionResult& result, bool use_refit = false,
334 bool refit_bottomup = false) {
335 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
336 COAL_THROW_PRETTY(
337 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
338 std::invalid_argument)
339
340 if (!tf1.isIdentity() &&
341 model1.vertices.get()) // TODO(jcarpent): vectorized version
342 {
343 std::vector<Vec3s> vertices_transformed(model1.num_vertices);
344 const std::vector<Vec3s>& model1_vertices_ = *(model1.vertices);
345 for (unsigned int i = 0; i < model1.num_vertices; ++i) {
346 const Vec3s& p = model1_vertices_[i];
347 Vec3s new_v = tf1.transform(p);
348 vertices_transformed[i] = new_v;
349 }
350
351 model1.beginReplaceModel();
352 model1.replaceSubModel(vertices_transformed);
353 model1.endReplaceModel(use_refit, refit_bottomup);
354
355 tf1.setIdentity();
356 }
357
358 node.model1 = &model1;
359 node.tf1 = tf1;
360 node.model2 = &model2;
361 node.tf2 = tf2;
362 node.nsolver = nsolver;
363
364 computeBV(model2, tf2, node.model2_bv);
365
366 node.vertices = model1.vertices.get() ? model1.vertices->data() : NULL;
367 node.tri_indices =
368 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
369
370 node.result = &result;
371
372 return true;
373 }
374
375 /// @brief Initialize traversal node for collision between one mesh and one
376 /// shape
377 template <typename BV, typename S>
378 252 bool initialize(MeshShapeCollisionTraversalNode<BV, S, 0>& node,
379 const BVHModel<BV>& model1, const Transform3s& tf1,
380 const S& model2, const Transform3s& tf2,
381 const GJKSolver* nsolver, CollisionResult& result) {
382
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 126 times.
252 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
383 COAL_THROW_PRETTY(
384 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
385 std::invalid_argument)
386
387 252 node.model1 = &model1;
388 252 node.tf1 = tf1;
389 252 node.model2 = &model2;
390 252 node.tf2 = tf2;
391 252 node.nsolver = nsolver;
392
393 252 computeBV(model2, tf2, node.model2_bv);
394
395
1/2
✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
252 node.vertices = model1.vertices.get() ? model1.vertices->data() : NULL;
396 252 node.tri_indices =
397
1/2
✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
252 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
398
399 252 node.result = &result;
400
401 252 return true;
402 }
403
404 /// @brief Initialize traversal node for collision between one mesh and one
405 /// shape, given current object transform
406 template <typename BV, typename S>
407 bool initialize(HeightFieldShapeCollisionTraversalNode<BV, S>& node,
408 HeightField<BV>& model1, Transform3s& tf1, const S& model2,
409 const Transform3s& tf2, const GJKSolver* nsolver,
410 CollisionResult& result, bool use_refit = false,
411 bool refit_bottomup = false);
412
413 /// @brief Initialize traversal node for collision between one mesh and one
414 /// shape
415 template <typename BV, typename S>
416 110 bool initialize(HeightFieldShapeCollisionTraversalNode<BV, S, 0>& node,
417 const HeightField<BV>& model1, const Transform3s& tf1,
418 const S& model2, const Transform3s& tf2,
419 const GJKSolver* nsolver, CollisionResult& result) {
420 110 node.model1 = &model1;
421 110 node.tf1 = tf1;
422 110 node.model2 = &model2;
423 110 node.tf2 = tf2;
424 110 node.nsolver = nsolver;
425
426 110 computeBV(model2, tf2, node.model2_bv);
427
428 110 node.result = &result;
429
430 110 return true;
431 }
432
433 /// @cond IGNORE
434 namespace details {
435 template <typename S, typename BV, template <typename> class OrientedNode>
436 static inline bool setupShapeMeshCollisionOrientedNode(
437 OrientedNode<S>& node, const S& model1, const Transform3s& tf1,
438 const BVHModel<BV>& model2, const Transform3s& tf2,
439 const GJKSolver* nsolver, CollisionResult& result) {
440 if (model2.getModelType() != BVH_MODEL_TRIANGLES)
441 COAL_THROW_PRETTY(
442 "model2 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
443 std::invalid_argument)
444
445 node.model1 = &model1;
446 node.tf1 = tf1;
447 node.model2 = &model2;
448 node.tf2 = tf2;
449 node.nsolver = nsolver;
450
451 computeBV(model1, tf1, node.model1_bv);
452
453 node.vertices = model2.vertices.get() ? model2.vertices->data() : NULL;
454 node.tri_indices =
455 model2.tri_indices.get() ? model2.tri_indices->data() : NULL;
456
457 node.result = &result;
458
459 return true;
460 }
461 } // namespace details
462 /// @endcond
463
464 /// @brief Initialize traversal node for collision between two meshes, given the
465 /// current transforms
466 template <typename BV>
467 202 bool initialize(
468 MeshCollisionTraversalNode<BV, RelativeTransformationIsIdentity>& node,
469 BVHModel<BV>& model1, Transform3s& tf1, BVHModel<BV>& model2,
470 Transform3s& tf2, CollisionResult& result, bool use_refit = false,
471 bool refit_bottomup = false) {
472
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
202 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
473 COAL_THROW_PRETTY(
474 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
475 std::invalid_argument)
476
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
202 if (model2.getModelType() != BVH_MODEL_TRIANGLES)
477 COAL_THROW_PRETTY(
478 "model2 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
479 std::invalid_argument)
480
481
6/8
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 67 times.
✓ Branch 5 taken 34 times.
✓ Branch 7 taken 67 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 67 times.
✓ Branch 10 taken 34 times.
202 if (!tf1.isIdentity() && model1.vertices.get()) {
482
1/2
✓ Branch 2 taken 67 times.
✗ Branch 3 not taken.
134 std::vector<Vec3s> vertices_transformed1(model1.num_vertices);
483 134 const std::vector<Vec3s>& model1_vertices_ = *(model1.vertices);
484
2/2
✓ Branch 0 taken 344352 times.
✓ Branch 1 taken 67 times.
688838 for (unsigned int i = 0; i < model1.num_vertices; ++i) {
485 688704 const Vec3s& p = model1_vertices_[i];
486
1/2
✓ Branch 1 taken 344352 times.
✗ Branch 2 not taken.
688704 Vec3s new_v = tf1.transform(p);
487
1/2
✓ Branch 2 taken 344352 times.
✗ Branch 3 not taken.
688704 vertices_transformed1[i] = new_v;
488 }
489
490
1/2
✓ Branch 1 taken 67 times.
✗ Branch 2 not taken.
134 model1.beginReplaceModel();
491
1/2
✓ Branch 1 taken 67 times.
✗ Branch 2 not taken.
134 model1.replaceSubModel(vertices_transformed1);
492
1/2
✓ Branch 1 taken 67 times.
✗ Branch 2 not taken.
134 model1.endReplaceModel(use_refit, refit_bottomup);
493
494
1/2
✓ Branch 1 taken 67 times.
✗ Branch 2 not taken.
134 tf1.setIdentity();
495 134 }
496
497
3/8
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 101 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 101 times.
202 if (!tf2.isIdentity() && model2.vertices.get()) {
498 std::vector<Vec3s> vertices_transformed2(model2.num_vertices);
499 const std::vector<Vec3s>& model2_vertices_ = *(model2.vertices);
500 for (unsigned int i = 0; i < model2.num_vertices; ++i) {
501 const Vec3s& p = model2_vertices_[i];
502 Vec3s new_v = tf2.transform(p);
503 vertices_transformed2[i] = new_v;
504 }
505
506 model2.beginReplaceModel();
507 model2.replaceSubModel(vertices_transformed2);
508 model2.endReplaceModel(use_refit, refit_bottomup);
509
510 tf2.setIdentity();
511 }
512
513 202 node.model1 = &model1;
514 202 node.tf1 = tf1;
515 202 node.model2 = &model2;
516 202 node.tf2 = tf2;
517
518
1/2
✓ Branch 1 taken 101 times.
✗ Branch 2 not taken.
202 node.vertices1 = model1.vertices.get() ? model1.vertices->data() : NULL;
519
1/2
✓ Branch 1 taken 101 times.
✗ Branch 2 not taken.
202 node.vertices2 = model2.vertices.get() ? model2.vertices->data() : NULL;
520
521 202 node.tri_indices1 =
522
1/2
✓ Branch 1 taken 101 times.
✗ Branch 2 not taken.
202 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
523 202 node.tri_indices2 =
524
1/2
✓ Branch 1 taken 101 times.
✗ Branch 2 not taken.
202 model2.tri_indices.get() ? model2.tri_indices->data() : NULL;
525
526 202 node.result = &result;
527
528 202 return true;
529 }
530
531 template <typename BV>
532 10709 bool initialize(MeshCollisionTraversalNode<BV, 0>& node,
533 const BVHModel<BV>& model1, const Transform3s& tf1,
534 const BVHModel<BV>& model2, const Transform3s& tf2,
535 CollisionResult& result) {
536
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
10709 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
537 COAL_THROW_PRETTY(
538 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
539 std::invalid_argument)
540
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
10709 if (model2.getModelType() != BVH_MODEL_TRIANGLES)
541 COAL_THROW_PRETTY(
542 "model2 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
543 std::invalid_argument)
544
545
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
10709 node.vertices1 = model1.vertices ? model1.vertices->data() : NULL;
546
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
10709 node.vertices2 = model2.vertices ? model2.vertices->data() : NULL;
547
548 10709 node.tri_indices1 =
549
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
10709 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
550 10709 node.tri_indices2 =
551
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
10709 model2.tri_indices.get() ? model2.tri_indices->data() : NULL;
552
553 10709 node.model1 = &model1;
554 10709 node.tf1 = tf1;
555 10709 node.model2 = &model2;
556 10709 node.tf2 = tf2;
557
558 10709 node.result = &result;
559
560
3/6
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
10709 node.RT.R.noalias() = tf1.getRotation().transpose() * tf2.getRotation();
561
4/8
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
10709 node.RT.T.noalias() = tf1.getRotation().transpose() *
562 10709 (tf2.getTranslation() - tf1.getTranslation());
563
564 10709 return true;
565 }
566
567 /// @brief Initialize traversal node for distance between two geometric shapes
568 template <typename S1, typename S2>
569 bool initialize(ShapeDistanceTraversalNode<S1, S2>& node, const S1& shape1,
570 const Transform3s& tf1, const S2& shape2,
571 const Transform3s& tf2, const GJKSolver* nsolver,
572 const DistanceRequest& request, DistanceResult& result) {
573 node.request = request;
574 node.result = &result;
575
576 node.model1 = &shape1;
577 node.tf1 = tf1;
578 node.model2 = &shape2;
579 node.tf2 = tf2;
580 node.nsolver = nsolver;
581
582 return true;
583 }
584
585 /// @brief Initialize traversal node for distance computation between two
586 /// meshes, given the current transforms
587 template <typename BV>
588 48 bool initialize(
589 MeshDistanceTraversalNode<BV, RelativeTransformationIsIdentity>& node,
590 BVHModel<BV>& model1, Transform3s& tf1, BVHModel<BV>& model2,
591 Transform3s& tf2, const DistanceRequest& request, DistanceResult& result,
592 bool use_refit = false, bool refit_bottomup = false) {
593
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
48 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
594 COAL_THROW_PRETTY(
595 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
596 std::invalid_argument)
597
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
48 if (model2.getModelType() != BVH_MODEL_TRIANGLES)
598 COAL_THROW_PRETTY(
599 "model2 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
600 std::invalid_argument)
601
602
4/8
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
48 if (!tf1.isIdentity() && model1.vertices.get()) {
603
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
48 std::vector<Vec3s> vertices_transformed1(model1.num_vertices);
604 48 const std::vector<Vec3s>& model1_vertices_ = *(model1.vertices);
605
2/2
✓ Branch 0 taken 156960 times.
✓ Branch 1 taken 24 times.
313968 for (unsigned int i = 0; i < model1.num_vertices; ++i) {
606 313920 const Vec3s& p = model1_vertices_[i];
607
1/2
✓ Branch 1 taken 156960 times.
✗ Branch 2 not taken.
313920 Vec3s new_v = tf1.transform(p);
608
1/2
✓ Branch 2 taken 156960 times.
✗ Branch 3 not taken.
313920 vertices_transformed1[i] = new_v;
609 }
610
611
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 model1.beginReplaceModel();
612
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 model1.replaceSubModel(vertices_transformed1);
613
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 model1.endReplaceModel(use_refit, refit_bottomup);
614
615
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 tf1.setIdentity();
616 48 }
617
618
3/8
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
48 if (!tf2.isIdentity() && model2.vertices.get()) {
619 std::vector<Vec3s> vertices_transformed2(model2.num_vertices);
620 const std::vector<Vec3s>& model2_vertices_ = *(model2.vertices);
621 for (unsigned int i = 0; i < model2.num_vertices; ++i) {
622 const Vec3s& p = model2_vertices_[i];
623 Vec3s new_v = tf2.transform(p);
624 vertices_transformed2[i] = new_v;
625 }
626
627 model2.beginReplaceModel();
628 model2.replaceSubModel(vertices_transformed2);
629 model2.endReplaceModel(use_refit, refit_bottomup);
630
631 tf2.setIdentity();
632 }
633
634 48 node.request = request;
635 48 node.result = &result;
636
637 48 node.model1 = &model1;
638 48 node.tf1 = tf1;
639 48 node.model2 = &model2;
640 48 node.tf2 = tf2;
641
642
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 node.vertices1 = model1.vertices.get() ? model1.vertices->data() : NULL;
643
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 node.vertices2 = model2.vertices.get() ? model2.vertices->data() : NULL;
644
645 48 node.tri_indices1 =
646
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
647 48 node.tri_indices2 =
648
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 model2.tri_indices.get() ? model2.tri_indices->data() : NULL;
649
650 48 return true;
651 }
652
653 /// @brief Initialize traversal node for distance computation between two meshes
654 template <typename BV>
655 14308 bool initialize(MeshDistanceTraversalNode<BV, 0>& node,
656 const BVHModel<BV>& model1, const Transform3s& tf1,
657 const BVHModel<BV>& model2, const Transform3s& tf2,
658 const DistanceRequest& request, DistanceResult& result) {
659
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7145 times.
14308 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
660 COAL_THROW_PRETTY(
661 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
662 std::invalid_argument)
663
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7145 times.
14308 if (model2.getModelType() != BVH_MODEL_TRIANGLES)
664 COAL_THROW_PRETTY(
665 "model2 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
666 std::invalid_argument)
667
668 14308 node.request = request;
669 14308 node.result = &result;
670
671 14308 node.model1 = &model1;
672 14308 node.tf1 = tf1;
673 14308 node.model2 = &model2;
674 14308 node.tf2 = tf2;
675
676
1/2
✓ Branch 1 taken 7145 times.
✗ Branch 2 not taken.
14308 node.vertices1 = model1.vertices.get() ? model1.vertices->data() : NULL;
677
1/2
✓ Branch 1 taken 7145 times.
✗ Branch 2 not taken.
14308 node.vertices2 = model2.vertices.get() ? model2.vertices->data() : NULL;
678
679 14308 node.tri_indices1 =
680
1/2
✓ Branch 1 taken 7145 times.
✗ Branch 2 not taken.
14308 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
681 14308 node.tri_indices2 =
682
1/2
✓ Branch 1 taken 7145 times.
✗ Branch 2 not taken.
14308 model2.tri_indices.get() ? model2.tri_indices->data() : NULL;
683
684 COAL_COMPILER_DIAGNOSTIC_PUSH
685 COAL_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
686
687 14308 relativeTransform(tf1.getRotation(), tf1.getTranslation(), tf2.getRotation(),
688 14308 tf2.getTranslation(), node.RT.R, node.RT.T);
689
690 COAL_COMPILER_DIAGNOSTIC_POP
691
692 14308 return true;
693 }
694
695 /// @brief Initialize traversal node for distance computation between one mesh
696 /// and one shape, given the current transforms
697 template <typename BV, typename S>
698 bool initialize(MeshShapeDistanceTraversalNode<BV, S>& node,
699 BVHModel<BV>& model1, Transform3s& tf1, const S& model2,
700 const Transform3s& tf2, const GJKSolver* nsolver,
701 const DistanceRequest& request, DistanceResult& result,
702 bool use_refit = false, bool refit_bottomup = false) {
703 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
704 COAL_THROW_PRETTY(
705 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
706 std::invalid_argument)
707
708 if (!tf1.isIdentity() && model1.vertices.get()) {
709 const std::vector<Vec3s>& model1_vertices_ = *(model1.vertices);
710 std::vector<Vec3s> vertices_transformed1(model1.num_vertices);
711 for (unsigned int i = 0; i < model1.num_vertices; ++i) {
712 const Vec3s& p = model1_vertices_[i];
713 Vec3s new_v = tf1.transform(p);
714 vertices_transformed1[i] = new_v;
715 }
716
717 model1.beginReplaceModel();
718 model1.replaceSubModel(vertices_transformed1);
719 model1.endReplaceModel(use_refit, refit_bottomup);
720
721 tf1.setIdentity();
722 }
723
724 node.request = request;
725 node.result = &result;
726
727 node.model1 = &model1;
728 node.tf1 = tf1;
729 node.model2 = &model2;
730 node.tf2 = tf2;
731 node.nsolver = nsolver;
732
733 node.vertices = model1.vertices.get() ? model1.vertices->data() : NULL;
734 node.tri_indices =
735 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
736
737 computeBV(model2, tf2, node.model2_bv);
738
739 return true;
740 }
741
742 /// @cond IGNORE
743 namespace details {
744
745 template <typename BV, typename S, template <typename> class OrientedNode>
746 204 static inline bool setupMeshShapeDistanceOrientedNode(
747 OrientedNode<S>& node, const BVHModel<BV>& model1, const Transform3s& tf1,
748 const S& model2, const Transform3s& tf2, const GJKSolver* nsolver,
749 const DistanceRequest& request, DistanceResult& result) {
750
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
204 if (model1.getModelType() != BVH_MODEL_TRIANGLES)
751 COAL_THROW_PRETTY(
752 "model1 should be of type BVHModelType::BVH_MODEL_TRIANGLES.",
753 std::invalid_argument)
754
755 204 node.request = request;
756 204 node.result = &result;
757
758 204 node.model1 = &model1;
759 204 node.tf1 = tf1;
760 204 node.model2 = &model2;
761 204 node.tf2 = tf2;
762 204 node.nsolver = nsolver;
763
764 204 computeBV(model2, tf2, node.model2_bv);
765
766
1/2
✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
204 node.vertices = model1.vertices.get() ? model1.vertices->data() : NULL;
767 204 node.tri_indices =
768
1/2
✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
204 model1.tri_indices.get() ? model1.tri_indices->data() : NULL;
769
770 204 return true;
771 }
772 } // namespace details
773 /// @endcond
774
775 /// @brief Initialize traversal node for distance computation between one mesh
776 /// and one shape, specialized for RSS type
777 template <typename S>
778 bool initialize(MeshShapeDistanceTraversalNodeRSS<S>& node,
779 const BVHModel<RSS>& model1, const Transform3s& tf1,
780 const S& model2, const Transform3s& tf2,
781 const GJKSolver* nsolver, const DistanceRequest& request,
782 DistanceResult& result) {
783 return details::setupMeshShapeDistanceOrientedNode(
784 node, model1, tf1, model2, tf2, nsolver, request, result);
785 }
786
787 /// @brief Initialize traversal node for distance computation between one mesh
788 /// and one shape, specialized for kIOS type
789 template <typename S>
790 bool initialize(MeshShapeDistanceTraversalNodekIOS<S>& node,
791 const BVHModel<kIOS>& model1, const Transform3s& tf1,
792 const S& model2, const Transform3s& tf2,
793 const GJKSolver* nsolver, const DistanceRequest& request,
794 DistanceResult& result) {
795 return details::setupMeshShapeDistanceOrientedNode(
796 node, model1, tf1, model2, tf2, nsolver, request, result);
797 }
798
799 /// @brief Initialize traversal node for distance computation between one mesh
800 /// and one shape, specialized for OBBRSS type
801 template <typename S>
802 102 bool initialize(MeshShapeDistanceTraversalNodeOBBRSS<S>& node,
803 const BVHModel<OBBRSS>& model1, const Transform3s& tf1,
804 const S& model2, const Transform3s& tf2,
805 const GJKSolver* nsolver, const DistanceRequest& request,
806 DistanceResult& result) {
807 102 return details::setupMeshShapeDistanceOrientedNode(
808 102 node, model1, tf1, model2, tf2, nsolver, request, result);
809 }
810
811 } // namespace coal
812
813 /// @endcond
814
815 #endif
816