Commit 8a19cd85 authored by Jan Möbius's avatar Jan Möbius

Python source



git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@1171 fdac6126-5c0c-442c-9429-916003d36597
parent 4613850d
#include "Python/Bindings.hh"
#include "Python/Vector.hh"
#include "Python/Mesh.hh"
#include "Python/Iterator.hh"
#include "Python/Circulator.hh"
#include "Python/PropertyManager.hh"
#include "Python/InputOutput.hh"
namespace OpenMesh {
namespace Python {
/**
* Expose mesh items to %Python.
*/
void expose_items() {
class_<ArrayItems::Vertex>("Vertex");
class_<ArrayItems::Halfedge>("Halfedge");
class_<ArrayItems::Edge>("Edge");
class_<ArrayItems::Face>("Face");
}
/**
* Expose item and property handles to %Python.
*/
void expose_handles() {
class_<BaseHandle>("BaseHandle", init<optional<int> >())
.def("idx", &BaseHandle::idx)
.def("is_valid", &BaseHandle::is_valid)
.def("reset", &BaseHandle::reset)
.def("invalidate", &BaseHandle::invalidate)
.def(self == self)
.def(self != self)
.def(self < self)
;
class_<VertexHandle, bases<BaseHandle> >("VertexHandle", init<optional<int> >());
class_<HalfedgeHandle, bases<BaseHandle> >("HalfedgeHandle", init<optional<int> >());
class_<EdgeHandle, bases<BaseHandle> >("EdgeHandle", init<optional<int> >());
class_<FaceHandle, bases<BaseHandle> >("FaceHandle", init<optional<int> >());
class_<BasePropHandleT<object>, bases<BaseHandle> >("BasePropHandle", init<optional<int> >());
class_<VPropHandleT<object>, bases<BasePropHandleT<object> > >("VPropHandle", init<optional<int> >())
.def(init<const BasePropHandleT<object>&>());
class_<HPropHandleT<object>, bases<BasePropHandleT<object> > >("HPropHandle", init<optional<int> >())
.def(init<const BasePropHandleT<object>&>());
class_<EPropHandleT<object>, bases<BasePropHandleT<object> > >("EPropHandle", init<optional<int> >())
.def(init<const BasePropHandleT<object>&>());
class_<FPropHandleT<object>, bases<BasePropHandleT<object> > >("FPropHandle", init<optional<int> >())
.def(init<const BasePropHandleT<object>&>());
class_<MPropHandleT<object>, bases<BasePropHandleT<object> > >("MPropHandle", init<optional<int> >())
.def(init<const BasePropHandleT<object>&>());
}
/**
* Expose the StatusBits enum and StatusInfo class to %Python.
*/
void expose_status_bits_and_info() {
using OpenMesh::Attributes::StatusBits;
using OpenMesh::Attributes::StatusInfo;
enum_<StatusBits>("StatusBits")
.value("DELETED", OpenMesh::Attributes::DELETED)
.value("LOCKED", OpenMesh::Attributes::LOCKED)
.value("SELECTED", OpenMesh::Attributes::SELECTED)
.value("HIDDEN", OpenMesh::Attributes::HIDDEN)
.value("FEATURE", OpenMesh::Attributes::FEATURE)
.value("TAGGED", OpenMesh::Attributes::TAGGED)
.value("TAGGED2", OpenMesh::Attributes::TAGGED2)
.value("FIXEDNONMANIFOLD", OpenMesh::Attributes::FIXEDNONMANIFOLD)
.value("UNUSED", OpenMesh::Attributes::UNUSED)
;
class_<StatusInfo>("StatusInfo")
.def("deleted", &StatusInfo::deleted)
.def("set_deleted", &StatusInfo::set_deleted)
.def("locked", &StatusInfo::locked)
.def("set_locked", &StatusInfo::set_locked)
.def("selected", &StatusInfo::selected)
.def("set_selected", &StatusInfo::set_selected)
.def("hidden", &StatusInfo::hidden)
.def("set_hidden", &StatusInfo::set_hidden)
.def("feature", &StatusInfo::feature)
.def("set_feature", &StatusInfo::set_feature)
.def("tagged", &StatusInfo::tagged)
.def("set_tagged", &StatusInfo::set_tagged)
.def("tagged2", &StatusInfo::tagged2)
.def("set_tagged2", &StatusInfo::set_tagged2)
.def("fixed_nonmanifold", &StatusInfo::fixed_nonmanifold)
.def("set_fixed_nonmanifold", &StatusInfo::set_fixed_nonmanifold)
.def("bits", &StatusInfo::bits)
.def("set_bits", &StatusInfo::set_bits)
.def("is_bit_set", &StatusInfo::is_bit_set)
.def("set_bit", &StatusInfo::set_bit)
.def("unset_bit", &StatusInfo::unset_bit)
.def("change_bit", &StatusInfo::change_bit)
;
}
BOOST_PYTHON_MODULE(openmesh) {
expose_items();
expose_handles();
expose_status_bits_and_info();
expose_vec<float, 2>("Vec2f");
expose_vec<float, 3>("Vec3f");
expose_vec<float, 4>("Vec4f");
expose_vec<double, 2>("Vec2d");
expose_vec<double, 3>("Vec3d");
expose_vec<double, 4>("Vec4d");
expose_mesh<PolyMesh>("PolyMesh");
expose_mesh<TriMesh>("TriMesh");
expose_iterator<OpenMesh::PolyConnectivity::VertexIter, &OpenMesh::ArrayKernel::n_vertices>("VertexIter");
expose_iterator<OpenMesh::PolyConnectivity::HalfedgeIter, &OpenMesh::ArrayKernel::n_halfedges>("HalfedgeIter");
expose_iterator<OpenMesh::PolyConnectivity::EdgeIter, &OpenMesh::ArrayKernel::n_edges>("EdgeIter");
expose_iterator<OpenMesh::PolyConnectivity::FaceIter, &OpenMesh::ArrayKernel::n_faces>("FaceIter");
expose_circulator<OpenMesh::PolyConnectivity::VertexVertexIter, VertexHandle>("VertexVertexIter");
expose_circulator<OpenMesh::PolyConnectivity::VertexIHalfedgeIter, VertexHandle>("VertexIHalfedgeIter");
expose_circulator<OpenMesh::PolyConnectivity::VertexOHalfedgeIter, VertexHandle>("VertexOHalfedgeIter");
expose_circulator<OpenMesh::PolyConnectivity::VertexEdgeIter, VertexHandle>("VertexEdgeIter");
expose_circulator<OpenMesh::PolyConnectivity::VertexFaceIter, VertexHandle>("VertexFaceIter");
expose_circulator<OpenMesh::PolyConnectivity::FaceVertexIter, FaceHandle>("FaceVertexIter");
expose_circulator<OpenMesh::PolyConnectivity::FaceHalfedgeIter, FaceHandle>("FaceHalfedgeIter");
expose_circulator<OpenMesh::PolyConnectivity::FaceEdgeIter, FaceHandle>("FaceEdgeIter");
expose_circulator<OpenMesh::PolyConnectivity::FaceFaceIter, FaceHandle>("FaceFaceIter");
expose_circulator<OpenMesh::PolyConnectivity::HalfedgeLoopIter, HalfedgeHandle>("HalfedgeLoopIter");
typedef IteratorWrapperT<PolyConnectivity::VertexIter, &ArrayKernel::n_vertices> VertexIterWrapper;
typedef IteratorWrapperT<PolyConnectivity::HalfedgeIter, &ArrayKernel::n_halfedges> HalfedgeIterWrapper;
typedef IteratorWrapperT<PolyConnectivity::EdgeIter, &ArrayKernel::n_edges> EdgeIterWrapper;
typedef IteratorWrapperT<PolyConnectivity::FaceIter, &ArrayKernel::n_faces> FaceIterWrapper;
expose_property_manager<VPropHandleT<object>, VertexHandle, VertexIterWrapper>("VPropertyManager");
expose_property_manager<HPropHandleT<object>, HalfedgeHandle, HalfedgeIterWrapper>("HPropertyManager");
expose_property_manager<EPropHandleT<object>, EdgeHandle, EdgeIterWrapper>("EPropertyManager");
expose_property_manager<FPropHandleT<object>, FaceHandle, FaceIterWrapper>("FPropertyManager");
expose_io();
}
} // namespace Python
} // namespace OpenMesh
/** @file */
#ifndef OPENMESH_PYTHON_BINDINGS_HH
#define OPENMESH_PYTHON_BINDINGS_HH
#include <boost/python.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/copy_const_reference.hpp>
#include "OpenMesh/Core/IO/MeshIO.hh"
#include "OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh"
#include "OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh"
using namespace boost::python;
namespace OpenMesh {
/**
* This namespace contains classes and functions that are used to expose
* %OpenMesh to %Python.
*/
namespace Python {
/**
* Return value policy for functions that return references to objects that are
* managed by %OpenMesh.
*/
#define OPENMESH_PYTHON_DEFAULT_POLICY return_value_policy<copy_const_reference>()
struct MeshTraits : public OpenMesh::DefaultTraits {
/** Use double precision points */
typedef OpenMesh::Vec3d Point;
/** Use double precision normals */
typedef OpenMesh::Vec3d Normal;
/** Use RGBA colors */
typedef OpenMesh::Vec4f Color;
};
typedef OpenMesh::TriMesh_ArrayKernelT<MeshTraits> TriMesh;
typedef OpenMesh::PolyMesh_ArrayKernelT<MeshTraits> PolyMesh;
} // namespace OpenMesh
} // namespace Python
#endif
IF(NOT DEFINED OPENMESH_BUILD_PYTHON_BINDINGS)
SET(OPENMESH_BUILD_PYTHON_BINDINGS TRUE CACHE BOOL "Enable or disable building the Python Bindings.")
ENDIF()
IF(NOT DEFINED OPENMESH_BUILD_PYTHON_UNIT_TESTS)
SET(OPENMESH_BUILD_PYTHON_UNIT_TESTS FALSE CACHE BOOL "Enable or disable building the Python unit tests.")
ENDIF()
IF(NOT DEFINED OPENMESH_PYTHON_VERSION)
SET(OPENMESH_PYTHON_VERSION "2.7" CACHE STRING "Choose the Python version that is used to build the Python Bindings.")
ENDIF()
IF(OPENMESH_BUILD_PYTHON_BINDINGS)
# Look for the python libs
MESSAGE(STATUS "Looking for Python")
FIND_PACKAGE(PythonLibs ${OPENMESH_PYTHON_VERSION} QUIET)
IF(PYTHONLIBS_FOUND)
MESSAGE(STATUS "Looking for Python -- found")
# Determine the name of the python component
STRING(REGEX MATCH "^[0-9]+\\.[0-9]+" PYTHON_VERSION ${PYTHONLIBS_VERSION_STRING})
STRING(REGEX REPLACE "\\." "" PYTHON_VERSION ${PYTHON_VERSION})
SET(BOOST_PYTHON_COMPONENT "python-py${PYTHON_VERSION}")
# Check known boost versions for the python component
SET(BOOST_KNOWN_VERSIONS
"1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54"
"1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
"1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1"
"1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42"
"1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37"
"1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0"
"1.34" "1.33.1" "1.33.0" "1.33"
)
MESSAGE(STATUS "Looking for Boost Python")
# Look for version specific python component
FOREACH(VERSION ${BOOST_KNOWN_VERSIONS})
IF(Boost_FOUND)
BREAK()
ENDIF()
FIND_PACKAGE(Boost ${VERSION} EXACT QUIET COMPONENTS ${BOOST_PYTHON_COMPONENT})
ENDFOREACH()
# Look for any other python component
FOREACH(VERSION ${BOOST_KNOWN_VERSIONS})
IF(Boost_FOUND)
BREAK()
ENDIF()
FIND_PACKAGE(Boost ${VERSION} EXACT QUIET COMPONENTS python)
ENDFOREACH()
IF(Boost_FOUND)
MESSAGE(STATUS "Looking for Boost Python -- found")
MESSAGE(STATUS "Checking the Boost Python configuration")
TRY_COMPILE(
COMPILE_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Example/
Example
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES:STRING=${PYTHON_INCLUDE_DIRS};${Boost_INCLUDE_DIRS}"
"-DLINK_LIBRARIES:STRING=${PYTHON_LIBRARIES};${Boost_LIBRARIES}"
)
IF(COMPILE_WORKS)
# Look for the python interpreter to check if the example works
FIND_PACKAGE(PythonInterp ${PYTHONLIBS_VERSION_STRING} QUIET)
IF(PYTHONINTERP_FOUND)
EXECUTE_PROCESS(
COMMAND ${PYTHON_EXECUTABLE} -c "from example import *; greet(); planet = World()"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RESULT_VARIABLE PYTHON_WORKS
OUTPUT_QUIET
ERROR_QUIET
)
IF(PYTHON_WORKS EQUAL 0)
### EVERYTHING WORKS ###
MESSAGE(STATUS "Checking the Boost Python configuration -- done")
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND ${Boost_VERSION} VERSION_LESS 105600)
MESSAGE("There are known issues with Clang and Boost Python 1.55 and below.")
MESSAGE("Please consider updating Boost Python.")
ENDIF()
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Build/python/)
FILE(GLOB SOURCES *.cc *hh)
ADD_LIBRARY(openmesh SHARED ${SOURCES})
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ../)
TARGET_LINK_LIBRARIES(
openmesh
OpenMeshCore
OpenMeshTools
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
)
SET_TARGET_PROPERTIES(
openmesh
PROPERTIES
PREFIX ""
DEBUG_POSTFIX ""
RELEASE_POSTFIX ""
)
IF(APPLE)
SET_TARGET_PROPERTIES(openmesh PROPERTIES SUFFIX ".so")
ENDIF()
IF(WIN32)
SET_TARGET_PROPERTIES(openmesh PROPERTIES SUFFIX ".pyd")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
SET(OUTPUTS openmesh.exp openmesh.lib openmesh.pyd)
FOREACH(FILE ${OUTPUTS})
ADD_CUSTOM_COMMAND(
TARGET openmesh POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${FILE}
${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
)
ENDFOREACH()
ENDIF()
IF(OPENMESH_BUILD_PYTHON_UNIT_TESTS)
SET(UNITTEST_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Python-Unittests/)
# Copy unit tests
FILE(GLOB UNITTESTS Unittests/*.py)
FOREACH(TEST ${UNITTESTS})
FILE(COPY ${TEST} DESTINATION ${UNITTEST_OUTPUT_DIRECTORY})
ENDFOREACH()
# Copy test files
FILE(GLOB TESTFILES ${PROJECT_SOURCE_DIR}/src/Unittests/TestFiles/*(.off|.obj|.mtl|.stl|.ply|.om))
FOREACH(FILE ${TESTFILES})
FILE(COPY ${FILE} DESTINATION ${UNITTEST_OUTPUT_DIRECTORY})
ENDFOREACH()
# Copy library
IF(WIN32)
FOREACH(FILE ${OUTPUTS})
ADD_CUSTOM_COMMAND(
TARGET openmesh POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${FILE}
${UNITTEST_OUTPUT_DIRECTORY}
)
ENDFOREACH()
ELSE()
ADD_CUSTOM_COMMAND(
TARGET openmesh POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_BINARY_DIR}/Build/python/openmesh.so
${UNITTEST_OUTPUT_DIRECTORY}
)
ENDIF()
ADD_TEST(
NAME Python_tests
WORKING_DIRECTORY ${UNITTEST_OUTPUT_DIRECTORY}
COMMAND ${PYTHON_EXECUTABLE} -m unittest discover --verbose
)
ENDIF()
ELSE()
MESSAGE("Checking the Boost Python configuration failed!")
MESSAGE("Reason: An error occurred while running a small Boost Python test project.")
MESSAGE("Make sure that your Python and Boost Python libraries match.")
MESSAGE("Skipping Python Bindings.")
ENDIF()
ELSE()
MESSAGE("Checking the Boost Python configuration failed!")
MESSAGE("Reason: Python Interpreter ${PYTHONLIBS_VERSION_STRING} not found.")
MESSAGE("Skipping Python Bindings.")
ENDIF()
ELSE()
MESSAGE("Checking the Boost Python configuration failed!")
MESSAGE("Reason: Building a small Boost Python test project failed.")
MESSAGE("Make sure that your Python and Boost Python libraries match.")
MESSAGE("Skipping Python Bindings.")
ENDIF()
ELSE()
MESSAGE("Boost Python not found! Skipping Python Bindings.")
ENDIF()
ELSE()
MESSAGE("Python not found! Skipping Python Bindings.")
ENDIF()
ENDIF()
#ifndef OPENMESH_PYTHON_CIRCULATOR_HH
#define OPENMESH_PYTHON_CIRCULATOR_HH
#include "Python/Bindings.hh"
namespace OpenMesh {
namespace Python {
/**
* Wrapper for circulators.
*
* This class template is used to wrap circulators for %Python. It implements
* %Python's iterator protocol (the magic methods \_\_iter\_\_ and
* \_\_next\_\_).
*
* @tparam Circulator A circulator type.
*/
template<class Circulator, class CenterEntityHandle>
class CirculatorWrapperT {
public:
/**
* Constructor
*
* @param _mesh The mesh that contains the items to iterate over.
* @param _center The handle to the center item.
*/
CirculatorWrapperT(PolyMesh& _mesh, CenterEntityHandle _center) :
circulator_(_mesh, _center) {
}
/**
* Constructor
*
* @param _mesh The mesh that contains the items to iterate over.
* @param _center The handle to the center item.
*/
CirculatorWrapperT(TriMesh& _mesh, CenterEntityHandle _center) :
circulator_(_mesh, _center) {
}
/**
* Implementation of %Python's \_\_iter\_\_ magic method.
*
* @return This circulator.
*/
CirculatorWrapperT iter() const {
return *this;
}
/**
* Implementation of %Python's \_\_next\_\_ magic method.
*
* @return The next item. Raises a %Python StopIteration exception if
* there are no more items.
*/
typename Circulator::value_type next() {
if (circulator_.is_valid()) {
typename Circulator::value_type res = *circulator_;
++circulator_;
return res;
}
else {
PyErr_SetString(PyExc_StopIteration, "No more data.");
boost::python::throw_error_already_set();
}
return typename Circulator::value_type();
}
private:
Circulator circulator_;
};
/**
* Expose a circulator type to %Python.
*
* @tparam Circulator A circulator type.
*
* @param _name The name of the circulator type to be exposed.
*
* @note Circulators are wrapped by CirculatorWrapperT before they are exposed
* to %Python, i.e. they are not exposed directly. This means that circulators
* that are passed from %Python to C++ are instances of CirculatorWrapperT.
*/
template<class Circulator, class CenterEntityHandle>
void expose_circulator(const char *_name) {
class_<CirculatorWrapperT<Circulator, CenterEntityHandle> >(_name, init<TriMesh&, CenterEntityHandle>())
.def(init<PolyMesh&, CenterEntityHandle>())
.def("__iter__", &CirculatorWrapperT<Circulator, CenterEntityHandle>::iter)
.def("__next__", &CirculatorWrapperT<Circulator, CenterEntityHandle>::next)
.def("next", &CirculatorWrapperT<Circulator, CenterEntityHandle>::next)
;
}
} // namespace OpenMesh
} // namespace Python
#endif
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(Example)
FILE(GLOB SOURCES *.cc *hh)
ADD_LIBRARY(example SHARED ${SOURCES})
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})
TARGET_LINK_LIBRARIES(example ${LINK_LIBRARIES})
SET_TARGET_PROPERTIES(
example
PROPERTIES
PREFIX ""
DEBUG_POSTFIX ""
RELEASE_POSTFIX ""
)
IF(APPLE)
SET_TARGET_PROPERTIES(example PROPERTIES SUFFIX ".so")
ENDIF()
IF(WIN32)
SET_TARGET_PROPERTIES(example PROPERTIES SUFFIX ".pyd")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
ENDIF()
#include <boost/python.hpp>
char const * greet() {
return "hello, world";
}
struct World {
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
BOOST_PYTHON_MODULE(example) {
using namespace boost::python;
def("greet", greet);
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
#ifndef OPENMESH_PYTHON_INPUTOUTPUT_HH
#define OPENMESH_PYTHON_INPUTOUTPUT_HH
#include "Python/Bindings.hh"
namespace OpenMesh {
namespace Python {
const IO::Options::Flag FLAG_DEFAULT = IO::Options::Default;
const IO::Options::Flag FLAG_BINARY = IO::Options::Binary;
const IO::Options::Flag FLAG_MSB = IO::Options::MSB;
const IO::Options::Flag FLAG_LSB = IO::Options::LSB;
const IO::Options::Flag FLAG_SWAP = IO::Options::Swap;
const IO::Options::Flag FLAG_VERTEXNORMAL = IO::Options::VertexNormal;
const IO::Options::Flag FLAG_VERTEXCOLOR = IO::Options::VertexColor;
const IO::Options::Flag FLAG_VERTEXTEXCOORD = IO::Options::VertexTexCoord;
const IO::Options::Flag FLAG_EDGECOLOR = IO::Options::EdgeColor;
const IO::Options::Flag FLAG_FACENORMAL = IO::Options::FaceNormal;
const IO::Options::Flag FLAG_FACECOLOR = IO::Options::FaceColor;
const IO::Options::Flag FLAG_FACETEXCOORD = IO::Options::FaceTexCoord;
const IO::Options::Flag FLAG_COLORALPHA = IO::Options::ColorAlpha;
const IO::Options::Flag FLAG_COLORFLOAT = IO::Options::ColorFloat;
BOOST_PYTHON_FUNCTION_OVERLOADS(read_mesh_overloads, IO::read_mesh, 3, 4)
BOOST_PYTHON_FUNCTION_OVERLOADS(write_mesh_overloads, IO::write_mesh, 2, 4)
/**
* Expose the input/output functions and options to Python.
*/
void expose_io() {
//======================================================================
// Functions
//======================================================================
bool (*read_mesh_poly )(PolyMesh&, const std::string& ) = &IO::read_mesh;
bool (*read_mesh_poly_options)(PolyMesh&, const std::string&, IO::Options&, bool) = &IO::read_mesh;
bool (*read_mesh_tri )(TriMesh&, const std::string& ) = &IO::read_mesh;
bool (*read_mesh_tri_options )(TriMesh&, const std::string&, IO::Options&, bool) = &IO::read_mesh;
bool (*write_mesh_poly)(const PolyMesh&, const std::string&, IO::Options, std::streamsize) = &IO::write_mesh;
bool (*write_mesh_tri )(const TriMesh&, const std::string&, IO::Options, std::streamsize) = &IO::write_mesh;
def("read_mesh", read_mesh_poly);
def("read_mesh", read_mesh_poly_options, read_mesh_overloads());
def("read_mesh", read_mesh_tri);
def("read_mesh", read_mesh_tri_options, read_mesh_overloads());
def("write_mesh", write_mesh_poly, write_mesh_overloads());
def("write_mesh", write_mesh_tri, write_mesh_overloads());
//======================================================================
// Options
//======================================================================
scope scope_options = class_<IO::Options>("Options")
.def(init<IO::Options::Flag>())
.def("cleanup", &IO::Options::cleanup)
.def("clear", &IO::Options::clear)
.def("is_empty", &IO::Options::is_empty)
.def("check", &IO::Options::check)
.def("is_binary", &IO::Options::is_binary)
.def("vertex_has_normal", &IO::Options::vertex_has_normal)
.def("vertex_has_color", &IO::Options::vertex_has_color)
.def("vertex_has_texcoord", &IO::Options::vertex_has_texcoord)
.def("edge_has_color", &IO::Options::edge_has_color)
.def("face_has_normal", &IO::Options::face_has_normal)
.def("face_has_color", &IO::Options::face_has_color)
.def("face_has_texcoord", &IO::Options::face_has_texcoord)
.def("color_has_alpha", &IO::Options::color_has_alpha)
.def("color_is_float", &IO::Options::color_is_float)
.def(self == self)
.def(self != self)
.def(self -= IO::Options::Flag())
.def(self += IO::Options::Flag())
.def_readonly("Default", &FLAG_DEFAULT)
.def_readonly("Binary", &FLAG_BINARY)
.def_readonly("MSB", &FLAG_MSB)
.def_readonly("LSB", &FLAG_LSB)
.def_readonly("Swap", &FLAG_SWAP)
.def_readonly("VertexNormal", &FLAG_VERTEXNORMAL)
.def_readonly("VertexColor", &FLAG_VERTEXCOLOR)
.def_readonly("VertexTexCoord", &FLAG_VERTEXTEXCOORD)
.def_readonly("EdgeColor", &FLAG_EDGECOLOR)
.def_readonly("FaceNormal", &FLAG_FACENORMAL)
.def_readonly("FaceColor", &FLAG_FACECOLOR)
.def_readonly("FaceTexCoord", &FLAG_FACETEXCOORD)
.def_readonly("ColorAlpha", &FLAG_COLORALPHA)
.def_readonly("ColorFloat", &FLAG_COLORFLOAT)
;
enum_<IO::Options::Flag>("Flag")
.value("Default", IO::Options::Default)
.value("Binary", IO::Options::Binary)
.value("MSB", IO::Options::MSB)
.value("LSB", IO::Options::LSB)
.value("Swap", IO::Options::Swap)
.value("VertexNormal", IO::Options::VertexNormal)
.value("VertexColor", IO::Options::VertexColor)
.value("VertexTexCoord", IO::Options::VertexTexCoord)
.value("EdgeColor", IO::Options::EdgeColor)
.value("FaceNormal", IO::Options::FaceNormal)
.value("FaceColor", IO::Options::FaceColor)
.value("FaceTexCoord", IO::Options::FaceTexCoord)
.value("ColorAlpha", IO::Options::ColorAlpha)
.value("ColorFloat", IO::Options::ColorFloat)
;
}
} // namespace OpenMesh
} // namespace Python
#endif
#ifndef OPENMESH_PYTHON_ITERATOR_HH
#define OPENMESH_PYTHON_ITERATOR_HH
#include "Python/Bindings.hh"
namespace OpenMesh {
namespace Python {
/**
* Wrapper for mesh item iterators.
*
* This class template is used to wrap mesh item iterators for %Python. It
* implements %Python's iterator protocol (the magic methods \_\_iter\_\_ and
* \_\_next\_\_).
*
* @tparam Iterator An iterator type.
* @tparam n_items A member function pointer that points to the mesh function
* that returns the number of items to iterate over (e.g. n_vertices).
*/
template<class Iterator, size_t (OpenMesh::ArrayKernel::*n_items)() const>
class IteratorWrapperT {
public:
/**
* Constructor
*
* @param _mesh The mesh that contains the items to iterate over.
* @param _hnd The handle of the first item to iterate over.
* @param _skip Specifies if deleted/hidden elements are skipped.
*/
IteratorWrapperT(const PolyMesh& _mesh, typename Iterator::value_type _hnd, bool _skip = false) :
mesh_(_mesh), n_items_(n_items),
iterator_(_mesh, _hnd, _skip),
iterator_end_(_mesh, typename Iterator::value_type(int((_mesh.*n_items)()))) {
}
/**
* Constructor
*
* @param _mesh The mesh that contains the items to iterate over.
* @param _hnd The handle of the first item to iterate over.
* @param _skip Specifies if deleted/hidden elements are skipped.
*/
IteratorWrapperT(const TriMesh& _mesh, typename Iterator::value_type _hnd, bool _skip = false) :
mesh_(_mesh), n_items_(n_items),
iterator_(_mesh, _hnd, _skip),
iterator_end_(_mesh, typename Iterator::value_type(int((_mesh.*n_items)()))) {
}
/**
* Implementation of %Python's \_\_iter\_\_ magic method.