FCL  0.6.0
Flexible Collision Library
mesh_shape_distance_traversal_node-inl.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2016, 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 
38 #ifndef FCL_TRAVERSAL_MESHSHAPEDISTANCETRAVERSALNODE_INL_H
39 #define FCL_TRAVERSAL_MESHSHAPEDISTANCETRAVERSALNODE_INL_H
40 
41 #include "fcl/narrowphase/detail/traversal/distance/mesh_shape_distance_traversal_node.h"
42 
43 namespace fcl
44 {
45 
46 namespace detail
47 {
48 
49 //==============================================================================
50 template <typename BV, typename Shape, typename NarrowPhaseSolver>
51 MeshShapeDistanceTraversalNode<BV, Shape, NarrowPhaseSolver>::
52 MeshShapeDistanceTraversalNode()
53  : BVHShapeDistanceTraversalNode<BV, Shape>()
54 {
55  vertices = nullptr;
56  tri_indices = nullptr;
57 
58  rel_err = 0;
59  abs_err = 0;
60 
61  nsolver = nullptr;
62 }
63 
64 //==============================================================================
65 template <typename BV, typename Shape, typename NarrowPhaseSolver>
67 leafTesting(int b1, int b2) const
68 {
69  if(this->enable_statistics) this->num_leaf_tests++;
70 
71  const BVNode<BV>& node = this->model1->getBV(b1);
72 
73  int primitive_id = node.primitiveId();
74 
75  const Triangle& tri_id = tri_indices[primitive_id];
76 
77  const Vector3<S>& p1 = vertices[tri_id[0]];
78  const Vector3<S>& p2 = vertices[tri_id[1]];
79  const Vector3<S>& p3 = vertices[tri_id[2]];
80 
81  S d;
82  Vector3<S> closest_p1, closest_p2;
83  nsolver->shapeTriangleDistance(*(this->model2), this->tf2, p1, p2, p3, &d, &closest_p2, &closest_p1);
84 
85  this->result->update(
86  d,
87  this->model1,
88  this->model2,
89  primitive_id,
91  closest_p1,
92  closest_p2);
93 }
94 
95 //==============================================================================
96 template <typename BV, typename Shape, typename NarrowPhaseSolver>
98 canStop(S c) const
99 {
100  if((c >= this->result->min_distance - abs_err) && (c * (1 + rel_err) >= this->result->min_distance))
101  return true;
102  return false;
103 }
104 
105 //==============================================================================
106 template <typename BV, typename Shape, typename NarrowPhaseSolver>
107 bool initialize(
109  BVHModel<BV>& model1,
110  Transform3<typename Shape::S>& tf1,
111  const Shape& model2,
112  const Transform3<typename BV::S>& tf2,
113  const NarrowPhaseSolver* nsolver,
116  bool use_refit,
117  bool refit_bottomup)
118 {
119  using S = typename BV::S;
120 
121  if(model1.getModelType() != BVH_MODEL_TRIANGLES)
122  return false;
123 
124  if(!tf1.matrix().isIdentity())
125  {
126  std::vector<Vector3<S>> vertices_transformed1(model1.num_vertices);
127  for(int i = 0; i < model1.num_vertices; ++i)
128  {
129  Vector3<S>& p = model1.vertices[i];
130  Vector3<S> new_v = tf1 * p;
131  vertices_transformed1[i] = new_v;
132  }
133 
134  model1.beginReplaceModel();
135  model1.replaceSubModel(vertices_transformed1);
136  model1.endReplaceModel(use_refit, refit_bottomup);
137 
138  tf1.setIdentity();
139  }
140 
141  node.request = request;
142  node.result = &result;
143 
144  node.model1 = &model1;
145  node.tf1 = tf1;
146  node.model2 = &model2;
147  node.tf2 = tf2;
148  node.nsolver = nsolver;
149 
150  node.vertices = model1.vertices;
151  node.tri_indices = model1.tri_indices;
152 
153  computeBV(model2, tf2, node.model2_bv);
154 
155  return true;
156 }
157 
158 //==============================================================================
159 template <typename BV, typename Shape, typename NarrowPhaseSolver>
160 void meshShapeDistanceOrientedNodeLeafTesting(
161  int b1, int /* b2 */,
162  const BVHModel<BV>* model1, const Shape& model2,
163  Vector3<typename BV::S>* vertices, Triangle* tri_indices,
164  const Transform3<typename BV::S>& tf1,
165  const Transform3<typename BV::S>& tf2,
166  const NarrowPhaseSolver* nsolver,
167  bool enable_statistics,
168  int & num_leaf_tests,
169  const DistanceRequest<typename BV::S>& /* request */,
171 {
172  using S = typename BV::S;
173 
174  if(enable_statistics) num_leaf_tests++;
175 
176  const BVNode<BV>& node = model1->getBV(b1);
177  int primitive_id = node.primitiveId();
178 
179  const Triangle& tri_id = tri_indices[primitive_id];
180  const Vector3<S>& p1 = vertices[tri_id[0]];
181  const Vector3<S>& p2 = vertices[tri_id[1]];
182  const Vector3<S>& p3 = vertices[tri_id[2]];
183 
184  S distance;
185  Vector3<S> closest_p1, closest_p2;
186  nsolver->shapeTriangleDistance(model2, tf2, p1, p2, p3, tf1, &distance, &closest_p2, &closest_p1);
187 
188  result.update(
189  distance,
190  model1,
191  &model2,
192  primitive_id,
194  closest_p1,
195  closest_p2);
196 }
197 
198 //==============================================================================
199 template <typename BV, typename Shape, typename NarrowPhaseSolver>
200 void distancePreprocessOrientedNode(
201  const BVHModel<BV>* model1,
202  Vector3<typename BV::S>* vertices,
203  Triangle* tri_indices,
204  int init_tri_id,
205  const Shape& model2,
206  const Transform3<typename BV::S>& tf1,
207  const Transform3<typename BV::S>& tf2,
208  const NarrowPhaseSolver* nsolver,
209  const DistanceRequest<typename BV::S>& /* request */,
211 {
212  using S = typename BV::S;
213 
214  const Triangle& init_tri = tri_indices[init_tri_id];
215 
216  const Vector3<S>& p1 = vertices[init_tri[0]];
217  const Vector3<S>& p2 = vertices[init_tri[1]];
218  const Vector3<S>& p3 = vertices[init_tri[2]];
219 
220  S distance;
221  Vector3<S> closest_p1, closest_p2;
222  nsolver->shapeTriangleDistance(model2, tf2, p1, p2, p3, tf1, &distance, &closest_p2, &closest_p1);
223 
224  result.update(
225  distance,
226  model1,
227  &model2,
228  init_tri_id,
230  closest_p1,
231  closest_p2);
232 }
233 
234 //==============================================================================
235 template <typename Shape, typename NarrowPhaseSolver>
239  RSS<typename Shape::S>, Shape, NarrowPhaseSolver>()
240 {
241 }
242 
243 //==============================================================================
244 template <typename Shape, typename NarrowPhaseSolver>
246 {
247  detail::distancePreprocessOrientedNode(
248  this->model1,
249  this->vertices,
250  this->tri_indices,
251  0,
252  *(this->model2),
253  this->tf1,
254  this->tf2,
255  this->nsolver,
256  this->request,
257  *(this->result));
258 }
259 
260 //==============================================================================
261 template <typename Shape, typename NarrowPhaseSolver>
263 {
264 }
265 
266 //==============================================================================
267 template <typename Shape, typename NarrowPhaseSolver>
268 typename Shape::S
270  int b1, int b2) const
271 {
272  if(this->enable_statistics) this->num_bv_tests++;
273 
274  return distance(this->tf1.linear(), this->tf1.translation(), this->model2_bv, this->model1->getBV(b1).bv);
275 }
276 
277 //==============================================================================
278 template <typename Shape, typename NarrowPhaseSolver>
280 leafTesting(int b1, int b2) const
281 {
282  detail::meshShapeDistanceOrientedNodeLeafTesting(
283  b1,
284  b2,
285  this->model1,
286  *(this->model2),
287  this->vertices,
288  this->tri_indices,
289  this->tf1,
290  this->tf2,
291  this->nsolver,
292  this->enable_statistics,
293  this->num_leaf_tests,
294  this->request,
295  *(this->result));
296 }
297 
298 //==============================================================================
299 template <typename Shape, typename NarrowPhaseSolver>
301 {
302 }
303 
304 //==============================================================================
305 template <typename Shape, typename NarrowPhaseSolver>
307 {
308  detail::distancePreprocessOrientedNode(this->model1, this->vertices, this->tri_indices, 0,
309  *(this->model2), this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
310 }
311 
312 //==============================================================================
313 template <typename Shape, typename NarrowPhaseSolver>
315 {
316 }
317 
318 //==============================================================================
319 template <typename Shape, typename NarrowPhaseSolver>
321 {
322  if(this->enable_statistics) this->num_bv_tests++;
323 
324  return distance(this->tf1.linear(), this->tf1.translation(), this->model2_bv, this->model1->getBV(b1).bv);
325 }
326 
327 //==============================================================================
328 template <typename Shape, typename NarrowPhaseSolver>
330 {
331  detail::meshShapeDistanceOrientedNodeLeafTesting(b1, b2, this->model1, *(this->model2), this->vertices, this->tri_indices,
332  this->tf1, this->tf2, this->nsolver, this->enable_statistics, this->num_leaf_tests, this->request, *(this->result));
333 }
334 
335 //==============================================================================
336 template <typename Shape, typename NarrowPhaseSolver>
338 {
339 }
340 
341 //==============================================================================
342 template <typename Shape, typename NarrowPhaseSolver>
344 {
345  detail::distancePreprocessOrientedNode(this->model1, this->vertices, this->tri_indices, 0,
346  *(this->model2), this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
347 }
348 
349 //==============================================================================
350 template <typename Shape, typename NarrowPhaseSolver>
352 {
353 
354 }
355 
356 //==============================================================================
357 template <typename Shape, typename NarrowPhaseSolver>
358 typename Shape::S
360 BVTesting(int b1, int b2) const
361 {
362  if(this->enable_statistics) this->num_bv_tests++;
363 
364  return distance(this->tf1.linear(), this->tf1.translation(), this->model2_bv, this->model1->getBV(b1).bv);
365 }
366 
367 //==============================================================================
368 template <typename Shape, typename NarrowPhaseSolver>
370 {
371  detail::meshShapeDistanceOrientedNodeLeafTesting(b1, b2, this->model1, *(this->model2), this->vertices, this->tri_indices,
372  this->tf1, this->tf2, this->nsolver, this->enable_statistics, this->num_leaf_tests, this->request, *(this->result));
373 }
374 
375 template <typename BV, typename Shape, typename NarrowPhaseSolver, template <typename, typename> class OrientedNode>
376 static bool setupMeshShapeDistanceOrientedNode(OrientedNode<Shape, NarrowPhaseSolver>& node,
377  const BVHModel<BV>& model1, const Transform3<typename BV::S>& tf1,
378  const Shape& model2, const Transform3<typename BV::S>& tf2,
379  const NarrowPhaseSolver* nsolver,
380  const DistanceRequest<typename BV::S>& request,
382 {
383  if(model1.getModelType() != BVH_MODEL_TRIANGLES)
384  return false;
385 
386  node.request = request;
387  node.result = &result;
388 
389  node.model1 = &model1;
390  node.tf1 = tf1;
391  node.model2 = &model2;
392  node.tf2 = tf2;
393  node.nsolver = nsolver;
394 
395  computeBV(model2, tf2, node.model2_bv);
396 
397  node.vertices = model1.vertices;
398  node.tri_indices = model1.tri_indices;
399 
400  return true;
401 }
402 
403 //==============================================================================
404 template <typename Shape, typename NarrowPhaseSolver>
405 bool initialize(
407  const BVHModel<RSS<typename Shape::S>>& model1, const Transform3<typename Shape::S>& tf1,
408  const Shape& model2, const Transform3<typename Shape::S>& tf2,
409  const NarrowPhaseSolver* nsolver,
410  const DistanceRequest<typename Shape::S>& request,
412 {
413  return detail::setupMeshShapeDistanceOrientedNode(node, model1, tf1, model2, tf2, nsolver, request, result);
414 }
415 
416 //==============================================================================
417 template <typename Shape, typename NarrowPhaseSolver>
418 bool initialize(
420  const BVHModel<kIOS<typename Shape::S>>& model1, const Transform3<typename Shape::S>& tf1,
421  const Shape& model2, const Transform3<typename Shape::S>& tf2,
422  const NarrowPhaseSolver* nsolver,
423  const DistanceRequest<typename Shape::S>& request,
425 {
426  return detail::setupMeshShapeDistanceOrientedNode(node, model1, tf1, model2, tf2, nsolver, request, result);
427 }
428 
429 //==============================================================================
430 template <typename Shape, typename NarrowPhaseSolver>
431 bool initialize(
433  const BVHModel<OBBRSS<typename Shape::S>>& model1, const Transform3<typename Shape::S>& tf1,
434  const Shape& model2, const Transform3<typename Shape::S>& tf2,
435  const NarrowPhaseSolver* nsolver,
436  const DistanceRequest<typename Shape::S>& request,
438 {
439  return detail::setupMeshShapeDistanceOrientedNode(node, model1, tf1, model2, tf2, nsolver, request, result);
440 }
441 
442 } // namespace detail
443 } // namespace fcl
444 
445 #endif
bool canStop(S c) const
Whether the traversal process can stop early.
Definition: mesh_shape_distance_traversal_node-inl.h:98
S min_distance
minimum distance between two objects. if two objects are in collision, min_distance <= 0...
Definition: distance_result.h:56
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: mesh_shape_distance_traversal_node-inl.h:369
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
int replaceSubModel(const std::vector< Vector3< S >> &ps)
Replace a set of points in the old BVH model.
Definition: BVH_model-inl.h:559
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: mesh_shape_distance_traversal_node-inl.h:269
A class for rectangle sphere-swept bounding volume.
Definition: RSS.h:49
Traversal node for distance between mesh and shape.
Definition: mesh_shape_distance_traversal_node.h:52
int beginReplaceModel()
Replace the geometry information of current frame (i.e. should have the same mesh topology with the p...
Definition: BVH_model-inl.h:508
BVHModelType getModelType() const
Model type described by the instance.
Definition: BVH_model-inl.h:48
distance result
Definition: distance_request.h:48
void update(S distance, const CollisionGeometry< S > *o1_, const CollisionGeometry< S > *o2_, int b1_, int b2_)
add distance information into the result
Definition: distance_result-inl.h:64
const BVNode< BV > & getBV(int id) const
We provide getBV() and getNumBVs() because BVH may be compressed (in future), so we must provide some...
Definition: BVH_model-inl.h:160
Transform3< OBBRSS< Shape::S >::S > tf2
configuration of second object
Definition: traversal_node_base.h:88
Vector3< S > * vertices
Geometry point data.
Definition: BVH_model.h:162
int num_vertices
Number of points.
Definition: BVH_model.h:174
int primitiveId() const
Return the primitive index. The index is referred to the original data (i.e. vertices or tri_indices)...
Definition: BV_node_base.cpp:50
Triangle * tri_indices
Geometry triangle index data, will be nullptr for point clouds.
Definition: BVH_model.h:165
Triangle with 3 indices for points.
Definition: triangle.h:47
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: mesh_shape_distance_traversal_node-inl.h:360
unknown model type
Definition: BVH_internal.h:78
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: mesh_shape_distance_traversal_node-inl.h:329
void computeBV(const Shape &s, const Transform3< typename BV::S > &tf, BV &bv)
calculate a bounding volume for a shape in a specific configuration
Definition: utility-inl.h:1049
DistanceRequest< OBBRSS< Shape::S >::S > request
request setting for distance
Definition: distance_traversal_node_base.h:73
Traversal node for distance between mesh and shape, when mesh BVH is one of the oriented node (RSS...
Definition: mesh_shape_distance_traversal_node.h:121
Definition: mesh_shape_distance_traversal_node.h:151
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: mesh_shape_distance_traversal_node-inl.h:280
Definition: mesh_shape_distance_traversal_node.h:180
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
Definition: BVH_model.h:57
void leafTesting(int b1, int b2) const
Distance testing between leaves (one triangle and one shape)
Definition: mesh_shape_distance_traversal_node-inl.h:67
DistanceResult< OBBRSS< Shape::S >::S > * result
distance result kept during the traversal iteration
Definition: distance_traversal_node_base.h:76
A class describing a bounding volume node. It includes the tree structure providing in BVNodeBase and...
Definition: BV_node.h:52
Transform3< OBBRSS< Shape::S >::S > tf1
configuation of first object
Definition: traversal_node_base.h:85
S distance(const Eigen::MatrixBase< DerivedA > &R0, const Eigen::MatrixBase< DerivedB > &T0, const kIOS< S > &b1, const kIOS< S > &b2, Vector3< S > *P, Vector3< S > *Q)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS-inl.h:266
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: mesh_shape_distance_traversal_node-inl.h:320
Class merging the OBB and RSS, can handle collision and distance simultaneously.
Definition: OBBRSS.h:50
request to the distance computation
Definition: distance_request.h:52
int endReplaceModel(bool refit=true, bool bottomup=true)
End BVH model replacement, will also refit or rebuild the bounding volume hierarchy.
Definition: BVH_model-inl.h:577
bool enable_statistics
Whether stores statistics.
Definition: distance_traversal_node_base.h:79
A class describing the kIOS collision structure, which is a set of spheres.
Definition: kIOS.h:48