FCL  0.6.0
Flexible Collision Library
shape_mesh_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_SHAPEMESHDISTANCETRAVERSALNODE_INL_H
39 #define FCL_TRAVERSAL_SHAPEMESHDISTANCETRAVERSALNODE_INL_H
40 
41 #include "fcl/narrowphase/detail/traversal/distance/shape_mesh_distance_traversal_node.h"
42 
43 namespace fcl
44 {
45 
46 namespace detail
47 {
48 
49 //==============================================================================
50 template <typename Shape, typename BV, typename NarrowPhaseSolver>
51 ShapeMeshDistanceTraversalNode<Shape, BV, NarrowPhaseSolver>::
52 ShapeMeshDistanceTraversalNode()
53  : ShapeBVHDistanceTraversalNode<Shape, BV>()
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 Shape, typename BV, typename NarrowPhaseSolver>
67 {
68  using S = typename BV::S;
69 
70  if(this->enable_statistics) this->num_leaf_tests++;
71 
72  const BVNode<BV>& node = this->model2->getBV(b2);
73 
74  int primitive_id = node.primitiveId();
75 
76  const Triangle& tri_id = tri_indices[primitive_id];
77 
78  const Vector3<S>& p1 = vertices[tri_id[0]];
79  const Vector3<S>& p2 = vertices[tri_id[1]];
80  const Vector3<S>& p3 = vertices[tri_id[2]];
81 
82  S distance;
83  Vector3<S> closest_p1, closest_p2;
84  nsolver->shapeTriangleDistance(*(this->model1), this->tf1, p1, p2, p3, &distance, &closest_p1, &closest_p2);
85 
86  this->result->update(
87  distance,
88  this->model1,
89  this->model2,
91  primitive_id,
92  closest_p1,
93  closest_p2);
94 }
95 
96 //==============================================================================
97 template <typename Shape, typename BV, typename NarrowPhaseSolver>
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 Shape, typename BV, typename NarrowPhaseSolver>
107 bool initialize(
109  const Shape& model1,
110  const Transform3<typename BV::S>& tf1,
111  BVHModel<BV>& model2,
112  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(model2.getModelType() != BVH_MODEL_TRIANGLES)
122  return false;
123 
124  if(!tf2.matrix().isIdentity())
125  {
126  std::vector<Vector3<S>> vertices_transformed(model2.num_vertices);
127  for(int i = 0; i < model2.num_vertices; ++i)
128  {
129  Vector3<S>& p = model2.vertices[i];
130  Vector3<S> new_v = tf2 * p;
131  vertices_transformed[i] = new_v;
132  }
133 
134  model2.beginReplaceModel();
135  model2.replaceSubModel(vertices_transformed);
136  model2.endReplaceModel(use_refit, refit_bottomup);
137 
138  tf2.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 = model2.vertices;
151  node.tri_indices = model2.tri_indices;
152 
153  computeBV(model1, tf1, node.model1_bv);
154 
155  return true;
156 }
157 
158 //==============================================================================
159 template <typename Shape, typename NarrowPhaseSolver>
161  : ShapeMeshDistanceTraversalNode<Shape, RSS<S>, NarrowPhaseSolver>()
162 {
163 }
164 
165 //==============================================================================
166 template <typename Shape, typename NarrowPhaseSolver>
168 {
169  detail::distancePreprocessOrientedNode(
170  this->model2, this->vertices, this->tri_indices, 0,
171  *(this->model1), this->tf2, this->tf1, this->nsolver, this->request, *(this->result));
172 }
173 
174 //==============================================================================
175 template <typename Shape, typename NarrowPhaseSolver>
177 {
178 }
179 
180 //==============================================================================
181 template <typename Shape, typename NarrowPhaseSolver>
182 typename Shape::S
184 BVTesting(int b1, int b2) const
185 {
186  if(this->enable_statistics) this->num_bv_tests++;
187  return distance(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
188 }
189 
190 //==============================================================================
191 template <typename Shape, typename NarrowPhaseSolver>
193 leafTesting(int b1, int b2) const
194 {
195  detail::meshShapeDistanceOrientedNodeLeafTesting(b2, b1, this->model2, *(this->model1), this->vertices, this->tri_indices,
196  this->tf2, this->tf1, this->nsolver, this->enable_statistics, this->num_leaf_tests, this->request, *(this->result));
197 }
198 
199 //==============================================================================
200 template <typename Shape, typename NarrowPhaseSolver>
203  : ShapeMeshDistanceTraversalNode<Shape, kIOS<S>, NarrowPhaseSolver>()
204 {
205 }
206 
207 //==============================================================================
208 template <typename Shape, typename NarrowPhaseSolver>
210 {
211  detail::distancePreprocessOrientedNode(
212  this->model2,
213  this->vertices,
214  this->tri_indices,
215  0,
216  *(this->model1),
217  this->tf2,
218  this->tf1,
219  this->nsolver,
220  *(this->result));
221 }
222 
223 //==============================================================================
224 template <typename Shape, typename NarrowPhaseSolver>
226 {
227 }
228 
229 //==============================================================================
230 template <typename Shape, typename NarrowPhaseSolver>
231 typename Shape::S
233 BVTesting(int b1, int b2) const
234 {
235  if(this->enable_statistics) this->num_bv_tests++;
236  return distance(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
237 }
238 
239 //==============================================================================
240 template <typename Shape, typename NarrowPhaseSolver>
242 leafTesting(int b1, int b2) const
243 {
244  detail::meshShapeDistanceOrientedNodeLeafTesting(b2, b1, this->model2, *(this->model1), this->vertices, this->tri_indices,
245  this->tf2, this->tf1, this->nsolver, this->enable_statistics, this->num_leaf_tests, this->request, *(this->result));
246 }
247 
248 //==============================================================================
249 template <typename Shape, typename NarrowPhaseSolver>
252 {
253 }
254 
255 //==============================================================================
256 template <typename Shape, typename NarrowPhaseSolver>
258 {
259  detail::distancePreprocessOrientedNode(
260  this->model2,
261  this->vertices,
262  this->tri_indices,
263  0,
264  *(this->model1),
265  this->tf2,
266  this->tf1,
267  this->nsolver,
268  *(this->result));
269 }
270 
271 //==============================================================================
272 template <typename Shape, typename NarrowPhaseSolver>
274 postprocess()
275 {
276 }
277 
278 //==============================================================================
279 template <typename Shape, typename NarrowPhaseSolver>
280 typename Shape::S
282 BVTesting(int b1, int b2) const
283 {
284  if(this->enable_statistics) this->num_bv_tests++;
285  return distance(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
286 }
287 
288 //==============================================================================
289 template <typename Shape, typename NarrowPhaseSolver>
291 leafTesting(int b1, int b2) const
292 {
293  detail::meshShapeDistanceOrientedNodeLeafTesting(
294  b2,
295  b1,
296  this->model2,
297  *(this->model1),
298  this->vertices,
299  this->tri_indices,
300  this->tf2,
301  this->tf1,
302  this->nsolver,
303  this->enable_statistics,
304  this->num_leaf_tests,
305  this->request,
306  *(this->result));
307 }
308 
309 template <typename Shape, typename BV, typename NarrowPhaseSolver, template <typename, typename> class OrientedNode>
310 static bool setupShapeMeshDistanceOrientedNode(OrientedNode<Shape, NarrowPhaseSolver>& node,
311  const Shape& model1, const Transform3<typename BV::S>& tf1,
312  const BVHModel<BV>& model2, const Transform3<typename BV::S>& tf2,
313  const NarrowPhaseSolver* nsolver,
314  const DistanceRequest<typename BV::S>& request,
316 {
317  if(model2.getModelType() != BVH_MODEL_TRIANGLES)
318  return false;
319 
320  node.request = request;
321  node.result = &result;
322 
323  node.model1 = &model1;
324  node.tf1 = tf1;
325  node.model2 = &model2;
326  node.tf2 = tf2;
327  node.nsolver = nsolver;
328 
329  computeBV(model1, tf1, node.model1_bv);
330 
331  node.vertices = model2.vertices;
332  node.tri_indices = model2.tri_indices;
333  node.R = tf2.linear();
334  node.T = tf2.translation();
335 
336  return true;
337 }
338 
339 //==============================================================================
340 template <typename Shape, typename NarrowPhaseSolver>
342  const Shape& model1, const Transform3<typename Shape::S>& tf1,
343  const BVHModel<RSS<typename Shape::S>>& model2, const Transform3<typename Shape::S>& tf2,
344  const NarrowPhaseSolver* nsolver,
345  const DistanceRequest<typename Shape::S>& request,
347 {
348  return detail::setupShapeMeshDistanceOrientedNode(node, model1, tf1, model2, tf2, nsolver, request, result);
349 }
350 
351 //==============================================================================
352 template <typename Shape, typename NarrowPhaseSolver>
354  const Shape& model1, const Transform3<typename Shape::S>& tf1,
355  const BVHModel<kIOS<typename Shape::S>>& model2, const Transform3<typename Shape::S>& tf2,
356  const NarrowPhaseSolver* nsolver,
357  const DistanceRequest<typename Shape::S>& request,
359 {
360  return detail::setupShapeMeshDistanceOrientedNode(node, model1, tf1, model2, tf2, nsolver, request, result);
361 }
362 
363 //==============================================================================
364 template <typename Shape, typename NarrowPhaseSolver>
366  const Shape& model1, const Transform3<typename Shape::S>& tf1,
367  const BVHModel<OBBRSS<typename Shape::S>>& model2, const Transform3<typename Shape::S>& tf2,
368  const NarrowPhaseSolver* nsolver,
369  const DistanceRequest<typename Shape::S>& request,
371 {
372  return detail::setupShapeMeshDistanceOrientedNode(node, model1, tf1, model2, tf2, nsolver, request, result);
373 }
374 
375 } // namespace detail
376 } // namespace fcl
377 
378 #endif
Definition: shape_mesh_distance_traversal_node.h:92
Traversal node for distance between shape and mesh.
Definition: shape_mesh_distance_traversal_node.h:52
S min_distance
minimum distance between two objects. if two objects are in collision, min_distance <= 0...
Definition: distance_result.h:56
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_distance_traversal_node-inl.h:184
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
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_distance_traversal_node-inl.h:291
Definition: shape_mesh_distance_traversal_node.h:126
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_distance_traversal_node-inl.h:233
A class for rectangle sphere-swept bounding volume.
Definition: RSS.h:49
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_distance_traversal_node-inl.h:242
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
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_distance_traversal_node-inl.h:282
Vector3< S > * vertices
Geometry point data.
Definition: BVH_model.h:162
Definition: shape_mesh_distance_traversal_node.h:160
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
bool canStop(S c) const
Whether the traversal process can stop early.
Definition: shape_mesh_distance_traversal_node-inl.h:98
unknown model type
Definition: BVH_internal.h:78
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
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 shape and one triangle)
Definition: shape_mesh_distance_traversal_node-inl.h:66
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
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
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_distance_traversal_node-inl.h:193
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