Vector.hh 5.52 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
namespace {
template<class Scalar>
struct Factory {
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
	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);
	}
66
67
68
};
}

69
template<class Scalar, class Vector>
Jan Möbius's avatar
Jan Möbius committed
70
void defInitMod(class_< OpenMesh::VectorT<Scalar, 2> > &classVector) {
71
72
73
74
	classVector
		.def("__init__", make_constructor(&Factory<Scalar>::vec2_default))
		.def("__init__", make_constructor(&Factory<Scalar>::vec2_user_defined))
		;
75
}
76
77

template<class Scalar, class Vector>
Jan Möbius's avatar
Jan Möbius committed
78
void defInitMod(class_< OpenMesh::VectorT<Scalar, 3> > &classVector) {
79
80
81
82
83
84
85
	Vector (Vector::*cross)(const Vector&) const = &Vector::operator%;
	classVector
		.def("__init__", make_constructor(&Factory<Scalar>::vec3_default))
		.def("__init__", make_constructor(&Factory<Scalar>::vec3_user_defined))
		.def("__mod__", cross)
		;
	def("cross", cross);
86
}
87
88

template<class Scalar, class Vector>
Jan Möbius's avatar
Jan Möbius committed
89
void defInitMod(class_< OpenMesh::VectorT<Scalar, 4> > &classVector) {
90
91
92
93
	classVector
		.def("__init__", make_constructor(&Factory<Scalar>::vec4_default))
		.def("__init__", make_constructor(&Factory<Scalar>::vec4_user_defined))
		;
94
95
}

Jan Möbius's avatar
Jan Möbius committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
 * 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;

119
120
121
122
123
124
125
126
127
128
129
130
131
	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;

#if (_MSC_VER >= 1900 || __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

Jan Möbius's avatar
Jan Möbius committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
	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)

157
158
159
160
161
162
163
		.def("dot", dot)
		.def("norm", norm)
		.def("length", length)
		.def("sqrnorm", sqrnorm)
		.def("normalized", normalized)
		.def("normalize", normalize, return_internal_reference<>())
		.def("normalize_cond", normalize_cond, return_internal_reference<>())
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")
		;

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

} // namespace OpenMesh
} // namespace Python

#endif