Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions python/src/broad_phase/broad_phase.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <ipc/candidates/candidate_vector.hpp>
#include <common.hpp>

#include <ipc/broad_phase/broad_phase.hpp>
Expand Down Expand Up @@ -39,83 +40,89 @@ class PyBroadPhase : public BroadPhase {
void clear() override { PYBIND11_OVERRIDE(void, BroadPhase, clear); }

void detect_vertex_vertex_candidates(
std::vector<VertexVertexCandidate>& candidates) const override
ipc::CandidateVector<VertexVertexCandidate>& candidates) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_vertex_vertex_candidates");
if (override) {
candidates = override().cast<std::vector<VertexVertexCandidate>>();
candidates =
override().cast<ipc::CandidateVector<VertexVertexCandidate>>();
return;
}
throw std::runtime_error(
"Tried to call pure virtual function \"BroadPhase::detect_vertex_vertex_candidates\"");
}

void detect_edge_vertex_candidates(
std::vector<EdgeVertexCandidate>& candidates) const override
ipc::CandidateVector<EdgeVertexCandidate>& candidates) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_edge_vertex_candidates");
if (override) {
candidates = override().cast<std::vector<EdgeVertexCandidate>>();
candidates =
override().cast<ipc::CandidateVector<EdgeVertexCandidate>>();
return;
}
throw std::runtime_error(
"Tried to call pure virtual function \"BroadPhase::detect_edge_vertex_candidates\"");
}

void detect_edge_edge_candidates(
std::vector<EdgeEdgeCandidate>& candidates) const override
ipc::CandidateVector<EdgeEdgeCandidate>& candidates) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_edge_edge_candidates");
if (override) {
candidates = override().cast<std::vector<EdgeEdgeCandidate>>();
candidates =
override().cast<ipc::CandidateVector<EdgeEdgeCandidate>>();
return;
}
throw std::runtime_error(
"Tried to call pure virtual function \"BroadPhase::detect_edge_edge_candidates\"");
}

void detect_face_vertex_candidates(
std::vector<FaceVertexCandidate>& candidates) const override
ipc::CandidateVector<FaceVertexCandidate>& candidates) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_face_vertex_candidates");
if (override) {
candidates = override().cast<std::vector<FaceVertexCandidate>>();
candidates =
override().cast<ipc::CandidateVector<FaceVertexCandidate>>();
return;
}
throw std::runtime_error(
"Tried to call pure virtual function \"BroadPhase::detect_face_vertex_candidates\"");
}

void detect_edge_face_candidates(
std::vector<EdgeFaceCandidate>& candidates) const override
ipc::CandidateVector<EdgeFaceCandidate>& candidates) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_edge_face_candidates");
if (override) {
candidates = override().cast<std::vector<EdgeFaceCandidate>>();
candidates =
override().cast<ipc::CandidateVector<EdgeFaceCandidate>>();
return;
}
throw std::runtime_error(
"Tried to call pure virtual function \"BroadPhase::detect_edge_face_candidates\"");
}

