C++ cook,Python assist,how to use Python-Ogre

devilatmay

30-07-2011 08:41:07

hi,everyone here,
Now I have a project based on Ogre(c++),and I want to add some scripting feature with python to it.When I found boost-python,I'm happy because it's quite easy.
and I installed Python-Ogre,too
this is my c++code

......
Ogre::Vector3 v(1,1,1);
//this boost function is used to call python module method named " doWithVector3",and v is the method parameter,_module is a handle for python object
boost::python::call_method<void>(_module.get(),"doWithVector3",boost::ref(v));
......

python code here

import import ogre.renderer.OGRE as Ogre
def doWithVector3(v):
v=v+Ogre.Vector3(1,2,3)

But,I got a python error "No Python class registered for C++ class class Ogre::Vector3"
I'm confused that what Python-Ogre do isn't expose Ogre classes to python? And HOW can I do with that error?
Need I try to use boost-pythn or py++ to expose all Ogre classes and methods to python by myself?
Can someone help me ,Much appreciate for that!

dermont

30-07-2011 14:00:34

Do you have a simple self-contained example of your problem, something along the lines of:

main.cpp

#include "Ogre.h"
#include <boost/python.hpp>
#include "Python.h"
#include <unistd.h>

using namespace boost::python;
namespace bp = boost::python;
using namespace Ogre;

BOOST_PYTHON_MODULE(PythonOgre)
{
}

int main()
{
bp::object main_module;
bp::object main_namespace;

PyImport_AppendInittab( "PythonOgre", &initPythonOgre);
Py_Initialize();

// main module and dictionary
main_module = bp::extract<bp::object>( PyImport_AddModule("__main__") );
main_namespace = main_module.attr("__dict__");

// load some default modules
main_namespace["os"]=bp::import("os");
main_namespace["sys"]=bp::import("sys");
main_namespace["math"]=bp::import("math");

main_namespace["pythonogre"] =
bp::object((bp::handle<>(PyImport_ImportModule("PythonOgre"))));

bp::object result = boost::python::exec_file("test.py", main_namespace, main_namespace);

Ogre::Vector3 v = Ogre::Vector3(1,1,1);
bp::object testVec = main_namespace["TESTVEC"]();
boost::python::call_method<void>(testVec.ptr(),"doWithVector3",boost::ref(v));

std::cout << "Vector Test ("
<< v.x << "," << v.y << "," << v.z << ")" << std::endl;

Ogre::Vector3 v2;
v2 = boost::python::call_method<Ogre::Vector3>(testVec.ptr(),"doWithVector33",boost::ref(v));
std::cout << "Vector Test2 ("
<< v2.x << "," << v2.y << "," << v2.z << ")" << std::endl;

return 0;
}


test.py

import sys
sys.path.insert(0,'/media/sda8/Libraries/PYTHON/cmake_generate/packages_2.7')
import ogre.renderer.OGRE as ogre

class TESTVEC:
def __init__(self):
pass
def doWithVector3(self,v):
v=v+ogre.Vector3(1,2,3)
print v
def doWithVector33(self,v):
x=v+ogre.Vector3(1,2,3)
return x


Alternatively you could look at the generated code for the ogre module or if you are looking for something more lightweight, maybe this would help:
https://github.com/nikki93/ngf/blob/d4c ... Python.cpp

devilatmay

31-07-2011 09:19:35

Thanks for your reply
I tried your code and got same error as before
the content of your linker is good, it may work for my work~

dermont

03-08-2011 07:10:26

Thanks for your reply
I tried your code and got same error as before
the content of your linker is good, it may work for my work~


Sorry don't think that the linker command will resolve your problem, more likely a problem in the code that I posted. What platform are you running (Linux/Windows 32bit/64bit).


g++ -o test main.cpp `pkg-config --cflags --libs OGRE OIS` -I/usr/local/include/boost -I/usr/include/python2.7 -lpython2.7 /usr/local/lib/libboost_python.so -Wl,-rpath=/media/sda8/Libraries/OGRE/sdk/v1-7/lib


AFAIK the python-ogre "class" converters should be registered with boost when importing the module and retrieved using the RTTI typeinfo(??), meaning that you have to link your application with the same libs you used to build python-ogre. I could be wrong.



#include "Ogre.h"
#include <boost/python.hpp>
#include "Python.h"
#include <unistd.h>

#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <vector>
#include <algorithm>

