Skip to content

Commit 8bd4910

Browse files
committed
fix: add fixed edges
trimesh.add_fixed_edges(np.array([[vertex_index1, vertex_index2]])
1 parent cac4751 commit 8bd4910

3 files changed

Lines changed: 84 additions & 56 deletions

File tree

loop_cgal/bindings.cpp

Lines changed: 61 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,60 +10,67 @@ namespace py = pybind11;
1010
PYBIND11_MODULE(loop_cgal, m)
1111
{
1212

13-
m.def("clip_surface", &clip_surface, py::arg("tm"), py::arg("clipper"),
14-
py::arg("target_edge_length") = 10.0,
15-
py::arg("remesh_before_clipping") = true,
16-
py::arg("remesh_after_clipping") = true,
17-
py::arg("remove_degenerate_faces") = true,
18-
py::arg("duplicate_vertex_threshold") = 1e-6,
19-
py::arg("area_threshold") = 1e-6,
20-
py::arg("protect_constraints") = false,
21-
py::arg("relax_constraints") = true, py::arg("verbose") = false,
22-
"Clip one surface with another.");
23-
m.def("clip_plane", &clip_plane, py::arg("tm"), py::arg("clipper"),
24-
py::arg("target_edge_length") = 10.0,
25-
py::arg("remesh_before_clipping") = true,
26-
py::arg("remesh_after_clipping") = true,
27-
py::arg("remove_degenerate_faces") = true,
28-
py::arg("duplicate_vertex_threshold") = 1e-6,
29-
py::arg("area_threshold") = 1e-6,
30-
py::arg("protect_constraints") = false,
31-
py::arg("relax_constraints") = true, py::arg("verbose") = false,
32-
33-
"Clip a surface with a plane.");
34-
m.def("corefine_mesh", &corefine_mesh, py::arg("tm1"), py::arg("tm2"),
35-
py::arg("target_edge_length") = 10.0,
36-
py::arg("duplicate_vertex_threshold") = 1e-6,
37-
py::arg("area_threshold") = 1e-6, py::arg("number_of_iterations") = 3,
38-
py::arg("relax_constraints") = true,
39-
py::arg("protect_constraints") = false, py::arg("verbose") = false,
40-
"Corefine two meshes.");
41-
py::class_<NumpyMesh>(m, "NumpyMesh")
42-
.def(py::init<>())
43-
.def_readwrite("vertices", &NumpyMesh::vertices)
44-
.def_readwrite("triangles", &NumpyMesh::triangles);
45-
py::class_<NumpyPlane>(m, "NumpyPlane")
46-
.def(py::init<>())
47-
.def_readwrite("normal", &NumpyPlane::normal)
48-
.def_readwrite("origin", &NumpyPlane::origin);
49-
py::class_<TriMesh>(m, "TriMesh")
50-
.def(py::init<const pybind11::array_t<double> &, const pybind11::array_t<int> &>(),
51-
py::arg("vertices"), py::arg("triangles"))
52-
.def("cut_with_surface", &TriMesh::cutWithSurface, py::arg("surface"),
53-
py::arg("verbose") = false,
54-
py::arg("preserve_intersection") = false,
55-
py::arg("preserve_intersection_clipper") = false)
56-
.def("remesh", &TriMesh::remesh, py::arg("split_long_edges") = true,
57-
py::arg("verbose") = false,
58-
py::arg("target_edge_length") = 10.0,
59-
py::arg("number_of_iterations") = 3,
60-
py::arg("protect_constraints") = true,
61-
py::arg("relax_constraints") = false)
62-
.def("save", &TriMesh::save, py::arg("area_threshold") = 1e-6,
63-
py::arg("duplicate_vertex_threshold") = 1e-6,
64-
py::arg("verbose") = false)
65-
.def("reverse_face_orientation", &TriMesh::reverseFaceOrientation,
66-
"Reverse the face orientation of the mesh.");
13+
m.def("clip_surface", &clip_surface, py::arg("tm"), py::arg("clipper"),
14+
py::arg("target_edge_length") = 10.0,
15+
py::arg("remesh_before_clipping") = true,
16+
py::arg("remesh_after_clipping") = true,
17+
py::arg("remove_degenerate_faces") = true,
18+
py::arg("duplicate_vertex_threshold") = 1e-6,
19+
py::arg("area_threshold") = 1e-6,
20+
py::arg("protect_constraints") = false,
21+
py::arg("relax_constraints") = true, py::arg("verbose") = false,
22+
"Clip one surface with another.");
23+
m.def("clip_plane", &clip_plane, py::arg("tm"), py::arg("clipper"),
24+
py::arg("target_edge_length") = 10.0,
25+
py::arg("remesh_before_clipping") = true,
26+
py::arg("remesh_after_clipping") = true,
27+
py::arg("remove_degenerate_faces") = true,
28+
py::arg("duplicate_vertex_threshold") = 1e-6,
29+
py::arg("area_threshold") = 1e-6,
30+
py::arg("protect_constraints") = false,
31+
py::arg("relax_constraints") = true, py::arg("verbose") = false,
6732

33+
"Clip a surface with a plane.");
34+
m.def("corefine_mesh", &corefine_mesh, py::arg("tm1"), py::arg("tm2"),
35+
py::arg("target_edge_length") = 10.0,
36+
py::arg("duplicate_vertex_threshold") = 1e-6,
37+
py::arg("area_threshold") = 1e-6, py::arg("number_of_iterations") = 3,
38+
py::arg("relax_constraints") = true,
39+
py::arg("protect_constraints") = false, py::arg("verbose") = false,
40+
"Corefine two meshes.");
41+
py::class_<NumpyMesh>(m, "NumpyMesh")
42+
.def(py::init<>())
43+
.def_readwrite("vertices", &NumpyMesh::vertices)
44+
.def_readwrite("triangles", &NumpyMesh::triangles)
45+
.def_readwrite("properties", &NumpyMesh::properties,
46+
"Dictionary to hold vertex properties.");
47+
py::class_<NumpyPlane>(m, "NumpyPlane")
48+
.def(py::init<>())
49+
.def_readwrite("normal", &NumpyPlane::normal)
50+
.def_readwrite("origin", &NumpyPlane::origin);
51+
py::class_<TriMesh>(m, "TriMesh")
52+
.def(py::init<const pybind11::array_t<double> &, const pybind11::array_t<int> &>(),
53+
py::arg("vertices"), py::arg("triangles"))
54+
.def("cut_with_surface", &TriMesh::cutWithSurface, py::arg("surface"),
55+
py::arg("verbose") = false,
56+
py::arg("preserve_intersection") = false,
57+
py::arg("preserve_intersection_clipper") = false)
58+
.def("add_vertex_property", &TriMesh::add_vertex_property,
59+
py::arg("name"), py::arg("values"),
60+
"Add a vertex property to the mesh.")
61+
.def("remesh", &TriMesh::remesh, py::arg("split_long_edges") = true,
62+
py::arg("verbose") = false,
63+
py::arg("target_edge_length") = 10.0,
64+
py::arg("number_of_iterations") = 3,
65+
py::arg("protect_constraints") = true,
66+
py::arg("relax_constraints") = false)
67+
.def("save", &TriMesh::save, py::arg("area_threshold") = 1e-6,
68+
py::arg("duplicate_vertex_threshold") = 1e-6,
69+
py::arg("verbose") = false)
70+
.def("reverse_face_orientation", &TriMesh::reverseFaceOrientation,
71+
"Reverse the face orientation of the mesh.")
72+
.def("add_fixed_edges", &TriMesh::add_fixed_edges,
73+
py::arg("pairs"),
74+
"Vertex index pairs defining edges to be fixed in mesh when remeshing.");
6875

6976
} // End of PYBIND11_MODULE

src/mesh.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ void TriMesh::init(){
7979
_fixedEdges = collect_border_edges(_mesh);
8080
_edge_is_constrained_map = CGAL::make_boolean_property_map(_fixedEdges);
8181
}
82+
83+
84+
void TriMesh::add_fixed_edges(const pybind11::array_t<int> &pairs) {
85+
// Convert std::set<std::array<int, 2>> to std::set<TriangleMesh::Edge_index>
86+
auto pairs_buf = pairs.unchecked<2>();
87+
for (ssize_t i = 0; i < pairs_buf.shape(0); ++i) {
88+
TriangleMesh::Edge_index e = _mesh.edge(_mesh.halfedge(TriangleMesh::Vertex_index(pairs_buf(i, 0)),
89+
TriangleMesh::Vertex_index(pairs_buf(i, 1))));
90+
_fixedEdges.insert(e);
91+
// if (e.is_valid()) {
92+
// _fixedEdges.insert(e);
93+
// } else {
94+
// std::cerr << "Warning: Edge (" << edge[0] << ", " << edge[1] << ") is not valid in the mesh." << std::endl;
95+
// }
96+
}
97+
// // Update the property map with the new fixed edges
98+
_edge_is_constrained_map = CGAL::make_boolean_property_map(_fixedEdges);
99+
}
82100
void TriMesh::remesh(bool split_long_edges, bool verbose,
83101
double target_edge_length, int number_of_iterations,
84102
bool protect_constraints, bool relax_constraints)

src/mesh.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class TriMesh
2323
const std::vector<std::pair<double, double>> &vertices);
2424
TriMesh(const pybind11::array_t<double> &vertices,
2525
const pybind11::array_t<int> &triangles);
26+
2627
// Method to cut the mesh with another surface object
2728
void cutWithSurface(TriMesh &surface, bool verbose = false,
2829
bool preserve_intersection = false,
@@ -32,16 +33,18 @@ class TriMesh
3233
void remesh(bool split_long_edges, bool verbose,
3334
double target_edge_length, int number_of_iterations,
3435
bool protect_constraints, bool relax_constraints);
35-
TriangleMesh make_solid(bool preserve_constraints = false, double thickness = 0.1) const;
3636
void init();
3737
// Getters for mesh properties
3838
void reverseFaceOrientation();
3939
NumpyMesh save(double area_threshold,
4040
double duplicate_vertex_threshold, bool verbose = false);
41+
void add_fixed_edges(const pybind11::array_t<int> &pairs);
4142

42-
private: std::set<TriangleMesh::Edge_index> _fixedEdges;
43+
private:
44+
std::set<TriangleMesh::Edge_index> _fixedEdges;
4345
TriangleMesh _mesh; // The underlying CGAL surface mesh
4446
CGAL::Boolean_property_map<std::set<TriangleMesh::Edge_index>> _edge_is_constrained_map;
47+
4548
};
4649

4750
#endif // MESH_HANDLER_H

0 commit comments

Comments
 (0)