Vector.hh 5.38 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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
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, int N>
void defInitMod(class_<OpenMesh::VectorT<Scalar, N>> &classVector);

template<class Scalar>
void defInitMod(class_<OpenMesh::VectorT<Scalar, 2>> &classVector) {
    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>
void defInitMod(class_<OpenMesh::VectorT<Scalar, 3>> &classVector) {
    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>
void defInitMod(class_<OpenMesh::VectorT<Scalar, 4>> &classVector) {
    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
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 151 152 153
/**
 * 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)

154 155 156 157 158 159
		.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<>())
Jan Möbius's avatar
Jan Möbius committed
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182

		.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")
		;

183
	defInitMod<Scalar, N>(classVector);
Jan Möbius's avatar
Jan Möbius committed
184 185 186 187 188 189
}

} // namespace OpenMesh
} // namespace Python

#endif