1 |
|
|
// |
2 |
|
|
// Software License Agreement (BSD License) |
3 |
|
|
// |
4 |
|
|
// Copyright (c) 2019-2021 CNRS-LAAS, INRIA |
5 |
|
|
// Author: Joseph Mirabel |
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 CNRS-LAAS. 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 |
|
|
#include <eigenpy/eigenpy.hpp> |
36 |
|
|
|
37 |
|
|
#include <hpp/fcl/fwd.hh> |
38 |
|
|
#include <hpp/fcl/collision.h> |
39 |
|
|
|
40 |
|
|
#include "fcl.hh" |
41 |
|
|
#include "deprecation.hh" |
42 |
|
|
|
43 |
|
|
#ifdef HPP_FCL_HAS_DOXYGEN_AUTODOC |
44 |
|
|
#include "doxygen_autodoc/functions.h" |
45 |
|
|
#include "doxygen_autodoc/hpp/fcl/collision_data.h" |
46 |
|
|
#endif |
47 |
|
|
|
48 |
|
|
#include "../doc/python/doxygen.hh" |
49 |
|
|
#include "../doc/python/doxygen-boost.hh" |
50 |
|
|
|
51 |
|
|
using namespace boost::python; |
52 |
|
|
using namespace hpp::fcl; |
53 |
|
|
using namespace hpp::fcl::python; |
54 |
|
|
|
55 |
|
|
namespace dv = doxygen::visitor; |
56 |
|
|
|
57 |
|
|
template <int index> |
58 |
|
|
const CollisionGeometry* geto(const Contact& c) { |
59 |
|
|
return index == 1 ? c.o1 : c.o2; |
60 |
|
|
} |
61 |
|
|
|
62 |
|
5 |
void exposeCollisionAPI() { |
63 |
|
5 |
if (!eigenpy::register_symbolic_link_to_registered_type< |
64 |
✓✗ |
5 |
CollisionRequestFlag>()) { |
65 |
|
10 |
enum_<CollisionRequestFlag>("CollisionRequestFlag") |
66 |
✓✗ |
5 |
.value("CONTACT", CONTACT) |
67 |
✓✗ |
5 |
.value("DISTANCE_LOWER_BOUND", DISTANCE_LOWER_BOUND) |
68 |
✓✗ |
5 |
.value("NO_REQUEST", NO_REQUEST) |
69 |
✓✗ |
5 |
.export_values(); |
70 |
|
|
} |
71 |
|
|
|
72 |
✓✗ |
5 |
if (!eigenpy::register_symbolic_link_to_registered_type<CPUTimes>()) { |
73 |
|
10 |
class_<CPUTimes>("CPUTimes", no_init) |
74 |
|
|
.def_readonly("wall", &CPUTimes::wall, |
75 |
✓✗ |
5 |
"wall time in micro seconds (us)") |
76 |
|
|
.def_readonly("user", &CPUTimes::user, |
77 |
✓✗ |
5 |
"user time in micro seconds (us)") |
78 |
|
|
.def_readonly("system", &CPUTimes::system, |
79 |
✓✗ |
5 |
"system time in micro seconds (us)") |
80 |
✓✗✓✗
|
5 |
.def("clear", &CPUTimes::clear, arg("self"), "Reset the time values."); |
81 |
|
|
} |
82 |
|
|
|
83 |
✓✗ |
5 |
if (!eigenpy::register_symbolic_link_to_registered_type<QueryRequest>()) { |
84 |
|
10 |
class_<QueryRequest>("QueryRequest", doxygen::class_doc<QueryRequest>(), |
85 |
|
|
no_init) |
86 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_tolerance) |
87 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_max_iterations) |
88 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_variant) |
89 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_convergence_criterion) |
90 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_convergence_criterion_type) |
91 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_initial_guess) |
92 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, enable_cached_gjk_guess) |
93 |
|
|
.add_property( |
94 |
|
|
"enable_cached_gjk_guess", |
95 |
✓✗ |
5 |
bp::make_function( |
96 |
|
|
+[](QueryRequest& self) -> bool { |
97 |
|
|
return self.enable_cached_gjk_guess; |
98 |
|
|
}, |
99 |
✓✗✓✗
|
10 |
deprecated_warning_policy<>( |
100 |
|
|
"enable_cached_gjk_guess has been marked as deprecated and " |
101 |
|
|
"will be removed in a future release.\n" |
102 |
|
|
"Please use gjk_initial_guess instead.")), |
103 |
✓✗ |
10 |
bp::make_function( |
104 |
|
|
+[](QueryRequest& self, const bool value) -> void { |
105 |
|
|
self.enable_cached_gjk_guess = value; |
106 |
|
|
}, |
107 |
✓✗✓✗
|
10 |
deprecated_warning_policy<>( |
108 |
|
|
"enable_cached_gjk_guess has been marked as deprecated and " |
109 |
|
|
"will be removed in a future release.\n" |
110 |
|
|
"Please use gjk_initial_guess instead.")), |
111 |
✓✗ |
10 |
doxygen::class_attrib_doc<QueryRequest>("enable_cached_gjk_guess")) |
112 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, cached_gjk_guess) |
113 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, cached_support_func_guess) |
114 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryRequest, enable_timings) |
115 |
✓✗✓✗
|
5 |
.DEF_CLASS_FUNC(QueryRequest, updateGuess); |
116 |
|
|
} |
117 |
|
|
|
118 |
✓✗ |
5 |
if (!eigenpy::register_symbolic_link_to_registered_type<CollisionRequest>()) { |
119 |
|
10 |
class_<CollisionRequest, bases<QueryRequest> >( |
120 |
|
|
"CollisionRequest", doxygen::class_doc<CollisionRequest>(), no_init) |
121 |
✓✗ |
5 |
.def(dv::init<CollisionRequest>()) |
122 |
✓✗ |
5 |
.def(dv::init<CollisionRequest, const CollisionRequestFlag, size_t>()) |
123 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(CollisionRequest, num_max_contacts) |
124 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(CollisionRequest, enable_contact) |
125 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(CollisionRequest, enable_distance_lower_bound) |
126 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(CollisionRequest, security_margin) |
127 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(CollisionRequest, break_distance) |
128 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(CollisionRequest, distance_upper_bound); |
129 |
|
|
} |
130 |
|
|
|
131 |
|
5 |
if (!eigenpy::register_symbolic_link_to_registered_type< |
132 |
✓✗ |
5 |
std::vector<CollisionRequest> >()) { |
133 |
|
10 |
class_<std::vector<CollisionRequest> >("StdVec_CollisionRequest") |
134 |
✓✗ |
5 |
.def(vector_indexing_suite<std::vector<CollisionRequest> >()); |
135 |
|
|
} |
136 |
|
|
|
137 |
✓✗ |
5 |
if (!eigenpy::register_symbolic_link_to_registered_type<Contact>()) { |
138 |
✓✗ |
5 |
class_<Contact>("Contact", doxygen::class_doc<Contact>(), |
139 |
✓✗ |
10 |
init<>(arg("self"), "Default constructor")) |
140 |
|
|
.def(dv::init<Contact, const CollisionGeometry*, |
141 |
✓✗ |
5 |
const CollisionGeometry*, int, int>()) |
142 |
|
|
.def(dv::init<Contact, const CollisionGeometry*, |
143 |
|
|
const CollisionGeometry*, int, int, const Vec3f&, |
144 |
✓✗ |
5 |
const Vec3f&, FCL_REAL>()) |
145 |
|
|
.add_property( |
146 |
|
|
"o1", |
147 |
✓✗ |
5 |
make_function(&geto<1>, |
148 |
|
5 |
return_value_policy<reference_existing_object>()), |
149 |
✓✗ |
10 |
doxygen::class_attrib_doc<Contact>("o1")) |
150 |
|
|
.add_property( |
151 |
|
|
"o2", |
152 |
✓✗ |
5 |
make_function(&geto<2>, |
153 |
|
5 |
return_value_policy<reference_existing_object>()), |
154 |
✓✗ |
10 |
doxygen::class_attrib_doc<Contact>("o2")) |
155 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(Contact, b1) |
156 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(Contact, b2) |
157 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(Contact, normal) |
158 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(Contact, pos) |
159 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(Contact, penetration_depth) |
160 |
✓✗ |
5 |
.def(self == self) |
161 |
✓✗ |
5 |
.def(self != self); |
162 |
|
|
} |
163 |
|
|
|
164 |
|
5 |
if (!eigenpy::register_symbolic_link_to_registered_type< |
165 |
✓✗ |
5 |
std::vector<Contact> >()) { |
166 |
|
10 |
class_<std::vector<Contact> >("StdVec_Contact") |
167 |
✓✗ |
5 |
.def(vector_indexing_suite<std::vector<Contact> >()); |
168 |
|
|
} |
169 |
|
|
|
170 |
✓✗ |
5 |
if (!eigenpy::register_symbolic_link_to_registered_type<QueryResult>()) { |
171 |
|
10 |
class_<QueryResult>("QueryResult", doxygen::class_doc<QueryResult>(), |
172 |
|
|
no_init) |
173 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryResult, cached_gjk_guess) |
174 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryResult, cached_support_func_guess) |
175 |
✓✗ |
5 |
.DEF_RW_CLASS_ATTRIB(QueryResult, timings); |
176 |
|
|
} |
177 |
|
|
|
178 |
✓✗ |
5 |
if (!eigenpy::register_symbolic_link_to_registered_type<CollisionResult>()) { |
179 |
|
10 |
class_<CollisionResult, bases<QueryResult> >( |
180 |
|
|
"CollisionResult", doxygen::class_doc<CollisionResult>(), no_init) |
181 |
✓✗ |
5 |
.def(dv::init<CollisionResult>()) |
182 |
✓✗✓✗
|
5 |
.DEF_CLASS_FUNC(CollisionResult, isCollision) |
183 |
✓✗✓✗
|
5 |
.DEF_CLASS_FUNC(CollisionResult, numContacts) |
184 |
✓✗✓✗
|
5 |
.DEF_CLASS_FUNC(CollisionResult, addContact) |
185 |
✓✗✓✗
|
5 |
.DEF_CLASS_FUNC(CollisionResult, clear) |
186 |
✓✗ |
5 |
.DEF_CLASS_FUNC2(CollisionResult, getContact, |
187 |
|
|
return_value_policy<copy_const_reference>()) |
188 |
|
|
.def(dv::member_func( |
189 |
|
|
"getContacts", |
190 |
|
|
static_cast<void (CollisionResult::*)(std::vector<Contact>&) const>( |
191 |
✓✗✓✗
|
5 |
&CollisionResult::getContacts))) |
192 |
|
|
.def("getContacts", |
193 |
|
|
static_cast<const std::vector<Contact>& (CollisionResult::*)() |
194 |
|
|
const>(&CollisionResult::getContacts), |
195 |
|
5 |
doxygen::member_func_doc( |
196 |
|
|
static_cast<const std::vector<Contact>& (CollisionResult::*)() |
197 |
|
|
const>(&CollisionResult::getContacts)), |
198 |
|
|
return_internal_reference<>()) |
199 |
|
|
|
200 |
✓✗✓✗
|
5 |
.DEF_RW_CLASS_ATTRIB(CollisionResult, distance_lower_bound); |
201 |
|
|
} |
202 |
|
|
|
203 |
|
5 |
if (!eigenpy::register_symbolic_link_to_registered_type< |
204 |
✓✗ |
5 |
std::vector<CollisionResult> >()) { |
205 |
|
10 |
class_<std::vector<CollisionResult> >("StdVec_CollisionResult") |
206 |
✓✗ |
5 |
.def(vector_indexing_suite<std::vector<CollisionResult> >()); |
207 |
|
|
} |
208 |
|
|
|
209 |
|
5 |
doxygen::def("collide", |
210 |
|
|
static_cast<std::size_t (*)( |
211 |
|
|
const CollisionObject*, const CollisionObject*, |
212 |
|
|
const CollisionRequest&, CollisionResult&)>(&collide)); |
213 |
|
5 |
doxygen::def( |
214 |
|
|
"collide", |
215 |
|
|
static_cast<std::size_t (*)(const CollisionGeometry*, const Transform3f&, |
216 |
|
|
const CollisionGeometry*, const Transform3f&, |
217 |
|
|
CollisionRequest&, CollisionResult&)>( |
218 |
|
|
&collide)); |
219 |
|
|
|
220 |
|
5 |
class_<ComputeCollision>("ComputeCollision", |
221 |
|
|
doxygen::class_doc<ComputeCollision>(), no_init) |
222 |
|
|
.def(dv::init<ComputeCollision, const CollisionGeometry*, |
223 |
✓✗ |
10 |
const CollisionGeometry*>()) |
224 |
|
5 |
.def("__call__", |
225 |
|
|
static_cast<std::size_t (ComputeCollision::*)( |
226 |
|
|
const Transform3f&, const Transform3f&, CollisionRequest&, |
227 |
✓✗ |
5 |
CollisionResult&) const>(&ComputeCollision::operator())); |
228 |
|
5 |
} |