Reputation:
So I've gotten to the point where I need to start wrapping a lot of functionality of GLM into my embedded Python module.
One of the nice things about GLM is that it defines all it's typical vector math functions (length
, normalize
etc.) as free-standing static functions. This works lovely when writing C++, but it's throwing a wrench in things when trying to wrap this functionality as part of a class definition.
I want to call len
on my Vec3F
class and have it call the correct overload of length
while passing self
as the first and only argument. The Boost.Python documentation is fairly opaque and there's not a lot of examples, so I don't even know if this is possible.
Implementing a length
function in the vec2
and vec3
structs is not possible, since these structs are in another project; I have to deal with the structs as-is.
Any help is greatly appreciated!
Vec3F v
v.x = 1.0
v.y = 1.0
v.z = 1.0
print len(v) # should print 1.732050...
template<typename T>
struct vec2
{
T x;
T y;
};
template<typename T>
struct vec3
{
T x;
T y;
T z;
};
template<typename T>
float length(vec2& v)
{
return sqrt(v.x * v.x + v.y * v.y);
}
template<typename T>
float length(vec3& v)
{
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
BOOST_PYTHON_MODULE(naga)
{
class_<vec2<float>, "Vec2F")
.def("x", &vec2<float>::x)
.def("y", &vec2<float>::y)
.def("__len__", /* ??? */); // not sure what needs to be here!
class_<vec3<float>, "Vec3F")
.def("x", &vec2<float>::x)
.def("y", &vec2<float>::y)
.def("__len__", /* ??? */); // not sure what needs to be here!
}
Upvotes: 0
Views: 311
Reputation: 8494
You will need a wrapper class but still __len__
is not going to return the correct result probably because the return value is converted into integer internally (I suspect __len__
must always return integer value).
So you will need to expose it as len
to get correct floating point return value.
namespace bp = boost::python;
template<typename T>
struct vec2
{
T x;
T y;
};
template<typename T>
struct vec3
{
T x;
T y;
T z;
};
template <typename T>
struct vec2_wrapper : vec2<T>
{
float length()
{
return sqrt(x * x + y * y);
}
};
template <typename T>
struct vec3_wrapper : vec3<T>
{
float length()
{
return sqrt(x * x + y * y + z * z);
}
};
BOOST_PYTHON_MODULE(naga)
{
bp::class_ < vec2_wrapper<float> >("Vec2F")
.def_readwrite("x", &vec2_wrapper<float>::x)
.def_readwrite("y", &vec2_wrapper<float>::y)
.def("__len__", &vec2_wrapper<float>::length)
.def("len", &vec2_wrapper<float>::length)
;
bp::class_ < vec3_wrapper<float> >("Vec3F")
.def_readwrite("x", &vec3_wrapper<float>::x)
.def_readwrite("y", &vec3_wrapper<float>::y)
.def_readwrite("z", &vec3_wrapper<float>::z)
.def("__len__", &vec3_wrapper<float>::length)
.def("len", &vec3_wrapper<float>::length)
;
}
Python test:
import naga as vec
v = vec.Vec3F()
v.x = 1.0
v.y = 1.0
v.z = 1.0
print "len(v):", len(v)
print "v.len():", v.len()
Output:
len(v): 1
v.len(): 1.73205077648
Upvotes: 0