#include <boost/python/object/class.hpp>
#include <boost/python/object/instance.hpp>
#include <boost/python/object/class_detail.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/converter/registry.hpp>
#include <boost/python/object/find_instance.hpp>
#include <boost/python/object/pickle_support.hpp>
#include <boost/python/detail/map_entry.hpp>
#include <boost/python/object.hpp>
#include <boost/python/object_protocol.hpp>
#include <boost/detail/binary_search.hpp>
#include <boost/python/self.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/str.hpp>
#include <boost/python/ssize_t.hpp>
#include <functional>
#include <vector>
#include <cstddef>
#include <new>
#include <structmember.h>

using namespace boost::python;
namespace bp = boost::python;
//using namespace Ogre;
#include <typeinfo>


namespace
{
// Find a registered class object corresponding to id. Return a
// null handle if no such class is registered.
inline type_handle query_class(type_info id)
{
converter::registration const* p = converter::registry::query(id);
return type_handle(
boost::python::borrowed(
boost::python::allow_null(p ? p->m_class_object : 0))
);
}

void check_class_exists(bp::type_info id)
{
type_handle qhandle(query_class(id));
if (qhandle.get() == 0)
std::cout << id.name() << " has not been created" << std::endl;
else
std::cout << id.name() << " already created" << std::endl;
}

// Find a registered class corresponding to id. If not found,
// throw an appropriate exception.
type_handle get_class(type_info id)
{
type_handle result(query_class(id));

if (result.get() == 0)
{
object report("extension class wrapper for base class ");
report = report + id.name() + " has not been created yet";
PyErr_SetObject(PyExc_RuntimeError, report.ptr());
throw_error_already_set();
}
return result;
}
}

BOOST_PYTHON_MODULE(PythonOgre)
{
}

int main()
{
bp::object main_module;
bp::object main_namespace;
PyImport_AppendInittab( "PythonOgre", &initPythonOgre);
Py_Initialize();

// main module and dictionary
main_module = bp::extract<bp::object>( PyImport_AddModule("__main__") );
main_namespace = main_module.attr("__dict__");

// load some default modules
main_namespace["os"]=bp::import("os");
main_namespace["sys"]=bp::import("sys");
main_namespace["math"]=bp::import("math");

main_namespace["pythonogre"] =
bp::object((bp::handle<>(PyImport_ImportModule("PythonOgre"))));

using namespace std;
Ogre::Vector2 vec1 = Ogre::Vector2(1,1);
Ogre::Vector3 vec2 = Ogre::Vector3(1,1,1);
Ogre::Vector4 vec3 = Ogre::Vector4(1,1,1,1);

cout << "vec1 is: " << typeid(vec1).name() << endl;
cout << "vec2 is: " << typeid(vec2).name() << endl;
cout << "vec3 is: " << typeid(vec3).name() << endl;

cout << "XXXXXXXXX vec1 is: " << bp::type_info(typeid(vec1)).name() << endl;
cout << "XXXXXXXXX vec2 is: " << bp::type_info(typeid(vec2)).name() << endl;
cout << "XXXXXXXXX vec3 is: " << bp::type_info(typeid(vec3)).name() << endl;

check_class_exists(bp::type_info(typeid(vec1)));
check_class_exists(bp::type_info(typeid(vec2)));
check_class_exists(bp::type_info(typeid(vec3)));

bp::object result = boost::python::exec_file("test.py", main_namespace, main_namespace);

check_class_exists(bp::type_info(typeid(vec1)));
check_class_exists(bp::type_info(typeid(vec2)));
check_class_exists(bp::type_info(typeid(vec3)));
...

devilatmay

03-08-2011 16:32:35

Thanks for your reply
I tried your code and got same error as before
the content of your linker is good, it may work for my work~


Sorry don't think that the linker command will resolve your problem, more likely a problem in the code that I posted. What platform are you running (Linux/Windows 32bit/64bit).

Thanks for your reply and your code! :D
I need say sorry for my ENGLISH..it's not my First language.In fact,What I mean "linker" in my last post is the hyperlink you posted.
The code about python binding of NGF already helped me.I choosed it and built a light-weight system for scripting.As what I need is doing something just with Vector3 or etc, it is enough.
Anyway,thanks NGF,and thank u again!

dermont

03-08-2011 17:40:13


Thanks for your reply and your code! :D
I need say sorry for my ENGLISH..it's not my First language.In fact,What I mean "linker" in my last post is the hyperlink you posted.

:oops: Sorry, my bad. Anyway glad you found what you were looking for.