object GetLinkVelocity(object pylink)
 {
     CHECK_POINTER(pylink);
     Vector linearvel, angularvel;
     if( !_pPhysicsEngine->GetLinkVelocity(openravepy::GetKinBodyLink(pylink),linearvel,angularvel) ) {
         return object();
     }
     return boost::python::make_tuple(toPyVector3(linearvel),toPyVector3(angularvel));
 }
 object GetLinkForceTorque(object pylink)
 {
     CHECK_POINTER(pylink);
     Vector force, torque;
     if( !_pPhysicsEngine->GetLinkForceTorque(openravepy::GetKinBodyLink(pylink),force,torque) ) {
         return object();
     }
     return boost::python::make_tuple(toPyVector3(force),toPyVector3(torque));
 }
 static bool _ViewerCallback(object fncallback, PyEnvironmentBasePtr pyenv, KinBody::LinkPtr plink,RaveVector<float> position,RaveVector<float> direction)
 {
     object res;
     PyGILState_STATE gstate = PyGILState_Ensure();
     try {
         res = fncallback(openravepy::toPyKinBodyLink(plink,pyenv),toPyVector3(position),toPyVector3(direction));
     }
     catch(...) {
         RAVELOG_ERROR("exception occured in python viewer callback:\n");
         PyErr_Print();
     }
     PyGILState_Release(gstate);
     extract<bool> xb(res);
     if( xb.check() ) {
         return (bool)xb;
     }
     extract<int> xi(res);
     if( xi.check() ) {
         return (int)xi;
     }
     extract<double> xd(res);
     if( xd.check() ) {
         return (double)xd>0;
     }
     return true;
 }
 object GetGravity() {
     return toPyVector3(_pPhysicsEngine->GetGravity());
 }