Vector.hh 5.92 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#ifndef OPENMESH_PYTHON_VECTOR_HH
#define OPENMESH_PYTHON_VECTOR_HH

#include "Python/Bindings.hh"

namespace OpenMesh {
namespace Python {

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 {
		PyErr_SetString(PyExc_IndexError, "Index out of range.");
		throw_error_already_set();
	}
}

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 {
		PyErr_SetString(PyExc_IndexError, "Index out of range.");
		throw_error_already_set();
	}

	return 0.0;
}

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
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>
Jan Möbius's avatar
Jan Möbius committed
70
void defInitMod(class_< OpenMesh::VectorT<Scalar, 2> > &classVector) {
71 72 73 74 75 76
    classVector
        .def("__init__", make_constructor(&Factory<Scalar>::vec2_default))
        .def("__init__", make_constructor(&Factory<Scalar>::vec2_user_defined))
        ;
}
template<class Scalar>
Jan Möbius's avatar
Jan Möbius committed
77
void defInitMod(class_< OpenMesh::VectorT<Scalar, 3> > &classVector) {
78 79 80
    classVector
        .def("__init__", make_constructor(&Factory<Scalar>::vec3_default))
        .def("__init__", make_constructor(&Factory<Scalar>::vec3_user_defined))
81 82 83 84 85
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
        .def("__mod__", &Factory<Scalar>::Vector3::template operator%<Scalar>)
        ;
    def("cross", &Factory<Scalar>::Vector3::template operator%<Scalar>);
#else
86 87 88
        .def("__mod__", &Factory<Scalar>::Vector3::operator%)
        ;
    def("cross", &Factory<Scalar>::Vector3::operator%);
89
#endif
90 91
}
template<class Scalar>
Jan Möbius's avatar
Jan Möbius committed
92
void defInitMod(class_< OpenMesh::VectorT<Scalar, 4> > &classVector) {
93 94 95 96 97 98
    classVector
        .def("__init__", make_constructor(&Factory<Scalar>::vec4_default))
        .def("__init__", make_constructor(&Factory<Scalar>::vec4_user_defined))
        ;
}

Jan Möbius's avatar
Jan Möbius committed
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
/**
 * 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(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;

	class_<Vector> classVector = class_<Vector>(_name);

	classVector
		.def("__setitem__", &set_item<Vector, Scalar>)
		.def("__getitem__", &get_item<Vector, Scalar>)
		.def(self == self)
		.def(self != self)
		.def(self *= Scalar())
		.def(self /= Scalar())
		.def(self * Scalar())
		.def(Scalar() * self)
		.def(self / Scalar())
		.def(self *= self)
		.def(self /= self)
		.def(self -= self)
		.def(self += self)
		.def(self * self)
		.def(self / self)
		.def(self + self)
		.def(self - self)
		.def(-self)
		.def(self | self)
		.def("vectorize", &Vector::vectorize, return_internal_reference<>())
		.def(self < self)

Janis Born's avatar
Janis Born committed
147
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
148
        .def("dot", &Vector::template operator|<Scalar>)
149 150 151 152 153 154 155
        .def("norm", &Vector::template norm<Scalar>)
        .def("length", &Vector::template length<Scalar>)
        .def("sqrnorm", &Vector::template sqrnorm<Scalar>)
        .def("normalize", &Vector::template normalize<Scalar>, return_internal_reference<>())
        .def("normalized", &Vector::template normalized<Scalar>)
        .def("normalize_cond", &Vector::template normalize_cond<Scalar>, return_internal_reference<>())
#else
156
        .def("dot", &Vector::operator|)
157 158 159 160 161 162 163
        .def("norm", &Vector::norm)
        .def("length", &Vector::length)
        .def("sqrnorm", &Vector::sqrnorm)
        .def("normalize", &Vector::normalize, return_internal_reference<>())
        .def("normalized", &Vector::normalized)
        .def("normalize_cond", &Vector::normalize_cond, return_internal_reference<>())
#endif
Jan Möbius's avatar
Jan Möbius committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

		.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, return_internal_reference<>())
		.def("minimized", &Vector::minimized)
		.def("maximize", &Vector::maximize, return_internal_reference<>())
		.def("maximized", &Vector::maximized)
		.def("min", min_vector)
		.def("max", max_vector)

		.def("size", &Vector::size)
		.staticmethod("size")
		.def("vectorized", &Vector::vectorized)
		.staticmethod("vectorized")
		;

Janis Born's avatar
Janis Born committed
187
    defInitMod<Scalar>(classVector);
Jan Möbius's avatar
Jan Möbius committed
188 189 190 191 192 193
}

} // namespace OpenMesh
} // namespace Python

#endif