Commit 1722d006 authored by Alexander Dielen's avatar Alexander Dielen

added mesh constructor that takes arrays

parent 77871b94
Pipeline #6523 passed with stages
in 5 minutes and 23 seconds
......@@ -596,6 +596,50 @@ void expose_mesh(py::module& m, const char *_name) {
class_mesh
.def(py::init<>())
.def(py::init([](py::array_t<typename Point::value_type> _points, py::array_t<int> _faces) {
Mesh mesh;
// return if _points is empty
if (_points.size() == 0) {
return mesh;
}
// _points is not empty, throw if _points has wrong shape
if (_points.ndim() != 2 || _points.shape(1) != 3) {
PyErr_SetString(PyExc_RuntimeError, "Array 'points' must have shape (n, 3)");
throw py::error_already_set();
}
for (ssize_t i = 0; i < _points.shape(0); ++i) {
mesh.add_vertex(Point(_points.at(i, 0), _points.at(i, 1), _points.at(i, 2)));
}
// return if _faces is empty
if (_faces.size() == 0) {
return mesh;
}
// _faces is not empty, throw if _faces has wrong shape
if (_faces.ndim() != 2 || _faces.shape(1) < 3) {
PyErr_SetString(PyExc_RuntimeError, "Array 'face_vertex_indices' must have shape (n, m) with m > 2");
throw py::error_already_set();
}
for (ssize_t i = 0; i < _faces.shape(0); ++i) {
std::vector<OM::VertexHandle> vhandles;
for (ssize_t j = 0; j < _faces.shape(1); ++j) {
if (_faces.at(i, j) >= 0 && _faces.at(i, j) < _points.shape(0)) {
vhandles.push_back(OM::VertexHandle(_faces.at(i, j)));
}
}
if (vhandles.size() >= 3) {
mesh.add_face(vhandles);
}
}
return mesh;
}), py::arg("points"), py::arg("face_vertex_indices")=py::array_t<int>())
//======================================================================
// KernelT
//======================================================================
......
......@@ -354,6 +354,46 @@ class Python(unittest.TestCase):
self.delete_vertices()
self.assertRaises(RuntimeError, self.mesh.halfedge_edge_indices)
self.assertRaises(RuntimeError, self.mesh.he_indices)
def test_init_with_arrays(self):
points = self.mesh.points()
face_vertex_indices = self.mesh.face_vertex_indices()
# init polymesh
polymesh = openmesh.PolyMesh(points, face_vertex_indices)
self.assertEqual(polymesh.n_vertices(), self.mesh.n_vertices())
self.assertEqual(polymesh.n_faces(), self.mesh.n_faces())
# init trimesh (one face will be triangulated)
trimesh = openmesh.TriMesh(points, face_vertex_indices)
self.assertEqual(trimesh.n_vertices(), self.mesh.n_vertices())
self.assertEqual(trimesh.n_faces(), self.mesh.n_faces() + 1)
# init with empty points and faces
trimesh = openmesh.TriMesh(np.empty((0, 3)), np.empty((0, 4)))
self.assertEqual(trimesh.n_vertices(), 0)
self.assertEqual(trimesh.n_faces(), 0)
# init with empty points
trimesh = openmesh.TriMesh(np.empty((0, 3)), face_vertex_indices)
self.assertEqual(trimesh.n_vertices(), 0)
self.assertEqual(trimesh.n_faces(), 0)
# init with empty faces
trimesh = openmesh.TriMesh(points, np.empty((0, 4)))
self.assertEqual(trimesh.n_vertices(), self.mesh.n_vertices())
self.assertEqual(trimesh.n_faces(), 0)
# init with points only
trimesh = openmesh.TriMesh(points)
self.assertEqual(trimesh.n_vertices(), self.mesh.n_vertices())
self.assertEqual(trimesh.n_faces(), 0)
# init with wrong points shape
with self.assertRaises(RuntimeError):
openmesh.TriMesh(points[:, :2])
# init with wrong faces shape
with self.assertRaises(RuntimeError):
openmesh.TriMesh(points, face_vertex_indices[:, :2])
# init with points and invalid faces
face_vertex_indices[1] = [-1, -1, -1, -1]
face_vertex_indices[3] = [-1, -1, -1, -1]
polymesh = openmesh.PolyMesh(points, face_vertex_indices)
self.assertEqual(polymesh.n_vertices(), self.mesh.n_vertices())
self.assertEqual(polymesh.n_faces(), self.mesh.n_faces() - 2)
if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment