Unverified Commit 543b7b45 authored by Justin Carpentier's avatar Justin Carpentier Committed by GitHub
Browse files

Merge pull request #1084 from jmirabel/devel

[Python] Remove duplication with hpp-fcl.
parents 561dc5db 2379f42f
......@@ -22,7 +22,7 @@ jobs:
sudo rm -rf /usr/local/share/boost/1.69.0
export APT_DEPENDENCIES="doxygen libboost-system-dev libboost-test-dev libboost-filesystem-dev libboost-program-options-dev libeigen3-dev liburdfdom-dev texlive-font-utils"
export APT_DEPENDENCIES=$APT_DEPENDENCIES" libboost-python-dev robotpkg-py27-eigenpy python2.7-dev python-numpy"
export APT_DEPENDENCIES=$APT_DEPENDENCIES" robotpkg-hpp-fcl"
export APT_DEPENDENCIES=$APT_DEPENDENCIES" robotpkg-py27-hpp-fcl robotpkg-hpp-fcl"
sudo apt-get update -qq
sudo apt-get install -qq curl cppcheck ${APT_DEPENDENCIES}
- name: Run cmake
......@@ -30,6 +30,7 @@ jobs:
git submodule update --init
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/openrobots/lib/pkgconfig
export PATH=$PATH:/opt/openrobots/bin
export PYTHONPATH=${PYTHONPATH}:/opt/openrobots/lib/python2.7/site-packages
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/openrobots/lib:/usr/local/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
export MAKEFLAGS="-j2"
mkdir build
......
......@@ -31,21 +31,19 @@ jobs:
env:
- BUILD_WITH_COLLISION_SUPPORT=OFF
- TRAVIS_PYTHON_VERSION=27
python: 2.7
- dist: trusty
env:
- BUILD_WITH_COLLISION_SUPPORT=ON
- TRAVIS_PYTHON_VERSION=27
- TRAVIS_PYTHON_VERSION_WITH_DOT=2.7
python: 2.7
- dist: xenial
env:
- BUILD_WITH_COLLISION_SUPPORT=ON
- TRAVIS_PYTHON_VERSION=27
- TRAVIS_PYTHON_VERSION_WITH_DOT=2.7
python: 2.7
- dist: xenial
env:
- BUILD_WITH_COLLISION_SUPPORT=ON
- TRAVIS_PYTHON_VERSION=35
- TRAVIS_PYTHON_VERSION_WITH_DOT=3.5
python: 3.5
before_install: ./travis_custom/custom_before_install
......
......@@ -100,12 +100,6 @@ IF(BUILD_WITH_URDF_SUPPORT)
LIST(APPEND CFLAGS_DEPENDENCIES "-DPINOCCHIO_WITH_URDFDOM")
ENDIF(BUILD_WITH_URDF_SUPPORT)
IF(BUILD_WITH_HPP_FCL_SUPPORT)
ADD_DEFINITIONS(-DPINOCCHIO_WITH_HPP_FCL)
LIST(APPEND CFLAGS_DEPENDENCIES "-DPINOCCHIO_WITH_HPP_FCL")
ADD_REQUIRED_DEPENDENCY("hpp-fcl >= 1.0.0")
ENDIF(BUILD_WITH_HPP_FCL_SUPPORT)
IF(BUILD_WITH_AUTODIFF_SUPPORT)
ADD_REQUIRED_DEPENDENCY("cppad >= 20180000.0")
ENDIF(BUILD_WITH_AUTODIFF_SUPPORT)
......@@ -165,6 +159,27 @@ IF(BUILD_PYTHON_INTERFACE)
FINDPYTHON()
ENDIF(BUILD_PYTHON_INTERFACE)
IF(BUILD_WITH_HPP_FCL_SUPPORT)
ADD_DEFINITIONS(-DPINOCCHIO_WITH_HPP_FCL)
LIST(APPEND CFLAGS_DEPENDENCIES "-DPINOCCHIO_WITH_HPP_FCL")
ADD_REQUIRED_DEPENDENCY("hpp-fcl >= 1.3.0")
# Check whether hpp-fcl python bindings are available.
SET(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS FALSE)
IF(BUILD_PYTHON_INTERFACE)
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -c "import hppfcl"
RESULT_VARIABLE _hpp_fcl_python_bindings_not_found
OUTPUT_QUIET
ERROR_QUIET)
IF(_hpp_fcl_python_bindings_not_found EQUAL 0)
SET(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS TRUE)
MESSAGE(STATUS "Found hpp-fcl python bindings.")
ELSE()
MESSAGE(STATUS "Did not find hpp-fcl python bindings.")
ENDIF()
UNSET(_hpp_fcl_python_bindings_not_found)
ENDIF(BUILD_PYTHON_INTERFACE)
ENDIF(BUILD_WITH_HPP_FCL_SUPPORT)
SET(BOOST_COMPONENTS ${BOOST_REQUIRED_COMPONENTS} ${BOOST_OPTIONAL_COMPONENTS} ${BOOST_BUILD_COMPONENTS})
SEARCH_FOR_BOOST()
# Enforce the preprocessed version of boost::list and boost::vector
......
......@@ -77,20 +77,15 @@ REMOVE_PATH_FROM_LIST("${${PROJECT_NAME}_PYTHON_HEADERS}" "${CMAKE_CURRENT_SOURC
REMOVE_PATH_FROM_LIST("${${PROJECT_NAME}_PYTHON_SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/" ${PROJECT_NAME}_PYTHON_SOURCES)
# Python exposition of FCL
IF(NOT BUILD_WITH_HPP_FCL_SUPPORT)
IF(NOT BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
LIST(REMOVE_ITEM ${PROJECT_NAME}_PYTHON_HEADERS
multibody/fcl/contact.hpp
multibody/fcl/collision-result.hpp
multibody/fcl/distance-result.hpp
multibody/fcl/collision-geometry.hpp
multibody/fcl/mesh-loader.hpp
multibody/fcl/transform.hpp
)
LIST(REMOVE_ITEM ${PROJECT_NAME}_PYTHON_SOURCES
multibody/fcl/expose-fcl.cpp
)
ENDIF(NOT BUILD_WITH_HPP_FCL_SUPPORT)
ENDIF(NOT BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
LIST(APPEND HEADERS ${${PROJECT_NAME}_PYTHON_HEADERS})
......@@ -99,9 +94,9 @@ MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python"
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/spatial")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/multibody")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/multibody/joint")
IF(BUILD_WITH_HPP_FCL_SUPPORT)
IF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/multibody/fcl")
ENDIF(BUILD_WITH_HPP_FCL_SUPPORT)
ENDIF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/parsers")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/serialization")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/algorithm")
......@@ -134,6 +129,9 @@ IF(BUILD_PYTHON_INTERFACE)
IF(HPP_FCL_FOUND)
PKG_CONFIG_USE_DEPENDENCY(${PYWRAP} hpp-fcl)
ENDIF(HPP_FCL_FOUND)
IF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
TARGET_COMPILE_DEFINITIONS(${PYWRAP} PRIVATE -DPINOCCHIO_WITH_HPP_FCL_PYTHON_BINDINGS)
ENDIF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
IF(CPPAD_FOUND)
PKG_CONFIG_USE_DEPENDENCY(${PYWRAP} "cppad")
......
......@@ -38,9 +38,9 @@ namespace pinocchio
// Expose algorithms
void exposeAlgorithms();
#ifdef PINOCCHIO_WITH_HPP_FCL
#ifdef PINOCCHIO_WITH_HPP_FCL_PYTHON_BINDINGS
void exposeFCL();
#endif // PINOCCHIO_WITH_HPP_FCL
#endif // PINOCCHIO_WITH_HPP_FCL_PYTHON_BINDINGS
} // namespace python
} // namespace pinocchio
......
......@@ -77,9 +77,9 @@ BOOST_PYTHON_MODULE(libpinocchio_pywrap)
exposeAlgorithms();
exposeParsers();
#ifdef PINOCCHIO_WITH_HPP_FCL
#ifdef PINOCCHIO_WITH_HPP_FCL_PYTHON_BINDINGS
exposeFCL();
#endif // PINOCCHIO_WITH_HPP_FCL
#endif // PINOCCHIO_WITH_HPP_FCL_PYTHON_BINDINGS
exposeVersion();
exposeDependencies();
......
//
// Copyright (c) 2017-2019 CNRS INRIA
//
#ifndef __pinocchio_python_fcl_collision_geometry_hpp__
#define __pinocchio_python_fcl_collision_geometry_hpp__
#include "pinocchio/spatial/fcl-pinocchio-conversions.hpp"
#include <hpp/fcl/collision_object.h>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <eigenpy/registration.hpp>
namespace pinocchio
{
namespace python
{
namespace fcl
{
namespace bp = boost::python;
struct CollisionGeometryPythonVisitor : public bp::def_visitor<CollisionGeometryPythonVisitor>
{
typedef ::hpp::fcl::CollisionGeometry CollisionGeometry;
template<class PyClass>
void visit(PyClass& cl) const
{
cl
.def("getObjectType",&CollisionGeometry::getObjectType,"Get the type of the object.")
.def("getNodeType",&CollisionGeometry::getNodeType,"Get the node type.")
.def("computeLocalAABB",&CollisionGeometry::computeLocalAABB)
.def_readwrite("aabb_radius",&CollisionGeometry::aabb_radius,"AABB radius")
;
}
static void expose()
{
bp::class_<CollisionGeometry,boost::noncopyable>("CollisionGeometry",
"The geometry for the object for collision or distance computation.",
bp::no_init)
.def(CollisionGeometryPythonVisitor())
;
}
};
} // namespace fcl
} // namespace python
} // namespace pinocchio
#endif // namespace __pinocchio_python_fcl_collision_geometry_hpp__
//
// Copyright (c) 2017 CNRS
//
#ifndef __pinocchio_python_fcl_collision_result_hpp__
#define __pinocchio_python_fcl_collision_result_hpp__
#include "pinocchio/spatial/fcl-pinocchio-conversions.hpp"
#include <hpp/fcl/collision_data.h>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
namespace pinocchio
{
namespace python
{
namespace fcl
{
namespace bp = boost::python;
struct CollisionResultPythonVisitor : public bp::def_visitor<CollisionResultPythonVisitor>
{
typedef ::hpp::fcl::CollisionResult CollisionResult;
template<class PyClass>
void visit(PyClass& cl) const
{
cl
.def(bp::init<>("Default constructor"))
.def("addContact",&CollisionResult::addContact,bp::arg("contact"),"Adds one contact into result structure")
.def("isCollision",&CollisionResult::isCollision,"Returns binary collision result")
.def("numContacts",&CollisionResult::numContacts,"Returns the number of contacts found")
.def("clear",&CollisionResult::clear,"Clears the results obtained")
.def("getContacts",&CollisionResult::getContacts,"Get all the contacts",bp::return_internal_reference<>())
.def("getContact",&CollisionResult::getContact,bp::arg("index"),"Get the i-th contact calculated",bp::return_value_policy<bp::copy_const_reference>())
.def_readwrite("distance_lower_bound",&CollisionResult::distance_lower_bound,"Lower bound on distance between objects if they are disjoint (computed only on request).")
;
}
static void expose()
{
bp::class_<CollisionResult>("CollisionResult",
"Contact information returned by collision.",
bp::no_init)
.def(CollisionResultPythonVisitor())
;
}
private:
};
} // namespace fcl
} // namespace python
} // namespace pinocchio
#endif // namespace __pinocchio_python_fcl_collision_result_hpp__
//
// Copyright (c) 2017 CNRS
//
#ifndef __pinocchio_python_fcl_contact_hpp__
#define __pinocchio_python_fcl_contact_hpp__
#include "pinocchio/spatial/fcl-pinocchio-conversions.hpp"
#include <hpp/fcl/collision_data.h>
#include <boost/python.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
namespace pinocchio
{
namespace python
{
namespace fcl
{
namespace bp = boost::python;
struct ContactPythonVisitor : public bp::def_visitor<ContactPythonVisitor>
{
typedef ::hpp::fcl::Contact Contact;
typedef ::hpp::fcl::CollisionGeometry CollisionGeometry;
template<class PyClass>
void visit(PyClass& cl) const
{
cl
.def(bp::init<>("Default constructor"))
// TODO: add a kind of bp::with_custodian_and_ward_postcall<0,1>() for managing arguments lifetime
.def("__init__",bp::make_constructor(&make_contact,
bp::default_call_policies(),
bp::args("o1","o2","b1","b2")),
"Constructor from two Collision Geometry objects")
.def_readwrite("b1", &Contact::b1, "Contact primitive in object 1.\n"
"if object 1 is mesh or point cloud, it is the triangle or point id\n"
"if object 1 is geometry shape, it is NONE (-1),\n"
"if object 1 is octree, it is the id of the cell.")
.def_readwrite("b2", &Contact::b2, "Contact primitive in object 2.\n"
"if object 2 is mesh or point cloud, it is the triangle or point id\n"
"if object 2 is geometry shape, it is NONE (-1),\n"
"if object 2 is octree, it is the id of the cell.")
.add_property("normal", &getNormal, &setNormal,
"Contact normal, pointing from o1 to o2.")
.add_property("pos", &getPos, &setPos,
"Contact position, in world space.")
.def_readwrite("penetration_depth",&Contact::penetration_depth,"Penetration depth.")
.add_property("o1",bp::make_function(&getObject1,bp::return_value_policy<bp::copy_const_reference>()),"Returns a copy of collision object 1")
.add_property("o2",bp::make_function(&getObject2,bp::return_value_policy<bp::copy_const_reference>()),"Returns a copy of collision object 2.")
;
}
static void expose()
{
bp::class_<Contact>("Contact",
"Contact information returned by collision.",
bp::no_init)
.def(ContactPythonVisitor())
;
}
private:
static Contact * make_contact(const CollisionGeometry & o1, const CollisionGeometry & o2, int b1, int b2)
{ return new Contact(&o1,&o2,b1,b2); }
static Eigen::Vector3d getNormal(const Contact & self)
{ return self.normal; }
static void setNormal(Contact & self, const Eigen::Vector3d & normal)
{ self.normal = normal; }
static Eigen::Vector3d getPos(const Contact & self)
{ return self.pos; }
static void setPos(Contact & self, const Eigen::Vector3d & pos)
{ self.pos = pos; }
static const CollisionGeometry & getObject1(const Contact & self)
{ return *self.o1; }
static const CollisionGeometry & getObject2(const Contact & self)
{ return *self.o2; }
};
} // namespace fcl
} // namespace python
} // namespace pinocchio
#endif // namespace __pinocchio_python_fcl_contact_hpp__
//
// Copyright (c) 2018 CNRS
//
#ifndef __pinocchio_python_fcl_distance_result_hpp__
#define __pinocchio_python_fcl_distance_result_hpp__
#include "pinocchio/spatial/fcl-pinocchio-conversions.hpp"
#include <hpp/fcl/collision_data.h>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
namespace pinocchio
{
namespace python
{
namespace fcl
{
namespace bp = boost::python;
struct DistanceResultPythonVisitor : public bp::def_visitor<DistanceResultPythonVisitor>
{
typedef ::hpp::fcl::DistanceResult DistanceResult;
template<class PyClass>
void visit(PyClass& cl) const
{
cl
.def(bp::init<>("Default constructor"))
.def_readonly("min_distance",&DistanceResult::min_distance,
"minimum distance between two objects.\n"
"If two objects are in collision, min_distance <= 0.")
.def("getNearestPoint1",getNearestPoint1,
"Returns the nearest point on collision object 1.")
.def("getNearestPoint2",getNearestPoint2,
"Returns the nearest point on collision object 2.")
;
}
static void expose()
{
bp::class_<DistanceResult>("DistanceResult",
"Contact information returned by collision.",
bp::no_init)
.def(DistanceResultPythonVisitor())
;
}
private:
static ::hpp::fcl::Vec3f getNearestPoint1(const DistanceResult & res) { return res.nearest_points[0]; }
static ::hpp::fcl::Vec3f getNearestPoint2(const DistanceResult & res) { return res.nearest_points[1]; }
};
} // namespace fcl
} // namespace python
} // namespace pinocchio
#endif // namespace __pinocchio_python_fcl_distance_result_hpp__
......@@ -3,11 +3,6 @@
//
#include "pinocchio/bindings/python/fwd.hpp"
#include "pinocchio/bindings/python/multibody/fcl/contact.hpp"
#include "pinocchio/bindings/python/multibody/fcl/collision-result.hpp"
#include "pinocchio/bindings/python/multibody/fcl/distance-result.hpp"
#include "pinocchio/bindings/python/multibody/fcl/collision-geometry.hpp"
#include "pinocchio/bindings/python/multibody/fcl/mesh-loader.hpp"
#include "pinocchio/bindings/python/multibody/fcl/transform.hpp"
#include "pinocchio/bindings/python/utils/std-vector.hpp"
......@@ -18,88 +13,8 @@ namespace pinocchio
{
void exposeFCL()
{
using namespace pinocchio::python::fcl;
namespace bp = boost::python;
if(!eigenpy::register_symbolic_link_to_registered_type< ::hpp::fcl::OBJECT_TYPE>())
{
bp::enum_< ::hpp::fcl::OBJECT_TYPE >("OBJECT_TYPE")
.value("OT_UNKNOWN",::hpp::fcl::OT_UNKNOWN)
.value("OT_BVH",::hpp::fcl::OT_BVH)
.value("OT_GEOM",::hpp::fcl::OT_GEOM)
.value("OT_OCTREE",::hpp::fcl::OT_OCTREE)
.value("OT_COUNT",::hpp::fcl::OT_COUNT)
;
}
if(!eigenpy::register_symbolic_link_to_registered_type< ::hpp::fcl::NODE_TYPE>())
{
bp::enum_< ::hpp::fcl::NODE_TYPE >("NODE_TYPE")
.value("BV_UNKNOWN",::hpp::fcl::BV_UNKNOWN)
.value("BV_AABB",::hpp::fcl::BV_AABB)
.value("BV_OBB",::hpp::fcl::BV_OBB)
.value("BV_RSS",::hpp::fcl::BV_RSS)
.value("BV_kIOS",::hpp::fcl::BV_kIOS)
.value("BV_OBBRSS",::hpp::fcl::BV_OBBRSS)
.value("BV_KDOP16",::hpp::fcl::BV_KDOP16)
.value("BV_KDOP18",::hpp::fcl::BV_KDOP18)
.value("BV_KDOP24",::hpp::fcl::BV_KDOP24)
.value("GEOM_BOX",::hpp::fcl::GEOM_BOX)
.value("GEOM_SPHERE",::hpp::fcl::GEOM_SPHERE)
.value("GEOM_CAPSULE",::hpp::fcl::GEOM_CAPSULE)
.value("GEOM_CONE",::hpp::fcl::GEOM_CONE)
.value("GEOM_CYLINDER",::hpp::fcl::GEOM_CYLINDER)
.value("GEOM_CONVEX",::hpp::fcl::GEOM_CONVEX)
.value("GEOM_PLANE",::hpp::fcl::GEOM_PLANE)
.value("GEOM_HALFSPACE",::hpp::fcl::GEOM_HALFSPACE)
.value("GEOM_TRIANGLE",::hpp::fcl::GEOM_TRIANGLE)
.value("GEOM_OCTREE",::hpp::fcl::GEOM_OCTREE)
.value("NODE_COUNT",::hpp::fcl::NODE_COUNT)
;
}
if(!eigenpy::register_symbolic_link_to_registered_type< ::hpp::fcl::Contact>())
{
ContactPythonVisitor::expose();
}
if(!eigenpy::register_symbolic_link_to_registered_type< std::vector< ::hpp::fcl::Contact> >())
{
StdVectorPythonVisitor<ContactPythonVisitor::Contact>::expose("StdVec_Contact");
}
if(!eigenpy::register_symbolic_link_to_registered_type< ::hpp::fcl::CollisionResult>())
{
CollisionResultPythonVisitor::expose();
}
if(!eigenpy::register_symbolic_link_to_registered_type< std::vector< ::hpp::fcl::CollisionResult> >())
{
StdVectorPythonVisitor<CollisionResultPythonVisitor::CollisionResult>::expose("StdVec_CollisionResult");
}
if(!eigenpy::register_symbolic_link_to_registered_type< ::hpp::fcl::DistanceResult>())
{
DistanceResultPythonVisitor::expose();
}
if(!eigenpy::register_symbolic_link_to_registered_type< std::vector< ::hpp::fcl::DistanceResult> >())
{
StdVectorPythonVisitor<DistanceResultPythonVisitor::DistanceResult>::expose("StdVec_DistanceResult");
}
if(!eigenpy::register_symbolic_link_to_registered_type< ::hpp::fcl::CollisionGeometry>())
{
CollisionGeometryPythonVisitor::expose();
}
typedef ::hpp::fcl::MeshLoader MeshLoader;
typedef ::hpp::fcl::CachedMeshLoader CachedMeshLoader;
if(!eigenpy::register_symbolic_link_to_registered_type<MeshLoader>())
MeshLoaderPythonVisitor<MeshLoader>::
expose("Class to create CollisionGeometry from mesh files.");
if(!eigenpy::register_symbolic_link_to_registered_type<CachedMeshLoader>())
MeshLoaderPythonVisitor<CachedMeshLoader>::
expose("Class to create CollisionGeometry from mesh files with cache mechanism.");
bp::import ("hppfcl");
typedef ::hpp::fcl::Transform3f Transform3f;
......
//
// Copyright (c) 2017-2020 CNRS INRIA
//
#ifndef __pinocchio_python_fcl_mesh_loader_hpp__
#define __pinocchio_python_fcl_mesh_loader_hpp__
#include "pinocchio/spatial/fcl-pinocchio-conversions.hpp"
#include <hpp/fcl/mesh_loader/loader.h>
#include <boost/python.hpp>
#include <boost/python/type_id.hpp>
namespace pinocchio
{
namespace python
{
namespace fcl
{
namespace bp = boost::python;
template<typename MeshLoader>
struct MeshLoaderPythonVisitor
: public bp::def_visitor< MeshLoaderPythonVisitor<MeshLoader> >
{
typedef boost::shared_ptr<MeshLoader> MeshLoaderPtr_t;
template <typename T>
static boost::shared_ptr<T> create()
{
return boost::shared_ptr<T>(new T);
}
template<class PyClass>
void visit(PyClass& cl) const
{
cl
.def(bp::init<>(bp::arg("self"),"Default constructor"))
.def("create",&MeshLoaderPythonVisitor::create<MeshLoader>,"Create a new object.")
.staticmethod("create")
;
}
static void expose(const std::string & doc = "")
{
static const bp::type_info info = bp::type_id<MeshLoader>();
static const std::string class_name = info.name();
static const std::string class_name_without_namespace = class_name.substr(class_name.find_last_of(':')+1);