2012-01-16

Passing a user defined python object to C++ code(3)

This time I will explain how to access to the self.vertex_list of TriMesh. This is a list of length three numpy.array. We have already seen how to get the python list (dict's keylist) in my former article http://shitohichiumaya.blogspot.com/2010/08/boostpython-how-to-pass-python-object.html.

void print_float32_3(boost::python::object const & float32_3_obj)
{
// check sequence length is 3 or not.
if(boost::python::len(float32_3_obj) != 3){
std::string const objstr =
boost::python::extract< std::string >(
boost::python::str(float32_3_obj));
std::cerr << "print_float32_3: arg is not a float[3] obj ["
<< objstr << "]" << std::endl;
return;
}

float vec[] = {0.0f, 0.0f, 0.0f};
for(int i = 0; i < 3; ++i){
vec[i] = boost::python::extract< float >(
float32_3_obj.attr("__getitem__")(i));
}
std::cout << "float[3] = " << vec[0] << " " << vec[1] << " "
<< vec[2] << std::endl;
}

First, numpy.array is a sequence, therefore, we can ask length of it by boost::python::len(). We check the length is 3 or not since I defined it is three dimensional vector in the python code. Then we can access to each element through the attribute __getitem__. The python code puts float values to numpy.array, thus we can extract float value with extract< float >. Strictly speaking, numpy.array contains numpy.float64 instead of float, but, extract< float > still works here.

The last member of TriMesh, the triangle face index, should be done in the same way. Actually I would like to say that, but, there is a glitch here in numpy. We can not access this elements in the same way. We will get an errer:
TypeError: No registered converter was able to produce a C++ rvalue of type int from this Python object of type numpy.int64().