Skip to content

Commit ffcef79

Browse files
committed
Fix thread_limiter segfault; implicit convert tuple to candidate
1 parent 1b19b36 commit ffcef79

10 files changed

+95
-9
lines changed

python/src/broad_phase/broad_phase.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ using namespace ipc;
99
class PyBroadPhase : public BroadPhase {
1010
public:
1111
using BroadPhase::BroadPhase; // Inherit constructors
12+
1213
std::string name() const override
1314
{
1415
PYBIND11_OVERRIDE_PURE(std::string, BroadPhase, name);
1516
}
17+
1618
void build(
1719
const Eigen::MatrixXd& vertices,
1820
const Eigen::MatrixXi& edges,

python/src/candidates/edge_edge.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ void define_edge_edge_candidate(py::module_& m)
1111
EdgeEdgeCandidate, CollisionStencil, ContinuousCollisionCandidate>(
1212
m, "EdgeEdgeCandidate")
1313
.def(py::init<long, long>(), py::arg("edge0_id"), py::arg("edge1_id"))
14+
.def(
15+
py::init([](std::tuple<long, long> edge_ids) {
16+
return std::make_unique<EdgeEdgeCandidate>(
17+
std::get<0>(edge_ids), std::get<1>(edge_ids));
18+
}),
19+
py::arg("edge_ids"))
1420
.def("known_dtype", &EdgeEdgeCandidate::known_dtype)
1521
.def(
1622
"__str__",
@@ -32,4 +38,6 @@ void define_edge_edge_candidate(py::module_& m)
3238
"edge0_id", &EdgeEdgeCandidate::edge0_id, "ID of the first edge.")
3339
.def_readwrite(
3440
"edge1_id", &EdgeEdgeCandidate::edge1_id, "ID of the second edge.");
41+
42+
py::implicitly_convertible<std::tuple<long, long>, EdgeEdgeCandidate>();
3543
}

python/src/candidates/edge_face.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ void define_edge_face_candidate(py::module_& m)
1010
{
1111
py::class_<EdgeFaceCandidate>(m, "EdgeFaceCandidate")
1212
.def(py::init<long, long>(), py::arg("edge_id"), py::arg("face_id"))
13+
.def(
14+
py::init([](std::tuple<long, long> face_ids) {
15+
return std::make_unique<EdgeFaceCandidate>(
16+
std::get<0>(face_ids), std::get<1>(face_ids));
17+
}),
18+
py::arg("edge_and_face_id"))
1319
.def(
1420
"__str__",
1521
[](const EdgeFaceCandidate& ev) {
@@ -29,4 +35,6 @@ void define_edge_face_candidate(py::module_& m)
2935
.def_readwrite("edge_id", &EdgeFaceCandidate::edge_id, "ID of the edge")
3036
.def_readwrite(
3137
"face_id", &EdgeFaceCandidate::face_id, "ID of the face");
38+
39+
py::implicitly_convertible<std::tuple<long, long>, EdgeFaceCandidate>();
3240
}

python/src/candidates/edge_vertex.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ void define_edge_vertex_candidate(py::module_& m)
1111
EdgeVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>(
1212
m, "EdgeVertexCandidate")
1313
.def(py::init<long, long>(), py::arg("edge_id"), py::arg("vertex_id"))
14+
.def(
15+
py::init([](std::tuple<long, long> vertex_ids) {
16+
return std::make_unique<EdgeVertexCandidate>(
17+
std::get<0>(vertex_ids), std::get<1>(vertex_ids));
18+
}),
19+
py::arg("edge_and_vertex_id"))
1420
.def("known_dtype", &EdgeVertexCandidate::known_dtype)
1521
.def(
1622
"__str__",
@@ -33,4 +39,6 @@ void define_edge_vertex_candidate(py::module_& m)
3339
"edge_id", &EdgeVertexCandidate::edge_id, "ID of the edge")
3440
.def_readwrite(
3541
"vertex_id", &EdgeVertexCandidate::vertex_id, "ID of the vertex");
42+
43+
py::implicitly_convertible<std::tuple<long, long>, EdgeVertexCandidate>();
3644
}

python/src/candidates/face_face.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ void define_face_face_candidate(py::module_& m)
1010
{
1111
py::class_<FaceFaceCandidate>(m, "FaceFaceCandidate")
1212
.def(py::init<long, long>(), py::arg("face0_id"), py::arg("face1_id"))
13+
.def(
14+
py::init([](std::tuple<long, long> face_ids) {
15+
return std::make_unique<FaceFaceCandidate>(
16+
std::get<0>(face_ids), std::get<1>(face_ids));
17+
}),
18+
py::arg("face_ids"))
1319
.def(
1420
"__str__",
1521
[](const FaceFaceCandidate& ff) {
@@ -30,4 +36,6 @@ void define_face_face_candidate(py::module_& m)
3036
"face0_id", &FaceFaceCandidate::face0_id, "ID of the first face.")
3137
.def_readwrite(
3238
"face1_id", &FaceFaceCandidate::face1_id, "ID of the second face.");
39+
40+
py::implicitly_convertible<std::tuple<long, long>, FaceFaceCandidate>();
3341
}

python/src/candidates/face_vertex.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ void define_face_vertex_candidate(py::module_& m)
1111
FaceVertexCandidate, CollisionStencil, ContinuousCollisionCandidate>(
1212
m, "FaceVertexCandidate")
1313
.def(py::init<long, long>(), py::arg("face_id"), py::arg("vertex_id"))
14+
.def(
15+
py::init([](std::tuple<long, long> vertex_ids) {
16+
return std::make_unique<FaceVertexCandidate>(
17+
std::get<0>(vertex_ids), std::get<1>(vertex_ids));
18+
}),
19+
py::arg("face_and_vertex_id"))
1420
.def("known_dtype", &FaceVertexCandidate::known_dtype)
1521
.def(
1622
"__str__",
@@ -33,4 +39,6 @@ void define_face_vertex_candidate(py::module_& m)
3339
"face_id", &FaceVertexCandidate::face_id, "ID of the face")
3440
.def_readwrite(
3541
"vertex_id", &FaceVertexCandidate::vertex_id, "ID of the vertex");
42+
43+
py::implicitly_convertible<std::tuple<long, long>, FaceVertexCandidate>();
3644
}

python/src/candidates/vertex_vertex.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ void define_vertex_vertex_candidate(py::module_& m)
1313
.def(
1414
py::init<long, long>(), py::arg("vertex0_id"),
1515
py::arg("vertex1_id"))
16+
.def(
17+
py::init([](std::tuple<long, long> vertex_ids) {
18+
return std::make_unique<VertexVertexCandidate>(
19+
std::get<0>(vertex_ids), std::get<1>(vertex_ids));
20+
}),
21+
py::arg("vertex_ids"))
1622
.def(
1723
"__str__",
1824
[](const VertexVertexCandidate& ev) {
@@ -37,4 +43,6 @@ void define_vertex_vertex_candidate(py::module_& m)
3743
.def_readwrite(
3844
"vertex1_id", &VertexVertexCandidate::vertex1_id,
3945
"ID of the second vertex");
46+
47+
py::implicitly_convertible<std::tuple<long, long>, VertexVertexCandidate>();
4048
}

python/src/utils/thread_limiter.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <common.hpp>
22

33
#include <memory>
4+
#include <cstdlib>
45

56
#include <tbb/info.h>
67
#include <tbb/global_control.h>
@@ -40,4 +41,6 @@ void define_thread_limiter(py::module_& m)
4041
m.def(
4142
"set_num_threads", &set_num_threads,
4243
"set maximum number of threads to use", py::arg("nthreads"));
44+
45+
std::atexit([]() { thread_limiter.reset(); });
4346
}

python/tests/test_candidates.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import numpy as np
2+
3+
from find_ipctk import ipctk
4+
from ipctk.filib import Interval
5+
6+
from utils import load_mesh
7+
8+
9+
def test_candidates():
10+
V0, E, F = load_mesh("two-cubes-close.ply")
11+
V1, E, F = load_mesh("two-cubes-intersecting.ply")
12+
13+
mesh = ipctk.CollisionMesh(V0, E, F)
14+
15+
candidates = ipctk.Candidates()
16+
candidates.build(mesh, V0, V1)
17+
18+
assert len(candidates) > 0, "No candidates generated."

python/tests/test_ccd.py

+24-9
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,21 @@ def test_ccd():
2222

2323
assert ipctk.is_step_collision_free(mesh, V0, (V1 - V0) * toi + V0)
2424

25+
2526
def test_custom_ccd():
2627
class DumbNarrowPhaseCCD(ipctk.NarrowPhaseCCD):
2728
def __init__(self):
2829
ipctk.NarrowPhaseCCD.__init__(self)
30+
2931
def point_point_ccd(self, p0_t0, p1_t0, p0_t1, p1_t1, min_distance=0.0, tmax=1.0):
3032
return True, 0.0
33+
3134
def point_edge_ccd(self, p_t0, e0_t0, e1_t0, p_t1, e0_t1, e1_t1, min_distance=0.0, tmax=1.0):
3235
return True, 0.0
36+
3337
def point_triangle_ccd(self, p_t0, t0_t0, t1_t0, t2_t0, p_t1, t0_t1, t1_t1, t2_t1, min_distance=0.0, tmax=1.0):
3438
return True, 0.0
39+
3540
def edge_edge_ccd(self, ea0_t0, ea1_t0, eb0_t0, eb1_t0, ea0_t1, ea1_t1, eb0_t1, eb1_t1, min_distance=0.0, tmax=1.0):
3641
return True, 0.0
3742

@@ -49,38 +54,48 @@ def edge_edge_ccd(self, ea0_t0, ea1_t0, eb0_t0, eb1_t0, ea0_t1, ea1_t1, eb0_t1,
4954
mesh, V0, V1, narrow_phase_ccd=DumbNarrowPhaseCCD())
5055
assert 0 <= toi <= 1
5156

57+
5258
def test_custom_broad_phase():
59+
V0, E, F = load_mesh("two-cubes-close.ply")
60+
V1, E, F = load_mesh("two-cubes-intersecting.ply")
61+
5362
class DumbBroadPhase(ipctk.BroadPhase):
5463
def __init__(self):
5564
ipctk.BroadPhase.__init__(self)
65+
5666
def name(self):
5767
return "DumbBroadPhase"
68+
5869
def detect_vertex_vertex_candidates(self):
5970
return []
71+
6072
def detect_edge_vertex_candidates(self):
6173
return []
74+
6275
def detect_edge_edge_candidates(self):
63-
return []
76+
return [(0, 232)]
77+
6478
def detect_face_vertex_candidates(self):
65-
return []
79+
return [(16, 205)]
80+
6681
def detect_edge_face_candidates(self):
6782
return []
83+
6884
def detect_face_face_candidates(self):
6985
return []
7086

71-
V0, E, F = load_mesh("two-cubes-close.ply")
72-
V1, E, F = load_mesh("two-cubes-intersecting.ply")
73-
7487
mesh = ipctk.CollisionMesh(V0, E, F)
7588

76-
ipctk.set_num_threads(1)
89+
broad_phase = DumbBroadPhase()
7790

78-
assert ipctk.is_step_collision_free(mesh, V0, V1, broad_phase=DumbBroadPhase())
91+
assert ipctk.is_step_collision_free(mesh, V0, V1, broad_phase=broad_phase)
7992

80-
toi = ipctk.compute_collision_free_stepsize(mesh, V0, V1, broad_phase=DumbBroadPhase())
93+
toi = ipctk.compute_collision_free_stepsize(
94+
mesh, V0, V1, broad_phase=broad_phase)
8195
assert toi == 1
8296

83-
assert not ipctk.has_intersections(mesh, V0, broad_phase=DumbBroadPhase())
97+
assert not ipctk.has_intersections(mesh, V0, broad_phase=broad_phase)
98+
8499

85100
def test_nonlinear_ccd():
86101
class LinearTrajectory(ipctk.NonlinearTrajectory):

0 commit comments

Comments
 (0)