diff --git a/docs/source/cpp-api/candidates.rst b/docs/source/cpp-api/candidates.rst index d51ac008d..f1b8d279b 100644 --- a/docs/source/cpp-api/candidates.rst +++ b/docs/source/cpp-api/candidates.rst @@ -14,13 +14,6 @@ Collision Stencil :allow-dot-graphs: -Continuous Collision Candidate ------------------------------- - -.. doxygenclass:: ipc::ContinuousCollisionCandidate - :allow-dot-graphs: - - Vertex-Vertex Candidate ----------------------- diff --git a/docs/source/python-api/candidates.rst b/docs/source/python-api/candidates.rst index d575f540e..8c83fe75c 100644 --- a/docs/source/python-api/candidates.rst +++ b/docs/source/python-api/candidates.rst @@ -16,13 +16,6 @@ Collision Stencil .. .. autoclass:: ipctk.CollisionStencil -Continuous Collision Candidate ------------------------------- - -.. autoclass:: ipctk.ContinuousCollisionCandidate - - .. autoclasstoc:: - Vertex-Vertex Candidate ----------------------- diff --git a/python/src/bindings.cpp b/python/src/bindings.cpp index 3e4411795..ac6d8eeb9 100644 --- a/python/src/bindings.cpp +++ b/python/src/bindings.cpp @@ -37,7 +37,6 @@ PYBIND11_MODULE(ipctk, m) // candidates define_candidates(m); define_collision_stencil(m); - define_continuous_collision_candidate(m); define_edge_edge_candidate(m); define_edge_face_candidate(m); define_edge_vertex_candidate(m); diff --git a/python/src/candidates/CMakeLists.txt b/python/src/candidates/CMakeLists.txt index 6357c93a0..fbb53eb8f 100644 --- a/python/src/candidates/CMakeLists.txt +++ b/python/src/candidates/CMakeLists.txt @@ -1,6 +1,5 @@ set(SOURCES collision_stencil.cpp - continuous_collision_candidate.cpp edge_edge.cpp edge_face.cpp edge_vertex.cpp diff --git a/python/src/candidates/bindings.hpp b/python/src/candidates/bindings.hpp index 612cfbfe2..2d7bd09f3 100644 --- a/python/src/candidates/bindings.hpp +++ b/python/src/candidates/bindings.hpp @@ -5,7 +5,6 @@ // candidates void define_candidates(py::module_& m); void define_collision_stencil(py::module_& m); -void define_continuous_collision_candidate(py::module_& m); void define_edge_edge_candidate(py::module_& m); void define_edge_face_candidate(py::module_& m); void define_edge_vertex_candidate(py::module_& m); diff --git a/python/src/candidates/candidates.cpp b/python/src/candidates/candidates.cpp index a53b16e10..64951732c 100644 --- a/python/src/candidates/candidates.cpp +++ b/python/src/candidates/candidates.cpp @@ -53,7 +53,7 @@ void define_candidates(py::module_& m) .def("clear", &Candidates::clear) .def( "__getitem__", - [](Candidates& self, size_t i) -> ContinuousCollisionCandidate& { + [](Candidates& self, size_t i) -> CollisionStencil& { return self[i]; }, py::return_value_policy::reference) diff --git a/python/src/candidates/collision_stencil.cpp b/python/src/candidates/collision_stencil.cpp index 3a4aeb8b3..1e55c879b 100644 --- a/python/src/candidates/collision_stencil.cpp +++ b/python/src/candidates/collision_stencil.cpp @@ -172,5 +172,48 @@ void define_collision_stencil(py::module_& m) Returns: Distance Hessian of the stencil w.r.t. the stencil's vertex positions. )ipc_Qu8mg5v7", - py::arg("positions")); + py::arg("positions")) + .def( + "ccd", + [](const CollisionStencil& self, const VectorMax12d& vertices_t0, + const VectorMax12d& vertices_t1, const double min_distance, + const double tmax, const NarrowPhaseCCD& narrow_phase_ccd) { + double toi; + bool r = self.ccd( + vertices_t0, vertices_t1, toi, min_distance, tmax, + narrow_phase_ccd); + return std::make_tuple(r, toi); + }, + R"ipc_Qu8mg5v7( + Perform narrow-phase CCD on the candidate. + + Parameters: + vertices_t0: Stencil vertices at the start of the time step. + vertices_t1: Stencil vertices at the end of the time step. + min_distance: Minimum separation distance between primitives. + tmax: Maximum time (normalized) to look for collisions. Should be in [0, 1]. + narrow_phase_ccd: The narrow phase CCD algorithm to use. + + Returns: + Tuple of: + If the candidate had a collision over the time interval. + Computed time of impact (normalized). + )ipc_Qu8mg5v7", + py::arg("vertices_t0"), py::arg("vertices_t1"), + py::arg("min_distance") = 0.0, py::arg("tmax") = 1.0, + py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD) + .def( + "print_ccd_query", + [](const CollisionStencil& self, const VectorMax12d& vertices_t0, + const VectorMax12d& vertices_t1) -> void { + self.write_ccd_query(std::cout, vertices_t0, vertices_t1); + }, + R"ipc_Qu8mg5v7( + Print the CCD query to cout. + + Parameters: + vertices_t0: Stencil vertices at the start of the time step. + vertices_t1: Stencil vertices at the end of the time step. + )ipc_Qu8mg5v7", + py::arg("vertices_t0"), py::arg("vertices_t1")); } diff --git a/python/src/candidates/continuous_collision_candidate.cpp b/python/src/candidates/continuous_collision_candidate.cpp deleted file mode 100644 index 15e15008c..000000000 --- a/python/src/candidates/continuous_collision_candidate.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include - -#include - -namespace py = pybind11; -using namespace ipc; - -void define_continuous_collision_candidate(py::module_& m) -{ - py::class_(m, "ContinuousCollisionCandidate") - .def( - "ccd", - [](const ContinuousCollisionCandidate& self, - const VectorMax12d& vertices_t0, const VectorMax12d& vertices_t1, - const double min_distance, const double tmax, - const NarrowPhaseCCD& narrow_phase_ccd) { - double toi; - bool r = self.ccd( - vertices_t0, vertices_t1, toi, min_distance, tmax, - narrow_phase_ccd); - return std::make_tuple(r, toi); - }, - R"ipc_Qu8mg5v7( - Perform narrow-phase CCD on the candidate. - - Parameters: - vertices_t0: Stencil vertices at the start of the time step. - vertices_t1: Stencil vertices at the end of the time step. - min_distance: Minimum separation distance between primitives. - tmax: Maximum time (normalized) to look for collisions. Should be in [0, 1]. - narrow_phase_ccd: The narrow phase CCD algorithm to use. - - Returns: - Tuple of: - If the candidate had a collision over the time interval. - Computed time of impact (normalized). - )ipc_Qu8mg5v7", - py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("min_distance") = 0.0, py::arg("tmax") = 1.0, - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD) - .def( - "print_ccd_query", - [](const ContinuousCollisionCandidate& self, - const VectorMax12d& vertices_t0, - const VectorMax12d& vertices_t1) -> void { - self.write_ccd_query(std::cout, vertices_t0, vertices_t1); - }, - R"ipc_Qu8mg5v7( - Print the CCD query to cout. - - Parameters: - vertices_t0: Stencil vertices at the start of the time step. - vertices_t1: Stencil vertices at the end of the time step. - )ipc_Qu8mg5v7", - py::arg("vertices_t0"), py::arg("vertices_t1")); -} diff --git a/python/src/candidates/edge_edge.cpp b/python/src/candidates/edge_edge.cpp index d4fb6ce6f..7e03caa47 100644 --- a/python/src/candidates/edge_edge.cpp +++ b/python/src/candidates/edge_edge.cpp @@ -7,9 +7,7 @@ using namespace ipc; void define_edge_edge_candidate(py::module_& m) { - py::class_< - EdgeEdgeCandidate, CollisionStencil, ContinuousCollisionCandidate>( - m, "EdgeEdgeCandidate") + py::class_(m, "EdgeEdgeCandidate") .def(py::init(), py::arg("edge0_id"), py::arg("edge1_id")) .def( py::init([](std::tuple edge_ids) { diff --git a/python/src/candidates/edge_vertex.cpp b/python/src/candidates/edge_vertex.cpp index 3d5e82296..706ec1656 100644 --- a/python/src/candidates/edge_vertex.cpp +++ b/python/src/candidates/edge_vertex.cpp @@ -7,9 +7,7 @@ using namespace ipc; void define_edge_vertex_candidate(py::module_& m) { - py::class_< - EdgeVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>( - m, "EdgeVertexCandidate") + py::class_(m, "EdgeVertexCandidate") .def(py::init(), py::arg("edge_id"), py::arg("vertex_id")) .def( py::init([](std::tuple edge_and_vertex_id) { diff --git a/python/src/candidates/face_vertex.cpp b/python/src/candidates/face_vertex.cpp index 3577729f2..bcd044135 100644 --- a/python/src/candidates/face_vertex.cpp +++ b/python/src/candidates/face_vertex.cpp @@ -7,9 +7,7 @@ using namespace ipc; void define_face_vertex_candidate(py::module_& m) { - py::class_< - FaceVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>( - m, "FaceVertexCandidate") + py::class_(m, "FaceVertexCandidate") .def(py::init(), py::arg("face_id"), py::arg("vertex_id")) .def( py::init([](std::tuple face_and_vertex_id) { diff --git a/python/src/candidates/vertex_vertex.cpp b/python/src/candidates/vertex_vertex.cpp index ba94e0eea..92d32b77f 100644 --- a/python/src/candidates/vertex_vertex.cpp +++ b/python/src/candidates/vertex_vertex.cpp @@ -7,8 +7,7 @@ using namespace ipc; void define_vertex_vertex_candidate(py::module_& m) { - py::class_< - VertexVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>( + py::class_( m, "VertexVertexCandidate") .def( py::init(), py::arg("vertex0_id"), diff --git a/src/ipc/candidates/CMakeLists.txt b/src/ipc/candidates/CMakeLists.txt index 0445d0af9..f314e397e 100644 --- a/src/ipc/candidates/CMakeLists.txt +++ b/src/ipc/candidates/CMakeLists.txt @@ -1,9 +1,8 @@ set(SOURCES candidates.cpp candidates.hpp + collision_stencil.cpp collision_stencil.hpp - continuous_collision_candidate.cpp - continuous_collision_candidate.hpp edge_edge.cpp edge_edge.hpp edge_face.cpp diff --git a/src/ipc/candidates/candidates.cpp b/src/ipc/candidates/candidates.cpp index 642179eb2..d77d8f2cd 100644 --- a/src/ipc/candidates/candidates.cpp +++ b/src/ipc/candidates/candidates.cpp @@ -195,7 +195,7 @@ bool Candidates::is_step_collision_free( // Narrow phase for (size_t i = 0; i < size(); i++) { - const ContinuousCollisionCandidate& candidate = (*this)[i]; + const CollisionStencil& candidate = (*this)[i]; double toi; bool is_collision = candidate.ccd( @@ -240,7 +240,7 @@ double Candidates::compute_collision_free_stepsize( tmax = earliest_toi; } - const ContinuousCollisionCandidate& candidate = (*this)[i]; + const CollisionStencil& candidate = (*this)[i]; double toi = std::numeric_limits::infinity(); // output const bool are_colliding = candidate.ccd( @@ -344,7 +344,7 @@ void Candidates::clear() fv_candidates.clear(); } -ContinuousCollisionCandidate& Candidates::operator[](size_t i) +CollisionStencil& Candidates::operator[](size_t i) { if (i < vv_candidates.size()) { return vv_candidates[i]; @@ -364,7 +364,7 @@ ContinuousCollisionCandidate& Candidates::operator[](size_t i) throw std::out_of_range("Candidate index is out of range!"); } -const ContinuousCollisionCandidate& Candidates::operator[](size_t i) const +const CollisionStencil& Candidates::operator[](size_t i) const { if (i < vv_candidates.size()) { return vv_candidates[i]; diff --git a/src/ipc/candidates/candidates.hpp b/src/ipc/candidates/candidates.hpp index 38fe53de3..58b2552a0 100644 --- a/src/ipc/candidates/candidates.hpp +++ b/src/ipc/candidates/candidates.hpp @@ -49,8 +49,8 @@ class Candidates { void clear(); - ContinuousCollisionCandidate& operator[](size_t i); - const ContinuousCollisionCandidate& operator[](size_t i) const; + CollisionStencil& operator[](size_t i); + const CollisionStencil& operator[](size_t i) const; /// @brief Determine if the step is collision free from the set of candidates. /// @note Assumes the trajectory is linear. diff --git a/src/ipc/candidates/continuous_collision_candidate.cpp b/src/ipc/candidates/collision_stencil.cpp similarity index 86% rename from src/ipc/candidates/continuous_collision_candidate.cpp rename to src/ipc/candidates/collision_stencil.cpp index f85def72b..2dc274257 100644 --- a/src/ipc/candidates/continuous_collision_candidate.cpp +++ b/src/ipc/candidates/collision_stencil.cpp @@ -1,8 +1,8 @@ -#include "continuous_collision_candidate.hpp" +#include "collision_stencil.hpp" namespace ipc { -std::ostream& ContinuousCollisionCandidate::write_ccd_query( +std::ostream& CollisionStencil::write_ccd_query( std::ostream& out, const VectorMax12d& vertices_t0, const VectorMax12d& vertices_t1) const diff --git a/src/ipc/candidates/collision_stencil.hpp b/src/ipc/candidates/collision_stencil.hpp index 67eabd454..92b9a58ff 100644 --- a/src/ipc/candidates/collision_stencil.hpp +++ b/src/ipc/candidates/collision_stencil.hpp @@ -1,9 +1,11 @@ #pragma once +#include #include #include #include +#include namespace ipc { @@ -161,6 +163,33 @@ class CollisionStencil { /// @return Coefficients of the stencil. virtual VectorMax4d compute_coefficients(const VectorMax12d& positions) const = 0; + + /// @brief Perform narrow-phase CCD on the candidate. + /// @param[in] vertices_t0 Stencil vertices at the start of the time step. + /// @param[in] vertices_t1 Stencil vertices at the end of the time step. + /// @param[out] toi Computed time of impact (normalized). + /// @param[in] min_distance Minimum separation distance between primitives. + /// @param[in] tmax Maximum time (normalized) to look for collisions. + /// @param[in] narrow_phase_ccd The narrow phase CCD algorithm to use. + /// @return If the candidate had a collision over the time interval. + virtual bool + ccd(const VectorMax12d& vertices_t0, + const VectorMax12d& vertices_t1, + double& toi, + const double min_distance = 0.0, + const double tmax = 1.0, + const NarrowPhaseCCD& narrow_phase_ccd = + DEFAULT_NARROW_PHASE_CCD) const = 0; + + /// @brief Write the CCD query to a stream. + /// @param out Stream to write to. + /// @param vertices_t0 Stencil vertices at the start of the time step. + /// @param vertices_t1 Stencil vertices at the end of the time step. + /// @return The stream. + std::ostream& write_ccd_query( + std::ostream& out, + const VectorMax12d& vertices_t0, + const VectorMax12d& vertices_t1) const; }; } // namespace ipc \ No newline at end of file diff --git a/src/ipc/candidates/continuous_collision_candidate.hpp b/src/ipc/candidates/continuous_collision_candidate.hpp deleted file mode 100644 index 2acf1552e..000000000 --- a/src/ipc/candidates/continuous_collision_candidate.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -namespace ipc { - -/// Virtual class for candidates that support CCD. -class ContinuousCollisionCandidate : virtual public CollisionStencil { -public: - virtual ~ContinuousCollisionCandidate() = default; - - /// @brief Perform narrow-phase CCD on the candidate. - /// @param[in] vertices_t0 Stencil vertices at the start of the time step. - /// @param[in] vertices_t1 Stencil vertices at the end of the time step. - /// @param[out] toi Computed time of impact (normalized). - /// @param[in] min_distance Minimum separation distance between primitives. - /// @param[in] tmax Maximum time (normalized) to look for collisions. - /// @param[in] narrow_phase_ccd The narrow phase CCD algorithm to use. - /// @return If the candidate had a collision over the time interval. - virtual bool - ccd(const VectorMax12d& vertices_t0, - const VectorMax12d& vertices_t1, - double& toi, - const double min_distance = 0.0, - const double tmax = 1.0, - const NarrowPhaseCCD& narrow_phase_ccd = - DEFAULT_NARROW_PHASE_CCD) const = 0; - - /// @brief Write the CCD query to a stream. - /// @param out Stream to write to. - /// @param vertices_t0 Stencil vertices at the start of the time step. - /// @param vertices_t1 Stencil vertices at the end of the time step. - /// @return The stream. - std::ostream& write_ccd_query( - std::ostream& out, - const VectorMax12d& vertices_t0, - const VectorMax12d& vertices_t1) const; -}; - -} // namespace ipc diff --git a/src/ipc/candidates/edge_edge.hpp b/src/ipc/candidates/edge_edge.hpp index 650a38485..fec868f73 100644 --- a/src/ipc/candidates/edge_edge.hpp +++ b/src/ipc/candidates/edge_edge.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,7 +9,7 @@ namespace ipc { -class EdgeEdgeCandidate : public ContinuousCollisionCandidate { +class EdgeEdgeCandidate : virtual public CollisionStencil { public: EdgeEdgeCandidate(long edge0_id, long edge1_id); @@ -43,7 +43,6 @@ class EdgeEdgeCandidate : public ContinuousCollisionCandidate { compute_coefficients(const VectorMax12d& positions) const override; // ------------------------------------------------------------------------ - // ContinuousCollisionCandidate bool ccd(const VectorMax12d& vertices_t0, diff --git a/src/ipc/candidates/edge_vertex.hpp b/src/ipc/candidates/edge_vertex.hpp index 78ba306aa..33079e72f 100644 --- a/src/ipc/candidates/edge_vertex.hpp +++ b/src/ipc/candidates/edge_vertex.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,7 +9,7 @@ namespace ipc { -class EdgeVertexCandidate : public ContinuousCollisionCandidate { +class EdgeVertexCandidate : virtual public CollisionStencil { public: EdgeVertexCandidate(long edge_id, long vertex_id); @@ -42,7 +42,6 @@ class EdgeVertexCandidate : public ContinuousCollisionCandidate { compute_coefficients(const VectorMax12d& positions) const override; // ------------------------------------------------------------------------ - // ContinuousCollisionCandidate bool ccd(const VectorMax12d& vertices_t0, diff --git a/src/ipc/candidates/face_vertex.hpp b/src/ipc/candidates/face_vertex.hpp index 9b508e012..fe756b55e 100644 --- a/src/ipc/candidates/face_vertex.hpp +++ b/src/ipc/candidates/face_vertex.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,7 +9,7 @@ namespace ipc { -class FaceVertexCandidate : public ContinuousCollisionCandidate { +class FaceVertexCandidate : virtual public CollisionStencil { public: FaceVertexCandidate(long face_id, long vertex_id); @@ -43,7 +43,6 @@ class FaceVertexCandidate : public ContinuousCollisionCandidate { compute_coefficients(const VectorMax12d& positions) const override; // ------------------------------------------------------------------------ - // ContinuousCollisionCandidate bool ccd(const VectorMax12d& vertices_t0, diff --git a/src/ipc/candidates/vertex_vertex.hpp b/src/ipc/candidates/vertex_vertex.hpp index db23a90e7..83f97c28f 100644 --- a/src/ipc/candidates/vertex_vertex.hpp +++ b/src/ipc/candidates/vertex_vertex.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,7 +9,7 @@ namespace ipc { -class VertexVertexCandidate : public ContinuousCollisionCandidate { +class VertexVertexCandidate : virtual public CollisionStencil { public: VertexVertexCandidate(long vertex0_id, long vertex1_id); @@ -46,7 +46,6 @@ class VertexVertexCandidate : public ContinuousCollisionCandidate { compute_coefficients(const VectorMax12d& positions) const override; // ------------------------------------------------------------------------ - // ContinuousCollisionCandidate bool ccd(const VectorMax12d& vertices_t0, diff --git a/src/ipc/collisions/normal/plane_vertex.cpp b/src/ipc/collisions/normal/plane_vertex.cpp index 27b3a53c8..cf5737700 100644 --- a/src/ipc/collisions/normal/plane_vertex.cpp +++ b/src/ipc/collisions/normal/plane_vertex.cpp @@ -1,5 +1,6 @@ #include "plane_vertex.hpp" +#include #include namespace ipc { @@ -43,4 +44,17 @@ VectorMax4d PlaneVertexNormalCollision::compute_coefficients( return coeffs; } +bool PlaneVertexNormalCollision::ccd( + const VectorMax12d& vertices_t0, + const VectorMax12d& vertices_t1, + double& toi, + const double min_distance, + const double tmax, + const NarrowPhaseCCD& narrow_phase_ccd) const +{ + assert(min_distance == 0 && "Not implemented"); + return point_static_plane_ccd( + vertices_t0, vertices_t1, plane_origin, plane_normal, toi); +} + } // namespace ipc diff --git a/src/ipc/collisions/normal/plane_vertex.hpp b/src/ipc/collisions/normal/plane_vertex.hpp index 713689bd5..1169eb6af 100644 --- a/src/ipc/collisions/normal/plane_vertex.hpp +++ b/src/ipc/collisions/normal/plane_vertex.hpp @@ -5,7 +5,8 @@ namespace ipc { -class PlaneVertexNormalCollision : public NormalCollision { +class PlaneVertexNormalCollision : virtual public CollisionStencil, + public NormalCollision { public: PlaneVertexNormalCollision( const VectorMax3d& plane_origin, @@ -21,10 +22,10 @@ class PlaneVertexNormalCollision : public NormalCollision { return { { vertex_id, -1, -1, -1 } }; } - using NormalCollision::compute_coefficients; - using NormalCollision::compute_distance; - using NormalCollision::compute_distance_gradient; - using NormalCollision::compute_distance_hessian; + using CollisionStencil::compute_coefficients; + using CollisionStencil::compute_distance; + using CollisionStencil::compute_distance_gradient; + using CollisionStencil::compute_distance_hessian; /// @brief Compute the distance between the point and plane. /// @param point Point's position. @@ -49,6 +50,23 @@ class PlaneVertexNormalCollision : public NormalCollision { VectorMax4d compute_coefficients(const VectorMax12d& positions) const override; + /// @brief Perform narrow-phase CCD on the candidate. + /// @param[in] vertices_t0 Stencil vertices at the start of the time step. + /// @param[in] vertices_t1 Stencil vertices at the end of the time step. + /// @param[out] toi Computed time of impact (normalized). + /// @param[in] min_distance Minimum separation distance between primitives. + /// @param[in] tmax Maximum time (normalized) to look for collisions. + /// @param[in] narrow_phase_ccd The narrow phase CCD algorithm to use. + /// @return If the candidate had a collision over the time interval. + bool + ccd(const VectorMax12d& vertices_t0, + const VectorMax12d& vertices_t1, + double& toi, + const double min_distance = 0.0, + const double tmax = 1.0, + const NarrowPhaseCCD& narrow_phase_ccd = + DEFAULT_NARROW_PHASE_CCD) const override; + /// @brief The plane's origin. VectorMax3d plane_origin; diff --git a/src/ipc/collisions/tangential/tangential_collision.hpp b/src/ipc/collisions/tangential/tangential_collision.hpp index c37701e6a..eab8acbbd 100644 --- a/src/ipc/collisions/tangential/tangential_collision.hpp +++ b/src/ipc/collisions/tangential/tangential_collision.hpp @@ -27,7 +27,7 @@ class TangentialCollision : virtual public CollisionStencil { int dim() const { return tangent_basis.rows(); } /// @brief Get the number of degrees of freedom for the collision. - int ndof() const { return dim() * num_vertices(); }; + int ndof() const { return dim() * num_vertices(); } // -- Abstract methods -----------------------------------------------------