GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: python/collision.cc Lines: 95 108 88.0 %
Date: 2024-02-09 12:57:42 Branches: 83 166 50.0 %

Line Branch Exec Source
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
}