Vector.hh 5.76 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 77 78 79
    classVector
        .def("__init__", make_constructor(&Factory<Scalar>::vec2_default))
        .def("__init__", make_constructor(&Factory<Scalar>::vec2_user_defined))
        ;

    typedef OpenMesh::VectorT<Scalar, 2> Vector;
    def("dot", &Vector::operator|);
}
template<class Scalar>
Jan Möbius's avatar
Jan Möbius committed
80
void defInitMod(class_< OpenMesh::VectorT<Scalar, 3> > &classVector) {
81 82 83 84 85 86 87 88 89 90 91 92
    classVector
        .def("__init__", make_constructor(&Factory<Scalar>::vec3_default))
        .def("__init__", make_constructor(&Factory<Scalar>::vec3_user_defined))
        .def("__mod__", &Factory<Scalar>::Vector3::operator%)
        ;

    def("cross", &Factory<Scalar>::Vector3::operator%);

    typedef OpenMesh::VectorT<Scalar, 3> Vector;
    def("dot", &Vector::operator|);
}
template<class Scalar>
Jan Möbius's avatar
Jan Möbius committed
93
void defInitMod(class_< OpenMesh::VectorT<Scalar, 4> > &classVector) {
94 95 96 97 98 99 100 101 102
    classVector
        .def("__init__", make_constructor(&Factory<Scalar>::vec4_default))
        .def("__init__", make_constructor(&Factory<Scalar>::vec4_user_defined))
        ;

    typedef OpenMesh::VectorT<Scalar, 4> Vector;
    def("dot", &Vector::operator|);
}

Jan Möbius's avatar
Jan Möbius committed
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 147 148 149 150
/**
 * 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)

151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#if (__cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
        .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
        .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
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

		.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
189
    defInitMod<Scalar>(classVector);
Jan Möbius's avatar
Jan Möbius committed
190 191 192 193 194 195
}

} // namespace OpenMesh
} // namespace Python

#endif