Commit ca77518e authored by Alexander Dielen's avatar Alexander Dielen
Browse files

don't expose vector classes and remove *_vec defines

parent 1e64ee4d
Pipeline #6139 passed with stage
in 1 minute and 12 seconds
#include "MeshTypes.hh"
#include "Miscellaneous.hh"
#include "Vector.hh"
#include "Mesh.hh"
#include "Iterator.hh"
#include "Circulator.hh"
......@@ -18,13 +17,6 @@ PYBIND11_MODULE(openmesh, m) {
expose_handles(m);
expose_status_bits_and_info(m);
expose_vec<float, 2>(m, "Vec2f");
expose_vec<float, 3>(m, "Vec3f");
expose_vec<float, 4>(m, "Vec4f");
expose_vec<double, 2>(m, "Vec2d");
expose_vec<double, 3>(m, "Vec3d");
expose_vec<double, 4>(m, "Vec4d");
expose_mesh<PolyMesh>(m, "PolyMesh");
expose_mesh<TriMesh>(m, "TriMesh");
......
......@@ -475,8 +475,6 @@ void expose_type_specific_functions(py::class_<PolyMesh>& _class) {
void (PolyMesh::*split_fh_pt)(OM::FaceHandle, const Point& ) = &PolyMesh::split;
void (PolyMesh::*split_fh_vh)(OM::FaceHandle, OM::VertexHandle) = &PolyMesh::split;
Normal (PolyMesh::*calc_face_normal_pt)(const Point&, const Point&, const Point&) const = &PolyMesh::calc_face_normal;
_class
.def("add_face", add_face_3_vh)
.def("add_face", add_face_4_vh)
......@@ -488,7 +486,6 @@ void expose_type_specific_functions(py::class_<PolyMesh>& _class) {
.def("split", split_fh_vh)
.def("split_copy", &PolyMesh::split_copy)
.def("calc_face_normal_vec", calc_face_normal_pt)
.def("insert_edge", &PolyMesh::insert_edge)
.def("face_vertex_indices", &face_vertex_indices_polymesh)
......@@ -620,47 +617,12 @@ void expose_mesh(py::module& m, const char *_name) {
OM::EdgeHandle (Mesh::*handle_e)(const typename Mesh::Edge& ) const = &Mesh::handle;
OM::FaceHandle (Mesh::*handle_f)(const typename Mesh::Face& ) const = &Mesh::handle;
// Get value of a standard property (point, normal, color)
const typename Mesh::Point& (Mesh::*point_vh )(OM::VertexHandle ) const = &Mesh::point;
const typename Mesh::Normal& (Mesh::*normal_vh)(OM::VertexHandle ) const = &Mesh::normal;
const typename Mesh::Normal& (Mesh::*normal_hh)(OM::HalfedgeHandle) const = &Mesh::normal;
const typename Mesh::Normal& (Mesh::*normal_fh)(OM::FaceHandle ) const = &Mesh::normal;
const typename Mesh::Color& (Mesh::*color_vh )(OM::VertexHandle ) const = &Mesh::color;
const typename Mesh::Color& (Mesh::*color_hh )(OM::HalfedgeHandle) const = &Mesh::color;
const typename Mesh::Color& (Mesh::*color_eh )(OM::EdgeHandle ) const = &Mesh::color;
const typename Mesh::Color& (Mesh::*color_fh )(OM::FaceHandle ) const = &Mesh::color;
// Get value of a standard property (texture coordinate)
const typename Mesh::TexCoord1D& (Mesh::*texcoord1D_vh)(OM::VertexHandle ) const = &Mesh::texcoord1D;
const typename Mesh::TexCoord1D& (Mesh::*texcoord1D_hh)(OM::HalfedgeHandle) const = &Mesh::texcoord1D;
const typename Mesh::TexCoord2D& (Mesh::*texcoord2D_vh)(OM::VertexHandle ) const = &Mesh::texcoord2D;
const typename Mesh::TexCoord2D& (Mesh::*texcoord2D_hh)(OM::HalfedgeHandle) const = &Mesh::texcoord2D;
const typename Mesh::TexCoord3D& (Mesh::*texcoord3D_vh)(OM::VertexHandle ) const = &Mesh::texcoord3D;
const typename Mesh::TexCoord3D& (Mesh::*texcoord3D_hh)(OM::HalfedgeHandle) const = &Mesh::texcoord3D;
// Get value of a standard property (status)
const StatusInfo& (Mesh::*status_vh)(OM::VertexHandle ) const = &Mesh::status;
const StatusInfo& (Mesh::*status_hh)(OM::HalfedgeHandle) const = &Mesh::status;
const StatusInfo& (Mesh::*status_eh)(OM::EdgeHandle ) const = &Mesh::status;
const StatusInfo& (Mesh::*status_fh)(OM::FaceHandle ) const = &Mesh::status;
// Set value of a standard property (point, normal, color)
void (Mesh::*set_normal_vh)(OM::VertexHandle, const typename Mesh::Normal&) = &Mesh::set_normal;
void (Mesh::*set_normal_hh)(OM::HalfedgeHandle, const typename Mesh::Normal&) = &Mesh::set_normal;
void (Mesh::*set_normal_fh)(OM::FaceHandle, const typename Mesh::Normal&) = &Mesh::set_normal;
void (Mesh::*set_color_vh )(OM::VertexHandle, const typename Mesh::Color& ) = &Mesh::set_color;
void (Mesh::*set_color_hh )(OM::HalfedgeHandle, const typename Mesh::Color& ) = &Mesh::set_color;
void (Mesh::*set_color_eh )(OM::EdgeHandle, const typename Mesh::Color& ) = &Mesh::set_color;
void (Mesh::*set_color_fh )(OM::FaceHandle, const typename Mesh::Color& ) = &Mesh::set_color;
// Set value of a standard property (texture coordinate)
void (Mesh::*set_texcoord1D_vh)(OM::VertexHandle, const typename Mesh::TexCoord1D&) = &Mesh::set_texcoord1D;
void (Mesh::*set_texcoord1D_hh)(OM::HalfedgeHandle, const typename Mesh::TexCoord1D&) = &Mesh::set_texcoord1D;
void (Mesh::*set_texcoord2D_vh)(OM::VertexHandle, const typename Mesh::TexCoord2D&) = &Mesh::set_texcoord2D;
void (Mesh::*set_texcoord2D_hh)(OM::HalfedgeHandle, const typename Mesh::TexCoord2D&) = &Mesh::set_texcoord2D;
void (Mesh::*set_texcoord3D_vh)(OM::VertexHandle, const typename Mesh::TexCoord3D&) = &Mesh::set_texcoord3D;
void (Mesh::*set_texcoord3D_hh)(OM::HalfedgeHandle, const typename Mesh::TexCoord3D&) = &Mesh::set_texcoord3D;
// Set value of a standard property (status)
void (*set_status_vh)(Mesh&, OM::VertexHandle, const StatusInfo&) = &set_status;
void (*set_status_hh)(Mesh&, OM::HalfedgeHandle, const StatusInfo&) = &set_status;
......@@ -779,12 +741,6 @@ void expose_mesh(py::module& m, const char *_name) {
// PolyMeshT Function Pointers
//======================================================================
void (Mesh::*calc_edge_vector_eh_normal)(OM::EdgeHandle, Normal&) const = &Mesh::calc_edge_vector;
void (Mesh::*calc_edge_vector_hh_normal)(OM::HalfedgeHandle, Normal&) const = &Mesh::calc_edge_vector;
Normal (Mesh::*calc_edge_vector_eh)(OM::EdgeHandle ) const = &Mesh::calc_edge_vector;
Normal (Mesh::*calc_edge_vector_hh)(OM::HalfedgeHandle) const = &Mesh::calc_edge_vector;
Scalar (Mesh::*calc_edge_length_eh)(OM::EdgeHandle ) const = &Mesh::calc_edge_length;
Scalar (Mesh::*calc_edge_length_hh)(OM::HalfedgeHandle) const = &Mesh::calc_edge_length;
......@@ -802,11 +758,6 @@ void expose_mesh(py::module& m, const char *_name) {
void (Mesh::*split_fh_vh)(OM::FaceHandle, OM::VertexHandle) = &Mesh::split;
void (Mesh::*split_eh_vh)(OM::EdgeHandle, OM::VertexHandle) = &Mesh::split;
Normal (Mesh::*calc_face_normal )(OM::FaceHandle ) const = &Mesh::calc_face_normal;
void (Mesh::*calc_face_centroid_fh_point)(OM::FaceHandle, Point&) const = &Mesh::calc_face_centroid;
Point (Mesh::*calc_face_centroid_fh )(OM::FaceHandle ) const = &Mesh::calc_face_centroid;
//======================================================================
// Mesh Type
//======================================================================
......@@ -875,40 +826,12 @@ void expose_mesh(py::module& m, const char *_name) {
.def("halfedge_handle", halfedge_handle_fh)
.def("set_halfedge_handle", set_halfedge_handle_fh_hh)
.def("point_vec", point_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_point_vec", &Mesh::set_point)
.def("normal_vec", normal_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_normal_vec", set_normal_vh)
.def("normal_vec", normal_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_normal_vec", set_normal_hh)
.def("color_vec", color_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color_vec", set_color_vh)
.def("texcoord1D_vec", texcoord1D_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord1D_vec", set_texcoord1D_vh)
.def("texcoord2D_vec", texcoord2D_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord2D_vec", set_texcoord2D_vh)
.def("texcoord3D_vec", texcoord3D_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord3D_vec", set_texcoord3D_vh)
.def("texcoord1D_vec", texcoord1D_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord1D_vec", set_texcoord1D_hh)
.def("texcoord2D_vec", texcoord2D_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord2D_vec", set_texcoord2D_hh)
.def("texcoord3D_vec", texcoord3D_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord3D_vec", set_texcoord3D_hh)
.def("status", status_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_vh)
.def("status", status_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_hh)
.def("color_vec", color_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color_vec", set_color_hh)
.def("color_vec", color_eh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color_vec", set_color_eh)
.def("status", status_eh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_eh)
.def("normal_vec", normal_fh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_normal_vec", set_normal_fh)
.def("color_vec", color_fh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color_vec", set_color_fh)
.def("status", status_fh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_fh)
......@@ -1066,12 +989,14 @@ void expose_mesh(py::module& m, const char *_name) {
if (!_self.has_face_status()) _self.request_face_status();
_self.delete_vertex(_vh, _delete_isolated);
}, py::arg("vh"), py::arg("delete_isolated_vertices")=true)
.def("delete_edge", [](Mesh& _self, OM::EdgeHandle _eh, bool _delete_isolated) {
if (!_self.has_vertex_status() && _delete_isolated) _self.request_vertex_status();
if (!_self.has_edge_status()) _self.request_edge_status();
if (!_self.has_face_status()) _self.request_face_status();
_self.delete_edge(_eh, _delete_isolated);
}, py::arg("eh"), py::arg("delete_isolated_vertices")=true)
.def("delete_face", [](Mesh& _self, OM::FaceHandle _fh, bool _delete_isolated) {
if (!_self.has_vertex_status() && _delete_isolated) _self.request_vertex_status();
if (!_self.has_face_status()) _self.request_face_status();
......@@ -1115,19 +1040,12 @@ void expose_mesh(py::module& m, const char *_name) {
.def("add_vertex", &Mesh::add_vertex)
.def("calc_edge_vector_vec", calc_edge_vector_eh_normal)
.def("calc_edge_vector_vec", calc_edge_vector_eh)
.def("calc_edge_vector_vec", calc_edge_vector_hh_normal)
.def("calc_edge_vector_vec", calc_edge_vector_hh)
.def("calc_edge_length", calc_edge_length_eh)
.def("calc_edge_length", calc_edge_length_hh)
.def("calc_edge_sqr_length", calc_edge_sqr_length_eh)
.def("calc_edge_sqr_length", calc_edge_sqr_length_hh)
.def("calc_sector_vectors_vec", &Mesh::calc_sector_vectors)
.def("calc_sector_angle", &Mesh::calc_sector_angle)
.def("calc_sector_normal_vec", &Mesh::calc_sector_normal)
.def("calc_sector_area", &Mesh::calc_sector_area)
.def("calc_dihedral_angle_fast", calc_dihedral_angle_fast_hh)
......@@ -1212,17 +1130,6 @@ void expose_mesh(py::module& m, const char *_name) {
.def_static("is_polymesh", &Mesh::is_polymesh)
.def("is_trimesh", &Mesh::is_trimesh)
.def("calc_face_normal_vec", calc_face_normal)
.def("calc_halfedge_normal_vec", &Mesh::calc_halfedge_normal,
py::arg("heh"), py::arg("feature_angle")=0.8)
.def("calc_vertex_normal_vec", &Mesh::calc_vertex_normal)
.def("calc_vertex_normal_fast_vec", &Mesh::calc_vertex_normal_fast)
.def("calc_vertex_normal_correct_vec", &Mesh::calc_vertex_normal_correct)
.def("calc_vertex_normal_loop_vec", &Mesh::calc_vertex_normal_loop)
.def("calc_face_centroid_vec", calc_face_centroid_fh_point)
.def("calc_face_centroid_vec", calc_face_centroid_fh)
//======================================================================
// numpy calc_*
//======================================================================
......@@ -1528,16 +1435,6 @@ void expose_mesh(py::module& m, const char *_name) {
expose_type_specific_functions(class_mesh);
//======================================================================
// Nested Types
//======================================================================
class_mesh.attr("Point") = m.attr("Vec3d");
class_mesh.attr("Normal") = m.attr("Vec3d");
class_mesh.attr("Color") = m.attr("Vec4f");
class_mesh.attr("TexCoord2D") = m.attr("Vec2f");
class_mesh.attr("TexCoord3D") = m.attr("Vec3f");
}
#endif
#ifndef OPENMESH_PYTHON_VECTOR_HH
#define OPENMESH_PYTHON_VECTOR_HH
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
template <class Vector, class Scalar>
void set_item(Vector& _vec, int _index, Scalar _value) {
if (_index < 0) {
_index += _vec.size();
}
if ((size_t)_index < _vec.size()) {
_vec[_index] = _value;
}
else {
throw py::index_error();
}
}
template <class Vector, class Scalar>
Scalar get_item(Vector& _vec, int _index) {
if (_index < 0) {
_index += _vec.size();
}
if ((size_t)_index < _vec.size()) {
return _vec[_index];
}
else {
throw py::index_error();
}
return 0.0;
}
namespace {
template<class Scalar>
struct Factory {
typedef OpenMesh::VectorT<Scalar, 2> Vector2;
typedef OpenMesh::VectorT<Scalar, 3> Vector3;
typedef OpenMesh::VectorT<Scalar, 4> Vector4;
static Vector2 *vec2_default() {
return new Vector2(Scalar(), Scalar());
}
static Vector2 *vec2_user_defined(const Scalar& _v0, const Scalar& _v1) {
return new Vector2(_v0, _v1);
}
static Vector3 *vec3_default() {
return new Vector3(Scalar(), Scalar(), Scalar());
}
static Vector3 *vec3_user_defined(const Scalar& _v0, const Scalar& _v1, const Scalar& _v2) {
return new Vector3(_v0, _v1, _v2);
}
static Vector4 *vec4_default() {
return new Vector4(Scalar(), Scalar(), Scalar(), Scalar());
}
static Vector4 *vec4_user_defined(const Scalar& _v0, const Scalar& _v1, const Scalar& _v2, const Scalar& _v3) {
return new Vector4(_v0, _v1, _v2, _v3);
}
};
}
template<class Scalar, class Vector>
void defInitMod(py::module& m, py::class_< OpenMesh::VectorT<Scalar, 2> > &classVector) {
classVector
.def(py::init(&Factory<Scalar>::vec2_default))
.def(py::init(&Factory<Scalar>::vec2_user_defined))
;
}
template<class Scalar, class Vector>
void defInitMod(py::module& m, py::class_< OpenMesh::VectorT<Scalar, 3> > &classVector) {
Vector (Vector::*cross)(const Vector&) const = &Vector::operator%;
classVector
.def(py::init(&Factory<Scalar>::vec3_default))
.def(py::init(&Factory<Scalar>::vec3_user_defined))
.def("__mod__", cross)
;
m.def("cross", cross);
}
template<class Scalar, class Vector>
void defInitMod(py::module& m, py::class_< OpenMesh::VectorT<Scalar, 4> > &classVector) {
classVector
.def(py::init(&Factory<Scalar>::vec4_default))
.def(py::init(&Factory<Scalar>::vec4_user_defined))
;
}
/**
* Expose a vector type to %Python.
*
* This function template is used to expose vectors to %Python. The template
* parameters are used to instantiate the appropriate vector type.
*
* @tparam Scalar A scalar type.
* @tparam N The dimension of the vector.
*
* @param _name The name of the vector type to be exposed.
*
* @note N must be either 2, 3 or 4.
*/
template<class Scalar, int N>
void expose_vec(py::module& m, const char *_name) {
typedef OpenMesh::VectorT<Scalar, N> Vector;
Scalar (Vector::*min_void)() const = &Vector::min;
Scalar (Vector::*max_void)() const = &Vector::max;
Vector (Vector::*max_vector)(const Vector&) const = &Vector::max;
Vector (Vector::*min_vector)(const Vector&) const = &Vector::min;
Scalar (Vector::*dot )(const Vector&) const = &Vector::operator|;
Scalar (Vector::*norm )(void ) const = &Vector::norm;
Scalar (Vector::*length )(void ) const = &Vector::length;
Scalar (Vector::*sqrnorm )(void ) const = &Vector::sqrnorm;
Vector& (Vector::*normalize )(void ) = &Vector::normalize;
Vector& (Vector::*normalize_cond)(void ) = &Vector::normalize_cond;
Vector& (Vector::*op_selfmul_scalar)(const Scalar&) = &Vector::operator*=;
Vector& (Vector::*op_selfmul_vector)(const Vector&) = &Vector::operator*=;
Vector& (Vector::*op_selfdiv_scalar)(const Scalar&) = &Vector::operator/=;
Vector& (Vector::*op_selfdiv_vector)(const Scalar&) = &Vector::operator/=;
Vector& (Vector::*op_selfadd_vector)(const Vector&) = &Vector::operator+=;
Vector& (Vector::*op_selfsub_vector)(const Vector&) = &Vector::operator-=;
Vector (Vector::*op_mul_scalar )(const Scalar&) const = &Vector::operator*;
Vector (Vector::*op_mul_vector )(const Vector&) const = &Vector::operator*;
Vector (Vector::*op_div_scalar )(const Scalar&) const = &Vector::operator/;
Vector (Vector::*op_div_vector )(const Vector&) const = &Vector::operator/;
Vector (Vector::*op_add_vector )(const Vector&) const = &Vector::operator+;
Vector (Vector::*op_sub_vector )(const Vector&) const = &Vector::operator-;
Vector (Vector::*op_unary_minus )(void ) const = &Vector::operator-;
#if (_MSC_VER >= 1800 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
Vector (Vector::*normalized)() const = &Vector::normalized;
#else
const Vector (Vector::*normalized)() const = &Vector::normalized;
#endif
py::class_<Vector> classVector = py::class_<Vector>(m, _name);
classVector
.def("__setitem__", &set_item<Vector, Scalar>)
.def("__getitem__", &get_item<Vector, Scalar>)
.def("__eq__", &Vector::operator==)
.def("__ne__", &Vector::operator!=)
.def("__lt__", &Vector::operator<)
.def("__imul__", op_selfmul_scalar)
.def("__imul__", op_selfmul_vector)
.def("__itruediv__", op_selfdiv_scalar)
.def("__itruediv__", op_selfdiv_vector)
.def("__iadd__", op_selfadd_vector)
.def("__isub__", op_selfsub_vector)
.def("__mul__", op_mul_scalar)
.def("__mul__", op_mul_vector)
.def("__rmul__", op_mul_scalar)
.def("__truediv__", op_div_scalar)
.def("__truediv__", op_div_vector)
.def("__add__", op_add_vector)
.def("__sub__", op_sub_vector)
.def("__neg__", op_unary_minus)
.def("__or__", dot)
.def("vectorize", &Vector::vectorize, py::return_value_policy::reference_internal)
.def("dot", dot)
.def("norm", norm)
.def("length", length)
.def("sqrnorm", sqrnorm)
.def("normalized", normalized)
.def("normalize", normalize, py::return_value_policy::reference_internal)
.def("normalize_cond", normalize_cond, py::return_value_policy::reference_internal)
.def("l1_norm", &Vector::l1_norm)
.def("l8_norm", &Vector::l8_norm)
.def("max", max_void)
.def("max_abs", &Vector::max_abs)
.def("min", min_void)
.def("min_abs", &Vector::min_abs)
.def("mean", &Vector::mean)
.def("mean_abs", &Vector::mean_abs)
.def("minimize", &Vector::minimize, py::return_value_policy::reference_internal)
.def("minimized", &Vector::minimized)
.def("maximize", &Vector::maximize, py::return_value_policy::reference_internal)
.def("maximized", &Vector::maximized)
.def("min", min_vector)
.def("max", max_vector)
.def_static("size", &Vector::size)
.def_static("vectorized", &Vector::vectorized)
.def(py::init([](py::array_t<Scalar, py::array::c_style | py::array::forcecast> _arr) {
if (_arr.size() != N) {
throw std::runtime_error("Incompatible array size!");
}
return Vector(_arr.data());
}));
;
defInitMod<Scalar, Vector>(m, classVector);
}
#endif
import unittest
import openmesh
class VectorTest(unittest.TestCase):
def test_compute_triangle_surface_with_cross_product(self):
# vec1
# y
# |
# |
# |
# x------>x vec2
vec1 = openmesh.Vec3d(0.0, 1.0, 0.0)
vec2 = openmesh.Vec3d(1.0, 0.0, 0.0)
area = 0.5 * openmesh.cross(vec1, vec2).norm()
self.assertEqual(area, 0.5)
area = 0.5 * (vec1 % vec2).norm()
self.assertEqual(area, 0.5)
def test_equality_operator_vec3d(self):
vec1 = openmesh.Vec3d(0.0, 1.0, 0.0)
vec2 = openmesh.Vec3d(1.0, 0.0, 0.0)
vec3 = openmesh.Vec3d(1.0, 0.0, 0.0)
self.assertFalse(vec1==vec2)
self.assertTrue(vec3==vec2)
def test_equality_operator_vec3f(self):
vec1 = openmesh.Vec3f(0.0, 1.0, 0.0)
vec2 = openmesh.Vec3f(1.0, 0.0, 0.0)
vec3 = openmesh.Vec3f(1.0, 0.0, 0.0)
self.assertFalse(vec1==vec2)
self.assertTrue(vec3==vec2)
def test_abs_test(self):
vec1 = openmesh.Vec3d(0.5, 0.5, -0.5)
self.assertEqual(vec1.l8_norm(), 0.5)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(VectorTest)
unittest.TextTestRunner(verbosity=2).run(suite)
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