void detect_face_face_candidates(
std::vector<FaceFaceCandidate>& candidates) const override
ipc::CandidateVector<FaceFaceCandidate>& candidates) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_face_face_candidates");
if (override) {
candidates = override().cast<std::vector<FaceFaceCandidate>>();
candidates =
override().cast<ipc::CandidateVector<FaceFaceCandidate>>();
return;
}
throw std::runtime_error(
Expand Down Expand Up @@ -170,7 +177,7 @@ void define_broad_phase(py::module_& m)
.def(
"detect_vertex_vertex_candidates",
[](const BroadPhase& self) {
std::vector<VertexVertexCandidate> candidates;
ipc::CandidateVector<VertexVertexCandidate> candidates;
self.detect_vertex_vertex_candidates(candidates);
return candidates;
},
Expand All @@ -183,7 +190,7 @@ void define_broad_phase(py::module_& m)
.def(
"detect_edge_vertex_candidates",
[](const BroadPhase& self) {
std::vector<EdgeVertexCandidate> candidates;
ipc::CandidateVector<EdgeVertexCandidate> candidates;
self.detect_edge_vertex_candidates(candidates);
return candidates;
},
Expand All @@ -196,7 +203,7 @@ void define_broad_phase(py::module_& m)
.def(
"detect_edge_edge_candidates",
[](const BroadPhase& self) {
std::vector<EdgeEdgeCandidate> candidates;
ipc::CandidateVector<EdgeEdgeCandidate> candidates;
self.detect_edge_edge_candidates(candidates);
return candidates;
},
Expand All @@ -209,7 +216,7 @@ void define_broad_phase(py::module_& m)
.def(
"detect_face_vertex_candidates",
[](const BroadPhase& self) {
std::vector<FaceVertexCandidate> candidates;
ipc::CandidateVector<FaceVertexCandidate> candidates;
self.detect_face_vertex_candidates(candidates);
return candidates;
},
Expand All @@ -222,7 +229,7 @@ void define_broad_phase(py::module_& m)
.def(
"detect_edge_face_candidates",
[](const BroadPhase& self) {
std::vector<EdgeFaceCandidate> candidates;
ipc::CandidateVector<EdgeFaceCandidate> candidates;
self.detect_edge_face_candidates(candidates);
return candidates;
},
Expand All @@ -235,7 +242,7 @@ void define_broad_phase(py::module_& m)
.def(
"detect_face_face_candidates",
[](const BroadPhase& self) {
std::vector<FaceFaceCandidate> candidates;
ipc::CandidateVector<FaceFaceCandidate> candidates;
self.detect_face_face_candidates(candidates);
return candidates;
},
Expand Down
31 changes: 20 additions & 11 deletions python/src/candidates/candidates.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <ipc/candidates/candidate_vector.hpp>
#include <common.hpp>

#include <ipc/candidates/candidates.hpp>
Expand Down Expand Up @@ -51,10 +52,18 @@ void define_candidates(py::module_& m)
.def("clear", &Candidates::clear)
.def(
"__getitem__",
[](Candidates& self, size_t i) -> CollisionStencil& {
return self[i];
// Python is dynamically typed, so the concrete candidate type is
// returned rather than a common base. The reference points into the
// vector that holds it, with the Candidates object kept alive for
// as long as the reference lives.
[](py::object self, size_t i) {
return self.cast<Candidates&>().visit(i, [&](auto& candidate) {
return py::cast(
&candidate, py::return_value_policy::reference_internal,
self);
});
},
py::return_value_policy::reference)
"i"_a)
.def(
"is_step_collision_free", &Candidates::is_step_collision_free,
R"ipc_Qu8mg5v7(
Expand Down Expand Up @@ -154,8 +163,8 @@ void define_candidates(py::module_& m)
.def(
"edge_vertex_to_vertex_vertex",
[](const Candidates& C, const CollisionMesh& mesh,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
py::object is_active) -> std::vector<VertexVertexCandidate> {
Eigen::ConstRef<Eigen::MatrixXd> vertices, py::object is_active)
-> ipc::CandidateVector<VertexVertexCandidate> {
std::function<bool(double)> is_active_fn = [](double) {
return true;
};
Expand All @@ -182,8 +191,8 @@ void define_candidates(py::module_& m)
.def(
"face_vertex_to_vertex_vertex",
[](const Candidates& C, const CollisionMesh& mesh,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
py::object is_active) -> std::vector<VertexVertexCandidate> {
Eigen::ConstRef<Eigen::MatrixXd> vertices, py::object is_active)
-> ipc::CandidateVector<VertexVertexCandidate> {
std::function<bool(double)> is_active_fn = [](double) {
return true;
};
Expand All @@ -210,8 +219,8 @@ void define_candidates(py::module_& m)
.def(
"face_vertex_to_edge_vertex",
[](const Candidates& C, const CollisionMesh& mesh,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
py::object is_active) -> std::vector<EdgeVertexCandidate> {
Eigen::ConstRef<Eigen::MatrixXd> vertices, py::object is_active)
-> ipc::CandidateVector<EdgeVertexCandidate> {
std::function<bool(double)> is_active_fn = [](double) {
return true;
};
Expand All @@ -238,8 +247,8 @@ void define_candidates(py::module_& m)
.def(
"edge_edge_to_edge_vertex",
[](const Candidates& C, const CollisionMesh& mesh,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
py::object is_active) -> std::vector<EdgeVertexCandidate> {
Eigen::ConstRef<Eigen::MatrixXd> vertices, py::object is_active)
-> ipc::CandidateVector<EdgeVertexCandidate> {
std::function<bool(double)> is_active_fn = [](double) {
return true;
};
Expand Down
44 changes: 24 additions & 20 deletions python/src/candidates/collision_stencil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ void define_collision_stencil(py::module_& m)
"X"_a, "edges"_a, "faces"_a)
.def(
"compute_distance",
py::overload_cast<
Eigen::ConstRef<Eigen::MatrixXd>,
Eigen::ConstRef<Eigen::MatrixXi>,
Eigen::ConstRef<Eigen::MatrixXi>>(
&CollisionStencil::compute_distance, py::const_),
[](const CollisionStencil& self,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces) {
return self.compute_distance(vertices, edges, faces);
},
R"ipc_Qu8mg5v7(
Compute the distance of the stencil.

Expand All @@ -88,11 +89,12 @@ void define_collision_stencil(py::module_& m)
"vertices"_a, "edges"_a, "faces"_a)
.def(
"compute_distance_gradient",
py::overload_cast<
Eigen::ConstRef<Eigen::MatrixXd>,
Eigen::ConstRef<Eigen::MatrixXi>,
Eigen::ConstRef<Eigen::MatrixXi>>(
&CollisionStencil::compute_distance_gradient, py::const_),
[](const CollisionStencil& self,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces) {
return self.compute_distance_gradient(vertices, edges, faces);
},
R"ipc_Qu8mg5v7(
Compute the distance gradient of the stencil w.r.t. the stencil's vertex positions.

Expand All @@ -107,11 +109,12 @@ void define_collision_stencil(py::module_& m)
"vertices"_a, "edges"_a, "faces"_a)
.def(
"compute_distance_hessian",
py::overload_cast<
Eigen::ConstRef<Eigen::MatrixXd>,
Eigen::ConstRef<Eigen::MatrixXi>,
Eigen::ConstRef<Eigen::MatrixXi>>(
&CollisionStencil::compute_distance_hessian, py::const_),
[](const CollisionStencil& self,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces) {
return self.compute_distance_hessian(vertices, edges, faces);
},
R"ipc_Qu8mg5v7(
Compute the distance Hessian of the stencil w.r.t. the stencil's vertex positions.

Expand All @@ -126,11 +129,12 @@ void define_collision_stencil(py::module_& m)
"vertices"_a, "edges"_a, "faces"_a)
.def(
"compute_coefficients",
py::overload_cast<
Eigen::ConstRef<Eigen::MatrixXd>,
Eigen::ConstRef<Eigen::MatrixXi>,
Eigen::ConstRef<Eigen::MatrixXi>>(
&CollisionStencil::compute_coefficients, py::const_),
[](const CollisionStencil& self,
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces) {
return self.compute_coefficients(vertices, edges, faces);
},
R"ipc_Qu8mg5v7(
Compute the distance Hessian of the stencil w.r.t. the stencil's vertex positions.

Expand Down
14 changes: 12 additions & 2 deletions python/src/candidates/edge_edge.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include <common.hpp>

#include "stencil_methods.hpp"

#include <ipc/candidates/edge_edge.hpp>

using namespace ipc;

void define_edge_edge_candidate(py::module_& m)
{
py::class_<EdgeEdgeCandidate, CollisionStencil>(m, "EdgeEdgeCandidate")
.def(py::init<index_t, index_t>(), "edge0_id"_a, "edge1_id"_a)
auto cls = py::class_<EdgeEdgeCandidate>(m, "EdgeEdgeCandidate");
cls.def(py::init<index_t, index_t>(), "edge0_id"_a, "edge1_id"_a)
.def(
py::init([](std::tuple<index_t, index_t> edge_ids) {
return std::make_unique<EdgeEdgeCandidate>(
Expand Down Expand Up @@ -38,4 +40,12 @@ void define_edge_edge_candidate(py::module_& m)

py::implicitly_convertible<
std::tuple<index_t, index_t>, EdgeEdgeCandidate>();

define_stencil_methods<EdgeEdgeCandidate>(cls);

// The adapter the collision types derive from; it carries the
// polymorphic stencil interface the POD candidate deliberately
// lacks.
py::class_<EdgeEdgeStencil, EdgeEdgeCandidate, CollisionStencil>(
m, "EdgeEdgeStencil");
}
14 changes: 12 additions & 2 deletions python/src/candidates/edge_vertex.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include <common.hpp>

#include "stencil_methods.hpp"

#include <ipc/candidates/edge_vertex.hpp>

using namespace ipc;

void define_edge_vertex_candidate(py::module_& m)
{
py::class_<EdgeVertexCandidate, CollisionStencil>(m, "EdgeVertexCandidate")
.def(py::init<index_t, index_t>(), "edge_id"_a, "vertex_id"_a)
auto cls = py::class_<EdgeVertexCandidate>(m, "EdgeVertexCandidate");
cls.def(py::init<index_t, index_t>(), "edge_id"_a, "vertex_id"_a)
.def(
py::init([](std::tuple<index_t, index_t> edge_and_vertex_id) {
return std::make_unique<EdgeVertexCandidate>(
Expand Down Expand Up @@ -40,4 +42,12 @@ void define_edge_vertex_candidate(py::module_& m)

py::implicitly_convertible<
std::tuple<index_t, index_t>, EdgeVertexCandidate>();

define_stencil_methods<EdgeVertexCandidate>(cls);

// The adapter the collision types derive from; it carries the
// polymorphic stencil interface the POD candidate deliberately
// lacks.
py::class_<EdgeVertexStencil, EdgeVertexCandidate, CollisionStencil>(
m, "EdgeVertexStencil");
}
14 changes: 12 additions & 2 deletions python/src/candidates/face_vertex.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include <common.hpp>

#include "stencil_methods.hpp"

#include <ipc/candidates/face_vertex.hpp>

using namespace ipc;

void define_face_vertex_candidate(py::module_& m)
{
py::class_<FaceVertexCandidate, CollisionStencil>(m, "FaceVertexCandidate")
.def(py::init<index_t, index_t>(), "face_id"_a, "vertex_id"_a)
auto cls = py::class_<FaceVertexCandidate>(m, "FaceVertexCandidate");
cls.def(py::init<index_t, index_t>(), "face_id"_a, "vertex_id"_a)
.def(
py::init([](std::tuple<index_t, index_t> face_and_vertex_id) {
return std::make_unique<FaceVertexCandidate>(
Expand Down Expand Up @@ -40,4 +42,12 @@ void define_face_vertex_candidate(py::module_& m)

py::implicitly_convertible<
std::tuple<index_t, index_t>, FaceVertexCandidate>();

define_stencil_methods<FaceVertexCandidate>(cls);

// The adapter the collision types derive from; it carries the
// polymorphic stencil interface the POD candidate deliberately
// lacks.
py::class_<FaceVertexStencil, FaceVertexCandidate, CollisionStencil>(
m, "FaceVertexStencil");
}
Loading
Loading