2012-01-16

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


The python code of the last article contains a simple triangle mesh (TriMesh) and sets some data to the object. The mesh has only two triangles that forms a rectangle. It's not so exciting scene, but it is sufficient as an example. The scene is shown in the following image. A camera looks up the rectangle.

Figure 1. TriMesh scene example (one rectangle)

This article explains how to access to the three members of TriMesh. Each member of a python object is an attribute, there is a way to access to any attribute in general, but I think it is complicated. I assume the programmer has an knowledge about a specific python class. For example, I know TriMesh object has three member variables
(three attributes).

  • self.__material_name: a string, but this is a private member. We should access to this member via get_material_name() method.
  • self.vertex_list: A list of numpy.array, that contains length three numpy.float64.
  • self.face_idx_list: A list of numpy.array, that contains length three numpy.int64.
How to access self.__material_name.

A TriMesh object is passing as pytrimesh in the code.
std::string const matname =
   extract< std::string >(pytrimesh.attr("get_material_name")());
We know the name of the attribute. Therefore, we can use boost::python::object's method attr to get the method function, then call the operator() to get string object. Please note the () of the end of the line. It is not
pytrimesh.attr("get_material_name")
but, it is
pytrimesh.attr("get_material_name")().
The operator() of boost::python::object returns an boost::python::object, we need to use extract<>() to extract a std::string. This is actually relatively simple since the contents is a build-in object of python.

I would like to stress two points here.

  • If we access to non-existing attribute, an AttributeError exception is casted. The following is an example:
    boost::python::object const vlist = pytrimesh.attr("vertex_list_non_exist");
    
  •  We can not access to an private member variables (private attribute). Therefore, the following code fails.
     std::string const matname = extract< std::string >(pytrimesh.attr("__material_name"));
I will show how to pass a list of numpy.array to C++ code in the next article.

No comments: