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
138 changes: 137 additions & 1 deletion python/src/broad_phase/broad_phase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,145 @@
namespace py = pybind11;
using namespace ipc;

class PyBroadPhase : public BroadPhase {
public:
using BroadPhase::BroadPhase; // Inherit constructors

std::string name() const override
{
PYBIND11_OVERRIDE_PURE(std::string, BroadPhase, name);
}

void build(
const Eigen::MatrixXd& vertices,
const Eigen::MatrixXi& edges,
const Eigen::MatrixXi& faces,
const double inflation_radius = 0) override
{
PYBIND11_OVERRIDE(
void, BroadPhase, build, vertices, edges, faces, inflation_radius);
}

void build(
const Eigen::MatrixXd& vertices_t0,
const Eigen::MatrixXd& vertices_t1,
const Eigen::MatrixXi& edges,
const Eigen::MatrixXi& faces,
const double inflation_radius = 0) override
{
PYBIND11_OVERRIDE(
void, BroadPhase, build, vertices_t0, vertices_t1, edges, faces,
inflation_radius);
}

void clear() override { PYBIND11_OVERRIDE(void, BroadPhase, clear); }

void detect_vertex_vertex_candidates(
std::vector<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>>();
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
{
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>>();
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
{
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>>();
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
{
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>>();
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
{
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>>();
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
{
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>>();
return;
}
throw std::runtime_error(
"Tried to call pure virtual function \"BroadPhase::detect_face_face_candidates\"");
}

void
detect_collision_candidates(int dim, Candidates& candidates) const override
{
{
py::gil_scoped_acquire
gil; // Acquire GIL before calling Python code
py::function override =
py::get_override(this, "detect_collision_candidates");
if (override) {
candidates = override(dim).cast<Candidates>();
return;
}
}
BroadPhase::detect_collision_candidates(dim, candidates);
}
};

void define_broad_phase(py::module_& m)
{
py::class_<BroadPhase, std::shared_ptr<BroadPhase>>(m, "BroadPhase")
py::class_<BroadPhase, PyBroadPhase, std::shared_ptr<BroadPhase>>(
m, "BroadPhase")
.def(py::init<>())
.def("name", &BroadPhase::name, "Get the name of the broad phase.")
.def(
"build",
Expand Down
8 changes: 8 additions & 0 deletions python/src/candidates/edge_edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ void define_edge_edge_candidate(py::module_& m)
EdgeEdgeCandidate, CollisionStencil, ContinuousCollisionCandidate>(
m, "EdgeEdgeCandidate")
.def(py::init<long, long>(), py::arg("edge0_id"), py::arg("edge1_id"))
.def(
py::init([](std::tuple<long, long> edge_ids) {
return std::make_unique<EdgeEdgeCandidate>(
std::get<0>(edge_ids), std::get<1>(edge_ids));
}),
py::arg("edge_ids"))
.def("known_dtype", &EdgeEdgeCandidate::known_dtype)
.def(
"__str__",
Expand All @@ -32,4 +38,6 @@ void define_edge_edge_candidate(py::module_& m)
"edge0_id", &EdgeEdgeCandidate::edge0_id, "ID of the first edge.")
.def_readwrite(
"edge1_id", &EdgeEdgeCandidate::edge1_id, "ID of the second edge.");

py::implicitly_convertible<std::tuple<long, long>, EdgeEdgeCandidate>();
}
9 changes: 9 additions & 0 deletions python/src/candidates/edge_face.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ void define_edge_face_candidate(py::module_& m)
{
py::class_<EdgeFaceCandidate>(m, "EdgeFaceCandidate")
.def(py::init<long, long>(), py::arg("edge_id"), py::arg("face_id"))
.def(
py::init([](std::tuple<long, long> edge_and_face_id) {
return std::make_unique<EdgeFaceCandidate>(
std::get<0>(edge_and_face_id),
std::get<1>(edge_and_face_id));
}),
py::arg("edge_and_face_id"))
.def(
"__str__",
[](const EdgeFaceCandidate& ev) {
Expand All @@ -29,4 +36,6 @@ void define_edge_face_candidate(py::module_& m)
.def_readwrite("edge_id", &EdgeFaceCandidate::edge_id, "ID of the edge")
.def_readwrite(
"face_id", &EdgeFaceCandidate::face_id, "ID of the face");

py::implicitly_convertible<std::tuple<long, long>, EdgeFaceCandidate>();
}
9 changes: 9 additions & 0 deletions python/src/candidates/edge_vertex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ void define_edge_vertex_candidate(py::module_& m)
EdgeVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>(
m, "EdgeVertexCandidate")
.def(py::init<long, long>(), py::arg("edge_id"), py::arg("vertex_id"))
.def(
py::init([](std::tuple<long, long> edge_and_vertex_id) {
return std::make_unique<EdgeVertexCandidate>(
std::get<0>(edge_and_vertex_id),
std::get<1>(edge_and_vertex_id));
}),
py::arg("edge_and_vertex_id"))
.def("known_dtype", &EdgeVertexCandidate::known_dtype)
.def(
"__str__",
Expand All @@ -33,4 +40,6 @@ void define_edge_vertex_candidate(py::module_& m)
"edge_id", &EdgeVertexCandidate::edge_id, "ID of the edge")
.def_readwrite(
"vertex_id", &EdgeVertexCandidate::vertex_id, "ID of the vertex");

py::implicitly_convertible<std::tuple<long, long>, EdgeVertexCandidate>();
}
8 changes: 8 additions & 0 deletions python/src/candidates/face_face.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ void define_face_face_candidate(py::module_& m)
{
py::class_<FaceFaceCandidate>(m, "FaceFaceCandidate")
.def(py::init<long, long>(), py::arg("face0_id"), py::arg("face1_id"))
.def(
py::init([](std::tuple<long, long> face_ids) {
return std::make_unique<FaceFaceCandidate>(
std::get<0>(face_ids), std::get<1>(face_ids));
}),
py::arg("face_ids"))
.def(
"__str__",
[](const FaceFaceCandidate& ff) {
Expand All @@ -30,4 +36,6 @@ void define_face_face_candidate(py::module_& m)
"face0_id", &FaceFaceCandidate::face0_id, "ID of the first face.")
.def_readwrite(
"face1_id", &FaceFaceCandidate::face1_id, "ID of the second face.");

py::implicitly_convertible<std::tuple<long, long>, FaceFaceCandidate>();
}
9 changes: 9 additions & 0 deletions python/src/candidates/face_vertex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ void define_face_vertex_candidate(py::module_& m)
FaceVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>(
m, "FaceVertexCandidate")
.def(py::init<long, long>(), py::arg("face_id"), py::arg("vertex_id"))
.def(
py::init([](std::tuple<long, long> face_and_vertex_id) {
return std::make_unique<FaceVertexCandidate>(
std::get<0>(face_and_vertex_id),
std::get<1>(face_and_vertex_id));
}),
py::arg("face_and_vertex_id"))
.def("known_dtype", &FaceVertexCandidate::known_dtype)
.def(
"__str__",
Expand All @@ -33,4 +40,6 @@ void define_face_vertex_candidate(py::module_& m)
"face_id", &FaceVertexCandidate::face_id, "ID of the face")
.def_readwrite(
"vertex_id", &FaceVertexCandidate::vertex_id, "ID of the vertex");

py::implicitly_convertible<std::tuple<long, long>, FaceVertexCandidate>();
}
8 changes: 8 additions & 0 deletions python/src/candidates/vertex_vertex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ void define_vertex_vertex_candidate(py::module_& m)
.def(
py::init<long, long>(), py::arg("vertex0_id"),
py::arg("vertex1_id"))
.def(
py::init([](std::tuple<long, long> vertex_ids) {
return std::make_unique<VertexVertexCandidate>(
std::get<0>(vertex_ids), std::get<1>(vertex_ids));
}),
py::arg("vertex_ids"))
.def(
"__str__",
[](const VertexVertexCandidate& ev) {
Expand All @@ -37,4 +43,6 @@ void define_vertex_vertex_candidate(py::module_& m)
.def_readwrite(
"vertex1_id", &VertexVertexCandidate::vertex1_id,
"ID of the second vertex");

py::implicitly_convertible<std::tuple<long, long>, VertexVertexCandidate>();
}
96 changes: 95 additions & 1 deletion python/src/ccd/narrow_phase_ccd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,103 @@
namespace py = pybind11;
using namespace ipc;

class PyNarrowPhaseCCD : public NarrowPhaseCCD {
public:
using NarrowPhaseCCD::NarrowPhaseCCD; // Inherit constructors
bool point_point_ccd(
const VectorMax3d& p0_t0,
const VectorMax3d& p1_t0,
const VectorMax3d& p0_t1,
const VectorMax3d& p1_t1,
double& toi,
const double min_distance = 0.0,
const double tmax = 1.0) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override = py::get_override(this, "point_point_ccd");
if (override) {
const py::tuple obj =
override(p0_t0, p1_t0, p0_t1, p1_t1, min_distance, tmax);
toi = obj[1].cast<double>();
return obj[0].cast<bool>();
}
throw std::runtime_error("pure virtual function called");
}
bool point_edge_ccd(
const VectorMax3d& p_t0,
const VectorMax3d& e0_t0,
const VectorMax3d& e1_t0,
const VectorMax3d& p_t1,
const VectorMax3d& e0_t1,
const VectorMax3d& e1_t1,
double& toi,
const double min_distance = 0.0,
const double tmax = 1.0) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override = py::get_override(this, "point_edge_ccd");
if (override) {
const py::tuple obj = override(
p_t0, e0_t0, e1_t0, p_t1, e0_t1, e1_t1, min_distance, tmax);
toi = obj[1].cast<double>();
return obj[0].cast<bool>();
}
throw std::runtime_error("pure virtual function called");
}
bool point_triangle_ccd(
const Eigen::Vector3d& p_t0,
const Eigen::Vector3d& t0_t0,
const Eigen::Vector3d& t1_t0,
const Eigen::Vector3d& t2_t0,
const Eigen::Vector3d& p_t1,
const Eigen::Vector3d& t0_t1,
const Eigen::Vector3d& t1_t1,
const Eigen::Vector3d& t2_t1,
double& toi,
const double min_distance = 0.0,
const double tmax = 1.0) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override = py::get_override(this, "point_triangle_ccd");
if (override) {
const py::tuple obj = override(
p_t0, t0_t0, t1_t0, t2_t0, p_t1, t0_t1, t1_t1, t2_t1,
min_distance, tmax);
toi = obj[1].cast<double>();
return obj[0].cast<bool>();
}
throw std::runtime_error("pure virtual function called");
}
bool edge_edge_ccd(
const Eigen::Vector3d& ea0_t0,
const Eigen::Vector3d& ea1_t0,
const Eigen::Vector3d& eb0_t0,
const Eigen::Vector3d& eb1_t0,
const Eigen::Vector3d& ea0_t1,
const Eigen::Vector3d& ea1_t1,
const Eigen::Vector3d& eb0_t1,
const Eigen::Vector3d& eb1_t1,
double& toi,
const double min_distance = 0.0,
const double tmax = 1.0) const override
{
py::gil_scoped_acquire gil; // Acquire GIL before calling Python code
py::function override = py::get_override(this, "edge_edge_ccd");
if (override) {
const py::tuple obj = override(
ea0_t0, ea1_t0, eb0_t0, eb1_t0, ea0_t1, ea1_t1, eb0_t1, eb1_t1,
min_distance, tmax);
toi = obj[1].cast<double>();
return obj[0].cast<bool>();
}
throw std::runtime_error("pure virtual function called");
}
};

void define_narrow_phase_ccd(py::module_& m)
{
py::class_<NarrowPhaseCCD>(m, "NarrowPhaseCCD")
py::class_<NarrowPhaseCCD, PyNarrowPhaseCCD>(m, "NarrowPhaseCCD")
.def(py::init<>())
.def(
"point_point_ccd",
[](const NarrowPhaseCCD& self, const VectorMax3d& p0_t0,
Expand Down
3 changes: 3 additions & 0 deletions python/src/utils/thread_limiter.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <common.hpp>

#include <memory>
#include <cstdlib>

#include <tbb/info.h>
#include <tbb/global_control.h>
Expand Down Expand Up @@ -40,4 +41,6 @@ void define_thread_limiter(py::module_& m)
m.def(
"set_num_threads", &set_num_threads,
"set maximum number of threads to use", py::arg("nthreads"));

std::atexit([]() { thread_limiter.reset(); });
}
Loading