Merge branch 'rm-python' into 'master'

remove the python bindings from this project

See merge request OpenMesh/OpenMesh!159
This commit is contained in:
Jan Möbius
2018-03-21 18:54:27 +01:00
48 changed files with 18 additions and 7844 deletions

View File

@@ -76,7 +76,7 @@ fi
cd build-release-$BUILDPATH-Vector-Checks
cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_BINDINGS=OFF $OPTIONS ../
cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON $OPTIONS ../
#build it
make $MAKE_OPTIONS
@@ -99,51 +99,6 @@ cd Unittests
cd ..
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Building Release version with vectorchecks disabled for python tests"
echo "======================================================================"
echo -e "${NC}"
if [ ! -d build-release-$BUILDPATH ]; then
mkdir build-release-$BUILDPATH
fi
cd build-release-$BUILDPATH
cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF $OPTIONS ../
#build it
make $MAKE_OPTIONS
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Running Python unittests Release version "
echo "======================================================================"
echo -e "${NC}"
if [ "$LANGUAGE" == "C++11" ] || [ "$COMPILER" == "gcc" ] ; then
# Execute Python unittests
cd Python-Unittests
python -m unittest discover -v
cd ..
else
echo -e "${WARNING}"
echo "WARNING! Python unittests disabled !!"
echo -e "${NC}"
fi
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
@@ -158,7 +113,7 @@ fi
cd build-debug-$BUILDPATH-Vector-Checks
cmake -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_BINDINGS=OFF $OPTIONS ../
cmake -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON $OPTIONS ../
#build it
make $MAKE_OPTIONS
@@ -181,42 +136,3 @@ cd Unittests
cd ..
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Building Debug version with vectorchecks disabled for python tests"
echo "======================================================================"
echo -e "${NC}"
if [ ! -d build-debug-$BUILDPATH ]; then
mkdir build-debug-$BUILDPATH
fi
cd build-debug-$BUILDPATH
cmake -DCMAKE_BUILD_TYPE=DEBUG -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF $OPTIONS ../
#build it
make $MAKE_OPTIONS
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Running Python unittests Debug version "
echo "======================================================================"
echo -e "${NC}"
if [ "$LANGUAGE" == "C++11" ] || [ "$COMPILER" == "gcc" ] ; then
# Execute Python unittests
cd Python-Unittests
python -m unittest discover -v
else
echo -e "${WARNING}"
echo "WARNING! Python unittests disabled !!"
echo -e "${NC}"
fi

View File

@@ -58,7 +58,7 @@ fi
cd build-release-$BUILDPATH-Vector-Checks
cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=OFF $OPTIONS ../
cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON $OPTIONS ../
#build it
make
@@ -81,53 +81,6 @@ cd Unittests
cd ..
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Building Release version with vectorchecks disabled for python tests"
echo "======================================================================"
echo -e "${NC}"
if [ ! -d build-release-$BUILDPATH ]; then
mkdir build-release-$BUILDPATH
fi
cd build-release-$BUILDPATH
cmake -DCMAKE_BUILD_TYPE=Release -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF -DCPACK_BINARY_DRAGNDROP=ON $OPTIONS ../
#build it
make
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Running Python unittests Release version "
echo "======================================================================"
echo -e "${NC}"
if [ "$LANGUAGE" == "C++11" ]; then
# Execute Python unittests
cd Python-Unittests
rm -f openmesh.so
cp ../Build/python/openmesh.so .
python -m unittest discover -v
cd ..
else
echo -e "${WARNING}"
echo "WARNING! Python unittests disabled for clang on Mac with c++98 !!"
echo -e "${NC}"
fi
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
@@ -142,7 +95,7 @@ fi
cd build-debug-$BUILDPATH-Vector-Checks
cmake -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=OFF $OPTIONS ../
cmake -DCMAKE_BUILD_TYPE=Debug -DOPENMESH_BUILD_UNIT_TESTS=TRUE -DSTL_VECTOR_CHECKS=ON $OPTIONS ../
#build it
make
@@ -166,52 +119,6 @@ cd Unittests
cd ..
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Building Debug version with vectorchecks disabled for python tests"
echo "======================================================================"
echo -e "${NC}"
if [ ! -d build-debug-$BUILDPATH ]; then
mkdir build-debug-$BUILDPATH
fi
cd build-debug-$BUILDPATH
cmake -DCMAKE_BUILD_TYPE=DEBUG -DOPENMESH_BUILD_PYTHON_UNIT_TESTS=ON -DBUILD_APPS=OFF $OPTIONS ../
#build it
make
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
echo "Running Python unittests Debug version "
echo "======================================================================"
echo -e "${NC}"
if [ "$LANGUAGE" == "C++11" ]; then
# Execute Python unittests
cd Python-Unittests
rm -f openmesh.so
cp ../Build/python/openmesh.so .
python -m unittest discover -v
cd ..
else
echo -e "${WARNING}"
echo "WARNING! Python unittests disabled for clang on Mac with c++98 !!"
echo -e "${NC}"
fi
cd ..
echo -e "${OUTPUT}"
echo ""
echo "======================================================================"
@@ -219,10 +126,15 @@ echo "Package creation (DMG and tarball)"
echo "======================================================================"
echo -e "${NC}"
if [ ! -d build-release-$BUILDPATH ]; then
mkdir build-release-$BUILDPATH
fi
cd build-release-$BUILDPATH
cp ../build-debug-$BUILDPATH/Build/lib/* ./Build/lib/
cmake .
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_APPS=OFF -DCPACK_BINARY_DRAGNDROP=ON $OPTIONS ../
#build it
make
make package

View File

@@ -129,12 +129,6 @@ endif()
add_subdirectory (Doc)
# ========================================================================
# Include Python interface
# ========================================================================
add_subdirectory (src/Python)
# ========================================================================
# Bundle generation (Targets exist, now configure them)
# ========================================================================

View File

@@ -1,158 +0,0 @@
##################################################
# Getting Started
##################################################
from openmesh import *
mesh = TriMesh()
##################################################
# Adding Items to a Mesh
##################################################
# add a a couple of vertices to the mesh
vh0 = mesh.add_vertex(TriMesh.Point(0, 1, 0))
vh1 = mesh.add_vertex(TriMesh.Point(1, 0, 0))
vh2 = mesh.add_vertex(TriMesh.Point(2, 1, 0))
vh3 = mesh.add_vertex(TriMesh.Point(0,-1, 0))
vh4 = mesh.add_vertex(TriMesh.Point(2,-1, 0))
# add a couple of faces to the mesh
fh0 = mesh.add_face(vh0, vh1, vh2)
fh1 = mesh.add_face(vh1, vh3, vh4)
fh2 = mesh.add_face(vh0, vh3, vh1)
# add another face to the mesh, this time using a list
vh_list = [vh2, vh1, vh4]
fh3 = mesh.add_face(vh_list)
# 0 ==== 2
# |\ 0 /|
# | \ / |
# |2 1 3|
# | / \ |
# |/ 1 \|
# 3 ==== 4
##################################################
# Iterators
##################################################
# iterate over all vertices
for vh in mesh.vertices():
print vh.idx()
# iterate over all halfedges
for heh in mesh.halfedges():
print heh.idx()
# iterate over all edges
for eh in mesh.edges():
print eh.idx()
# iterate over all faces
for fh in mesh.faces():
print fh.idx()
##################################################
# Circulators
##################################################
# iterate over all neighboring vertices
for vh in mesh.vv(vh1):
print vh.idx()
# iterate over all incoming halfedges
for heh in mesh.vih(vh1):
print heh.idx()
# iterate over all outgoing halfedges
for heh in mesh.voh(vh1):
print heh.idx()
# iterate over all adjacent edges
for eh in mesh.ve(vh1):
print eh.idx()
# iterate over all adjacent faces
for fh in mesh.vf(vh1):
print fh.idx()
# iterate over the face's vertices
for vh in mesh.fv(fh0):
print vh.idx()
# iterate over the face's halfedges
for heh in mesh.fh(fh0):
print heh.idx()
# iterate over the face's edges
for eh in mesh.fe(fh0):
print eh.idx()
# iterate over all edge-neighboring faces
for fh in mesh.ff(fh0):
print fh.idx()
##################################################
# Properties
##################################################
prop_handle = VPropHandle()
mesh.add_property(prop_handle, "cogs")
for vh in mesh.vertices():
cog = TriMesh.Point(0,0,0)
valence = 0
for neighbor in mesh.vv(vh):
cog += mesh.point(neighbor)
valence += 1
mesh.set_property(prop_handle, vh, cog / valence)
mesh.remove_property(prop_handle)
##################################################
# Property Managers
##################################################
prop_man = VPropertyManager(mesh, "cogs")
prop_man.set_range(mesh.vertices(), TriMesh.Point(0,0,0))
for vh in mesh.vertices():
valence = 0
for neighbor in mesh.vv(vh):
prop_man[vh] += mesh.point(neighbor)
valence += 1
prop_man[vh] /= valence
##################################################
# I/O
##################################################
mesh = TriMesh()
read_mesh(mesh, "bunny.obj")
# modify mesh ...
write_mesh(mesh, "bunny.obj")
mesh = TriMesh()
mesh.request_halfedge_normals()
mesh.request_vertex_normals()
options = Options()
options += Options.VertexNormal
result = read_mesh(mesh, "bunny.obj", options)
if result:
print "everything worked"
else:
print "something went wrong"

View File

@@ -11,6 +11,7 @@
<b>Breaking changes</b>
<ul>
<li>The minimal standard for C++ has been raised to C++11. Compilers not supporting C++11 or higher are no longer supported</li>
<li>Removed the python bindings from this project. They have migrated to a <a href="https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python">seperate project</a>.</li>
</ul>
<b>Core</b>

View File

@@ -87,14 +87,6 @@ repeatedly replacing each vertex' position by the center of gravity
<br /><br />
\section python_and_om OpenMesh Python interface
OpenMesh itself is written in C++. We also provide a python interface
to use OpenMesh. A detailed description of the interface can be found
in the following tutorial:
\li \subpage python_tutorial
<br /><br />
\subpage additional_information
\li \ref mesh_first_to_read

View File

@@ -1,288 +0,0 @@
/** \page python_tutorial Python Tutorial
This tutorial will introduce the basic concepts behind the %OpenMesh Python
Bindings. We will cover the following topics:
\li How to build the Python Bindings
\li How to create an empty mesh
\li How to add vertices and faces to a mesh
\li How to navigate on a mesh using iterators and circulators
\li How to add and remove custom properties
\li How to read and write meshes from files
In addition, we will briefly discuss some of the differences between the Python
Bindings and the original C++ implementation of %OpenMesh.
\section python_build Building the Python Bindings
The Python Bindings depend on the following libraries:
\li Python (2.7 or later)
\li Boost Python (1.54.0 or later)
\note Make sure that your Boost Python and Python versions match, i.e. that
Boost Python was linked against the correct Python version.
The Python Bindings are automatically built with %OpenMesh. The generated files are written to the
Build/python subdirectory of the build tree. For more information on how to build %OpenMesh see
\ref compiling.
If CMake does not find your Python installation (or finds the wrong one) you can
explicitly specify an installation by setting the following variables:
\verbatim
PYTHON_LIBRARY - Path to the python library
PYTHON_INCLUDE_DIR - Path to where Python.h is found
\endverbatim
Similarly, if CMake does not find your Boost Python installation, set the
following variables:
\verbatim
BOOST_ROOT - Preferred installation prefix
BOOST_INCLUDEDIR - Preferred include directory e.g. <prefix>/include
BOOST_LIBRARYDIR - Preferred library directory e.g. <prefix>/lib
\endverbatim
\section python_start Getting Started
To use the %OpenMesh Python Bindings we first need to import the openmesh module:
\dontinclude python_tutorial.py
\skipline from
The module provides two mesh classes: One for polygonal meshes (PolyMesh) and
one for triangle meshes (TriMesh). You should use triangle meshes whenever
possible, since they are usually more efficient. In addition, some algorithms
are only implemented for triangle meshes while triangle meshes inherit the full
functionality of polygonal meshes.
The following code creates a new triangle mesh:
\skipline mesh
\section python_add Adding Items to a Mesh
We can add a new vertex to the mesh by calling the add_vertex() member function.
This function gets a coordinate and returns a handle to the newly inserted
vertex.
\skipline vh0
\until vh4
To add a new face to the mesh we have to call add_face(). This function gets the
handles of the vertices that make up the new face and returns a handle to the
newly inserted face:
\skipline fh0
\until fh2
We can also use a Python list to add a face to the mesh:
\skipline vh_list
\until fh3
\section python_iterators Iterators and Circulators
Now that we have added a couple of vertices to the mesh, we can iterate over
them and print out their indices:
\skipline for
\until vh.idx()
We can also iterate over halfedges, edges and faces by calling mesh.halfedges(),
mesh.edges() and mesh.faces() respectively:
\skipline iterate
\until fh.idx()
To iterate over the items adjacent to another item we can use one of the
circulator functions. For example, to iterate over the vertices adjacent to
another vertex we can call mesh.vv() and pass the handle of the center vertex:
\skipline for
\until vh.idx()
We can also iterate over the adjacent halfedges, edges and faces:
\skipline iterate
\until fh.idx()
To iterate over the items adjacent to a face we can use the following functions:
\skipline iterate
\until fh.idx()
\section python_props Properties
%OpenMesh allows us to dynamically add custom properties to a mesh. We can add
properties to vertices, halfedges, edges, faces and the mesh itself. To
add a property to a mesh (and later access its value) we have to use a property
handle of the appropriate type:
\li VPropHandle (for vertex properties)
\li HPropHandle (for halfedge properties)
\li EPropHandle (for edge properties)
\li FPropHandle (for face properties)
\li MPropHandle (for mesh properties)
The following code shows how to add a vertex property to a mesh:
\skipline prop_handle
\until mesh
The second parameter of the function add_property() is optional. The parameter
is used to specify a name for the new property. This name can later be used
to retrieve a handle to the property using the get_property_handle() member
function.
Now that we have added a vertex property to the mesh we can set and get its
value. Here we will use the property to store the center of gravity of each
vertex' neighborhood:
\skipline for
\until mesh.set_property
Properties use Python's type system. This means that we can use the same
property to store values of different types (e.g. store both strings and
integers using the same vertex property). Properties are initialized to the
Python built-in constant None.
To remove a property we have to call remove_property() with the appropriate
property handle:
\skipline mesh.remove_property
\section python_propman Property Managers
Another way to add and remove a property is to use a property manager. A
Property manager encapsulates a property and manages its lifecycle. A Property
manager also provides a number of convenience functions to access the enclosed
property.
There are four different types of property managers. One for each type of mesh
item:
\li VPropertyManager (for vertex properties)
\li HPropertyManager (for halfedge properties)
\li EPropertyManager (for edge properties)
\li FPropertyManager (for face properties)
Property managers automatically add a new property to a mesh when they are
initialized. Thus the following code not only creates a new vertex property
manager, but also adds a new vertex property to the mesh:
\skipline prop_man
Property managers allow us to conveniently set the property value for an entire
range of mesh items:
\skipline prop_man
They also allow us to use the subscript operator to set and get property values.
Here we will once again use a property to store the center of gravity of each
vertex' neighborhood:
\skipline for
\until prop_man[vh] /= valence
Properties that are encapsulated by a property manager are automatically removed
from the mesh when the property manager goes out of scope (i.e. the property
manager is garbage collected).
\section python_io Read and write meshes from files
You can read and write meshes from files using the read_mesh() and write_mesh()
functions:
\skipline mesh
\until write_mesh(mesh, "bunny.obj")
The file type is automatically deduced from the file extension. %OpenMesh
currently supports four file types: .off, .obj, .stl and .om
The behaviour of the I/O functions can be controlled by passing an instance of
the Options class to either read_mesh() or write_mesh(). The class controls the
behaviour of the I/O functions by means of enabled/disabled bits in a bitset:
\skipline mesh
\until print "something went wrong"
Other available option bits include:
-# mode bits - control binary reading/writing
- Options.Binary
- Options.MSB
- Options.LSB
- Options.Swap (MSB|LSB)
-# property bits - controls which standard properties to read/write
- Options.VertexNormal
- Options.VertexTexCoord
- Options.VertexColor
- Options.FaceNormal
- Options.FaceColor
- Options.ColorAlpha
- Options.ColorFloat
\note You have to pass an instance of the Options class to the I/O functions,
i.e. you cannot directly pass one of the option bits. For example, directly
passing Options.Binary to either one of the functions will cause an error.
When reading a file the options are used as hints, i.e. depending on the format
we can help the reader to interpret the data correctly.
\note If you want to read a property from a file the property must have been
requested prior to reading the file.
When writing the mesh the mode bits control whether to use the binary variant of
the respective file format and the desired byte-ordering.
\section python_examples Additional Code Examples
You can use our unit tests to learn more about the %OpenMesh Python Bindings.
They are located in the src/Python/Unittests subdirectory.
\section python_cpp Python and C++
The interface of the Python Bindings is to a large extent identical to the
interface of the original C++ implementation of %OpenMesh. You should therefore
be able to use the C++ documentation as a reference for the Python Bindings. In
particular, the classes KernelT, PolyMeshT and TriMeshT provide a good overview
of the available mesh member functions. That being said, there are a number of
small differences. For example, whenever the C++ implementation returns a
reference to an object that is managed by %OpenMesh, the Python Bindings will
return a copy of that object. This is due to the fact that Python does not have
a language feature that is analogous to C++ references. One example of such a
function is the point() member function of the PolyMesh and TriMesh classes.
Unlike its C++ counterpart, the function does not return a reference to the
requested point. It instead returns a copy of the point. This implies that you
have to use the set_point() member function to change the value of a point. The
same applies to the following functions: normal(), color(), property(),
status(), etc.
<br>The complete source looks like this:
\include python_tutorial.py
**/

View File

@@ -10,6 +10,9 @@ https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh.git
The gitlab site can be found here:
https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh
The python bindings can be found here:
https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python
## Installing
Unpack the tar-ball to a suitable place.

View File

@@ -1,152 +0,0 @@
#include "Python/Bindings.hh"
#include "Python/Vector.hh"
#include "Python/Mesh.hh"
#include "Python/PropertyManager.hh"
#include "Python/InputOutput.hh"
#include "Python/Decimater.hh"
#include <memory>
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();
expose_decimater<PolyMesh>("PolyMesh");
expose_decimater<TriMesh>("TriMesh");
}
} // namespace Python
} // namespace OpenMesh

View File

@@ -1,48 +0,0 @@
/** @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

View File

@@ -1,215 +0,0 @@
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)
# Create log file
SET(PYTHONLOG "${CMAKE_CURRENT_BINARY_DIR}/PythonLog.txt")
FILE(WRITE ${PYTHONLOG} "")
# Look for the python libs
MESSAGE(STATUS "Looking for PythonLibs")
FIND_PACKAGE(PythonLibs ${OPENMESH_PYTHON_VERSION} QUIET)
IF(PYTHONLIBS_FOUND)
MESSAGE(STATUS "Looking for PythonLibs -- found")
# Determine the name of the python component
STRING(REGEX MATCH "^[0-9]+\\.[0-9]+" PYTHON_VERSION_MAJOR_MINOR ${PYTHONLIBS_VERSION_STRING})
STRING(REGEX REPLACE "\\." "" PYTHON_VERSION_MAJOR_MINOR ${PYTHON_VERSION_MAJOR_MINOR})
STRING(REGEX MATCH "^[0-9]" PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR_MINOR})
MESSAGE(STATUS "Looking for Boost Python")
SET(BOOST_PYTHON_COMPONENT_NAMES "python-py${PYTHON_VERSION_MAJOR_MINOR}" "python${PYTHON_VERSION_MAJOR}" "python")
FOREACH(NAME ${BOOST_PYTHON_COMPONENT_NAMES})
IF(NOT Boost_FOUND)
FILE(APPEND ${PYTHONLOG} "Looking for component ${NAME}\n")
FIND_PACKAGE(Boost QUIET COMPONENTS ${NAME})
ENDIF()
ENDFOREACH()
FILE(APPEND ${PYTHONLOG} "\n")
IF(Boost_FOUND)
MESSAGE(STATUS "Looking for Boost Python -- found")
MESSAGE(STATUS "Checking the Boost Python configuration")
SET(CMAKE_TRY_COMPILE_CONFIGURATION "Release")
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_DIRECTORIES:STRING=${Boost_LIBRARY_DIRS}"
"-DLINK_LIBRARIES:STRING=${PYTHON_LIBRARIES};${Boost_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT_TRY_COMPILE
)
FILE(APPEND ${PYTHONLOG} "INCLUDE_DIRECTORIES: ${PYTHON_INCLUDE_DIRS};${Boost_INCLUDE_DIRS}\n")
FILE(APPEND ${PYTHONLOG} "LINK_DIRECTORIES: ${Boost_LIBRARY_DIRS}\n")
FILE(APPEND ${PYTHONLOG} "LINK_LIBRARIES: ${PYTHON_LIBRARIES};${Boost_LIBRARIES}\n\n")
FILE(APPEND ${PYTHONLOG} "${OUTPUT_TRY_COMPILE}")
IF(COMPILE_WORKS)
# Look for the python interpreter to check if the example works
# strip version string of any characters (e.g. rc1 # '+') than 0-9 and .
STRING(REGEX REPLACE "(rc[0-9]+)|[^ 0-9 | \\.]" "" PYTHONLIBS_VERSION_STRING_STRIPPED ${PYTHONLIBS_VERSION_STRING})
FIND_PACKAGE(PythonInterp ${PYTHONLIBS_VERSION_STRING_STRIPPED} QUIET)
IF(PYTHONINTERP_FOUND)
IF(MSVC)
SET(PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_TRY_COMPILE_CONFIGURATION}")
ELSE()
SET(PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}")
ENDIF()
EXECUTE_PROCESS(
COMMAND ${PYTHON_EXECUTABLE} -c "from example import *; greet(); planet = World()"
WORKING_DIRECTORY ${PYTHON_WORKING_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(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
FILE(GLOB SOURCES *.cc *hh)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ../)
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
ADD_LIBRARY(openmesh SHARED ${SOURCES})
install(TARGETS openmesh DESTINATION ${ACG_PROJECT_LIBDIR}/python )
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")
IF (NOT (CMAKE_MAJOR_VERSION LESS 3))
SET_TARGET_PROPERTIES(openmesh PROPERTIES MACOSX_RPATH TRUE)
ENDIF()
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("PythonLibs not found! Skipping Python Bindings.")
ENDIF()
ENDIF()

View File

@@ -1,98 +0,0 @@
#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

View File

@@ -1,297 +0,0 @@
#ifndef OPENMESH_PYTHON_DECIMATER_HH
#define OPENMESH_PYTHON_DECIMATER_HH
#include "Python/Bindings.hh"
#include "OpenMesh/Tools/Decimater/ModBaseT.hh"
#include "OpenMesh/Tools/Decimater/ModAspectRatioT.hh"
#include "OpenMesh/Tools/Decimater/ModEdgeLengthT.hh"
#include "OpenMesh/Tools/Decimater/ModHausdorffT.hh"
#include "OpenMesh/Tools/Decimater/ModIndependentSetsT.hh"
#include "OpenMesh/Tools/Decimater/ModNormalDeviationT.hh"
#include "OpenMesh/Tools/Decimater/ModNormalFlippingT.hh"
#include "OpenMesh/Tools/Decimater/ModProgMeshT.hh"
#include "OpenMesh/Tools/Decimater/ModQuadricT.hh"
#include "OpenMesh/Tools/Decimater/ModRoundnessT.hh"
#include "OpenMesh/Tools/Decimater/DecimaterT.hh"
#include <cstdio>
namespace OpenMesh {
namespace Python {
#define INIT_MESH_REF init<Mesh&>()[with_custodian_and_ward<1,2>()]
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(decimate_overloads, decimate, 0, 1)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(decimate_to_faces_overloads, decimate_to_faces, 0, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_max_err_overloads, set_max_err, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_min_roundness_overloads, set_min_roundness, 1, 2)
template <class Handle>
void expose_module_handle(const char *_name) {
class_<Handle, boost::noncopyable>(_name)
.def("is_valid", &Handle::is_valid)
;
}
template <class Module>
list infolist(Module& _self) {
const typename Module::InfoList& infos = _self.infolist();
list res;
for (size_t i = 0; i < infos.size(); ++i) {
res.append(infos[i]);
}
return res;
}
template <class Mesh>
void expose_decimater(const char *_name) {
typedef Decimater::ModBaseT<Mesh> ModBase;
typedef Decimater::ModAspectRatioT<Mesh> ModAspectRatio;
typedef Decimater::ModEdgeLengthT<Mesh> ModEdgeLength;
typedef Decimater::ModHausdorffT<Mesh> ModHausdorff;
typedef Decimater::ModIndependentSetsT<Mesh> ModIndependentSets;
typedef Decimater::ModNormalDeviationT<Mesh> ModNormalDeviation;
typedef Decimater::ModNormalFlippingT<Mesh> ModNormalFlipping;
typedef Decimater::ModProgMeshT<Mesh> ModProgMesh;
typedef Decimater::ModQuadricT<Mesh> ModQuadric;
typedef Decimater::ModRoundnessT<Mesh> ModRoundness;
typedef Decimater::ModHandleT<ModAspectRatio> ModAspectRatioHandle;
typedef Decimater::ModHandleT<ModEdgeLength> ModEdgeLengthHandle;
typedef Decimater::ModHandleT<ModHausdorff> ModHausdorffHandle;
typedef Decimater::ModHandleT<ModIndependentSets> ModIndependentSetsHandle;
typedef Decimater::ModHandleT<ModNormalDeviation> ModNormalDeviationHandle;
typedef Decimater::ModHandleT<ModNormalFlipping> ModNormalFlippingHandle;
typedef Decimater::ModHandleT<ModProgMesh> ModProgMeshHandle;
typedef Decimater::ModHandleT<ModQuadric> ModQuadricHandle;
typedef Decimater::ModHandleT<ModRoundness> ModRoundnessHandle;
typedef Decimater::BaseDecimaterT<Mesh> BaseDecimater;
typedef Decimater::DecimaterT<Mesh> Decimater;
typedef typename ModProgMesh::Info Info;
typedef std::vector<Info> InfoList;
bool (BaseDecimater::*add1)(ModAspectRatioHandle&) = &Decimater::add;
bool (BaseDecimater::*add2)(ModEdgeLengthHandle&) = &Decimater::add;
bool (BaseDecimater::*add3)(ModHausdorffHandle&) = &Decimater::add;
bool (BaseDecimater::*add4)(ModIndependentSetsHandle&) = &Decimater::add;
bool (BaseDecimater::*add5)(ModNormalDeviationHandle&) = &Decimater::add;
bool (BaseDecimater::*add6)(ModNormalFlippingHandle&) = &Decimater::add;
bool (BaseDecimater::*add7)(ModProgMeshHandle&) = &Decimater::add;
bool (BaseDecimater::*add8)(ModQuadricHandle&) = &Decimater::add;
bool (BaseDecimater::*add9)(ModRoundnessHandle&) = &Decimater::add;
bool (BaseDecimater::*remove1)(ModAspectRatioHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove2)(ModEdgeLengthHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove3)(ModHausdorffHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove4)(ModIndependentSetsHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove5)(ModNormalDeviationHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove6)(ModNormalFlippingHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove7)(ModProgMeshHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove8)(ModQuadricHandle&) = &Decimater::remove;
bool (BaseDecimater::*remove9)(ModRoundnessHandle&) = &Decimater::remove;
ModAspectRatio& (BaseDecimater::*module1)(ModAspectRatioHandle&) = &Decimater::module;
ModEdgeLength& (BaseDecimater::*module2)(ModEdgeLengthHandle&) = &Decimater::module;
ModHausdorff& (BaseDecimater::*module3)(ModHausdorffHandle&) = &Decimater::module;
ModIndependentSets& (BaseDecimater::*module4)(ModIndependentSetsHandle&) = &Decimater::module;
ModNormalDeviation& (BaseDecimater::*module5)(ModNormalDeviationHandle&) = &Decimater::module;
ModNormalFlipping& (BaseDecimater::*module6)(ModNormalFlippingHandle&) = &Decimater::module;
ModProgMesh& (BaseDecimater::*module7)(ModProgMeshHandle&) = &Decimater::module;
ModQuadric& (BaseDecimater::*module8)(ModQuadricHandle&) = &Decimater::module;
ModRoundness& (BaseDecimater::*module9)(ModRoundnessHandle&) = &Decimater::module;
// Decimater
// ----------------------------------------
char buffer[64];
snprintf(buffer, sizeof buffer, "%s%s", _name, "Decimater");
class_<Decimater, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("decimate", &Decimater::decimate, decimate_overloads())
.def("decimate_to", &Decimater::decimate_to)
.def("decimate_to_faces", &Decimater::decimate_to_faces, decimate_to_faces_overloads())
.def("initialize", &Decimater::initialize)
.def("is_initialized", &Decimater::is_initialized)
.def("add", add1)
.def("add", add2)
.def("add", add3)
.def("add", add4)
.def("add", add5)
.def("add", add6)
.def("add", add7)
.def("add", add8)
.def("add", add9)
.def("remove", remove1)
.def("remove", remove2)
.def("remove", remove3)
.def("remove", remove4)
.def("remove", remove5)
.def("remove", remove6)
.def("remove", remove7)
.def("remove", remove8)
.def("remove", remove9)
.def("module", module1, return_value_policy<reference_existing_object>())
.def("module", module2, return_value_policy<reference_existing_object>())
.def("module", module3, return_value_policy<reference_existing_object>())
.def("module", module4, return_value_policy<reference_existing_object>())
.def("module", module5, return_value_policy<reference_existing_object>())
.def("module", module6, return_value_policy<reference_existing_object>())
.def("module", module7, return_value_policy<reference_existing_object>())
.def("module", module8, return_value_policy<reference_existing_object>())
.def("module", module9, return_value_policy<reference_existing_object>())
;
// ModBase
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModBase");
class_<ModBase, boost::noncopyable>(buffer, no_init)
.def("name", &ModBase::name, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("is_binary", &ModBase::is_binary)
.def("set_binary", &ModBase::set_binary)
.def("initialize", &ModBase::initialize) // TODO VIRTUAL
.def("collapse_priority", &ModBase::collapse_priority) // TODO VIRTUAL
.def("preprocess_collapse", &ModBase::preprocess_collapse) // TODO VIRTUAL
.def("postprocess_collapse", &ModBase::postprocess_collapse) // TODO VIRTUAL
.def("set_error_tolerance_factor", &ModBase::set_error_tolerance_factor) // TODO VIRTUAL
;
// ModAspectRatio
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModAspectRatio");
class_<ModAspectRatio, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("aspect_ratio", &ModAspectRatio::aspect_ratio)
.def("set_aspect_ratio", &ModAspectRatio::set_aspect_ratio)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModAspectRatioHandle");
expose_module_handle<ModAspectRatioHandle>(buffer);
// ModEdgeLength
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModEdgeLength");
class_<ModEdgeLength, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("edge_length", &ModEdgeLength::edge_length)
.def("set_edge_length", &ModEdgeLength::set_edge_length)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModEdgeLengthHandle");
expose_module_handle<ModEdgeLengthHandle>(buffer);
// ModHausdorff
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModHausdorff");
class_<ModHausdorff, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("tolerance", &ModHausdorff::tolerance)
.def("set_tolerance", &ModHausdorff::set_tolerance)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModHausdorffHandle");
expose_module_handle<ModHausdorffHandle>(buffer);
// ModIndependentSets
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModIndependentSets");
class_<ModIndependentSets, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF);
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModIndependentSetsHandle");
expose_module_handle<ModIndependentSetsHandle>(buffer);
// ModNormalDeviation
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalDeviation");
class_<ModNormalDeviation, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("normal_deviation", &ModNormalDeviation::normal_deviation)
.def("set_normal_deviation", &ModNormalDeviation::set_normal_deviation)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalDeviationHandle");
expose_module_handle<ModNormalDeviationHandle>(buffer);
// ModNormalFlipping
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalFlipping");
class_<ModNormalFlipping, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("max_normal_deviation", &ModNormalFlipping::max_normal_deviation)
.def("set_max_normal_deviation", &ModNormalFlipping::set_max_normal_deviation)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModNormalFlippingHandle");
expose_module_handle<ModNormalFlippingHandle>(buffer);
// ModProgMesh
// ----------------------------------------
class_<Info>("Info", no_init)
.def_readwrite("v0", &Info::v0)
.def_readwrite("v1", &Info::v1)
.def_readwrite("vl", &Info::vl)
.def_readwrite("vr", &Info::vr)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModProgMesh");
class_<ModProgMesh, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("pmi", &infolist<ModProgMesh>)
.def("infolist", &infolist<ModProgMesh>)
.def("write", &ModProgMesh::write)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModProgMeshHandle");
expose_module_handle<ModProgMeshHandle>(buffer);
// ModQuadric
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModQuadric");
class_<ModQuadric, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("set_max_err", &ModQuadric::set_max_err, set_max_err_overloads())
.def("unset_max_err", &ModQuadric::unset_max_err)
.def("max_err", &ModQuadric::max_err)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModQuadricHandle");
expose_module_handle<ModQuadricHandle>(buffer);
// ModRoundness
// ----------------------------------------
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModRoundness");
class_<ModRoundness, bases<ModBase>, boost::noncopyable>(buffer, INIT_MESH_REF)
.def("set_min_angle", &ModRoundness::set_min_angle)
.def("set_min_roundness", &ModRoundness::set_min_roundness, set_min_roundness_overloads())
.def("unset_min_roundness", &ModRoundness::unset_min_roundness)
.def("roundness", &ModRoundness::roundness)
;
snprintf(buffer, sizeof buffer, "%s%s", _name, "ModRoundnessHandle");
expose_module_handle<ModRoundnessHandle>(buffer);
}
} // namespace OpenMesh
} // namespace Python
#endif

View File

@@ -1,30 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(Example)
FILE(GLOB SOURCES *.cc *hh)
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})
LINK_DIRECTORIES(${LINK_DIRECTORIES})
ADD_LIBRARY(example SHARED ${SOURCES})
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")
IF (NOT (CMAKE_MAJOR_VERSION LESS 3))
SET_TARGET_PROPERTIES(example PROPERTIES MACOSX_RPATH TRUE)
ENDIF()
ENDIF()
IF(WIN32)
SET_TARGET_PROPERTIES(example PROPERTIES SUFFIX ".pyd")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
ENDIF()

View File

@@ -1,22 +0,0 @@
#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)
;
}

View File

@@ -1,115 +0,0 @@
#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

View File

@@ -1,121 +0,0 @@
#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.
*
* @return This iterator.
*/
IteratorWrapperT 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 Iterator::value_type next() {
if (iterator_ != iterator_end_) {
typename Iterator::value_type res = *iterator_;
++iterator_;
return res;
}
else {
PyErr_SetString(PyExc_StopIteration, "No more data.");
boost::python::throw_error_already_set();
}
return typename Iterator::value_type();
}
/**
* Implementation of %Python's \_\_len\_\_ magic method.
*
* @return The number of items in the mesh.
*/
unsigned int len() const {
return (mesh_.*n_items_)();
}
private:
const OpenMesh::PolyConnectivity& mesh_;
size_t (OpenMesh::ArrayKernel::*n_items_)() const;
Iterator iterator_;
Iterator iterator_end_;
};
/**
* Expose an iterator type to %Python.
*
* @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).
*
* @param _name The name of the iterator type to be exposed.
*
* @note %Iterators are wrapped by IteratorWrapperT before they are exposed to
* %Python, i.e. they are not exposed directly. This means that iterators
* that are passed from %Python to C++ are instances of IteratorWrapperT.
*/
template<class Iterator, size_t (OpenMesh::ArrayKernel::*n_items)() const>
void expose_iterator(const char *_name) {
class_<IteratorWrapperT<Iterator, n_items> >(_name, init<PolyMesh&, typename Iterator::value_type, optional<bool> >())
.def(init<TriMesh&, typename Iterator::value_type, optional<bool> >())
.def("__iter__", &IteratorWrapperT<Iterator, n_items>::iter)
.def("__next__", &IteratorWrapperT<Iterator, n_items>::next)
.def("__len__", &IteratorWrapperT<Iterator, n_items>::len)
.def("next", &IteratorWrapperT<Iterator, n_items>::next)
;
}
} // namespace OpenMesh
} // namespace Python
#endif

View File

@@ -1,931 +0,0 @@
#ifndef OPENMESH_PYTHON_MESH_HH
#define OPENMESH_PYTHON_MESH_HH
#include "Python/Bindings.hh"
#include "Python/Iterator.hh"
#include "Python/Circulator.hh"
#include <boost/python/stl_iterator.hpp>
namespace OpenMesh {
namespace Python {
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(garbage_collection_overloads, garbage_collection, 0, 3)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(add_property_overloads, add_property, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(copy_all_properties_overloads, copy_all_properties, 2, 3)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(delete_vertex_overloads, delete_vertex, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(delete_edge_overloads, delete_edge, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(delete_face_overloads, delete_face, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(is_boundary_overloads, is_boundary, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(find_feature_edges_overloads, find_feature_edges, 0, 1)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(update_normal_overloads, update_normal, 1, 2)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(update_halfedge_normals_overloads, update_halfedge_normals, 0, 1)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(calc_halfedge_normal_overloads, calc_halfedge_normal, 1, 2)
/**
* Set the status of an item.
*
* @tparam Mesh A mesh type.
* @tparam PropHandle A handle type.
*
* @param _self The mesh instance that is to be used.
* @param _h The handle of the item whose status is to be set.
* @param _info The status to be set.
*
* Depending on @ref OPENMESH_PYTHON_DEFAULT_POLICY, Mesh::status may
* return by value instead of reference. This function ensures that the
* status of an item can be changed nonetheless.
*/
template <class Mesh, class IndexHandle>
void set_status(Mesh& _self, IndexHandle _h, const OpenMesh::Attributes::StatusInfo& _info) {
_self.status(_h) = _info;
}
/**
* Set the value of a property of an item.
*
* @tparam Mesh A mesh type.
* @tparam PropHandle A property handle type.
* @tparam IndexHandle The appropriate handle type.
*
* @param _self The mesh instance that is to be used.
* @param _ph The property that is to be set.
* @param _h The handle of the item whose property is to be set.
* @param _value The value to be set.
*
* Depending on @ref OPENMESH_PYTHON_DEFAULT_POLICY, Mesh::property may
* return by value instead of reference. This function ensures that the
* property value of an item can be changed nonetheless.
*/
template <class Mesh, class PropHandle, class IndexHandle>
void set_property(Mesh& _self, PropHandle _ph, IndexHandle _h, const object& _value) {
_self.property(_ph, _h) = _value;
}
/**
* Set the value of a mesh property.
*
* @tparam Mesh A mesh type.
* @tparam PropHandle A property handle type.
*
* @param _self The mesh instance that is to be used.
* @param _ph The property that is to be set.
* @param _value The value to be set.
*
* Depending on @ref OPENMESH_PYTHON_DEFAULT_POLICY, Mesh::property may
* return by value instead of reference. This function ensures that the
* property value of an item can be changed nonetheless.
*/
template <class Mesh, class PropHandle>
void set_property(Mesh& _self, PropHandle _ph, const object& _value) {
_self.property(_ph) = _value;
}
/**
* Thin wrapper for assign_connectivity.
*
* @tparam Mesh A mesh type.
* @tparam OtherMesh A mesh type.
*
* @param _self The mesh instance that is to be used.
* @param _other The mesh from which the connectivity is to be copied.
*/
template <class Mesh, class OtherMesh>
void assign_connectivity(Mesh& _self, const OtherMesh& _other) {
_self.assign_connectivity(_other);
}
/**
* Get an iterator.
*/
template <class Mesh, class Iterator, size_t (ArrayKernel::*n_items)() const>
IteratorWrapperT<Iterator, n_items> get_iterator(Mesh& _self) {
return IteratorWrapperT<Iterator, n_items>(_self, typename Iterator::value_type(0));
}
/**
* Get a skipping iterator.
*/
template <class Mesh, class Iterator, size_t (ArrayKernel::*n_items)() const>
IteratorWrapperT<Iterator, n_items> get_skipping_iterator(Mesh& _self) {
return IteratorWrapperT<Iterator, n_items>(_self, typename Iterator::value_type(0), true);
}
/**
* Get a circulator.
*
* @tparam Mesh A Mesh type.
* @tparam Circulator A circulator type.
* @tparam CenterEntityHandle The appropriate handle type.
*
* @param _self The mesh instance that is to be used.
* @param _handle The handle of the item to circulate around.
*/
template <class Mesh, class Circulator, class CenterEntityHandle>
CirculatorWrapperT<Circulator, CenterEntityHandle> get_circulator(Mesh& _self, CenterEntityHandle _handle) {
return CirculatorWrapperT<Circulator, CenterEntityHandle>(_self, _handle);
}
/**
* Garbage collection using lists instead of vectors to keep track of a set of
* handles.
*
* @tparam Mesh A Mesh type.
*
* @param _self The mesh instance that is to be used.
* @param _vh_to_update The list of vertex handles to be updated.
* @param _hh_to_update The list of halfedge handles to be updated.
* @param _fh_to_update The list of face handles to be updated.
* @param _v Remove deleted vertices?
* @param _e Remove deleted edges?
* @param _f Remove deleted faces?
*/
template <class Mesh>
void garbage_collection(Mesh& _self, list& _vh_to_update, list& _hh_to_update, list& _fh_to_update, bool _v = true, bool _e = true, bool _f = true) {
// Convert list of handles to vector of pointers
stl_input_iterator<VertexHandle*> vh_begin(_vh_to_update);
stl_input_iterator<VertexHandle*> vh_end;
std::vector<VertexHandle*> vh_vector;
vh_vector.insert(vh_vector.end(), vh_begin, vh_end);
// Convert list of handles to vector of pointers
stl_input_iterator<HalfedgeHandle*> hh_begin(_hh_to_update);
stl_input_iterator<HalfedgeHandle*> hh_end;
std::vector<HalfedgeHandle*> hh_vector;
hh_vector.insert(hh_vector.end(), hh_begin, hh_end);
// Convert list of handles to vector of pointers
stl_input_iterator<FaceHandle*> fh_begin(_fh_to_update);
stl_input_iterator<FaceHandle*> fh_end;
std::vector<FaceHandle*> fh_vector;
fh_vector.insert(fh_vector.end(), fh_begin, fh_end);
// Call garbage collection
_self.garbage_collection(vh_vector, hh_vector, fh_vector, _v, _e, _f);
}
/**
* Add a new face from a %Python list of vertex handles.
*
* @tparam Mesh A Mesh type.
*
* @param _self The mesh instance that is to be used.
* @param _vhandles The list of vertex handles.
*/
template<class Mesh>
FaceHandle add_face(Mesh& _self, const list& _vhandles) {
stl_input_iterator<VertexHandle> begin(_vhandles);
stl_input_iterator<VertexHandle> end;
std::vector<VertexHandle> vector;
vector.insert(vector.end(), begin, end);
return _self.add_face(vector);
}
/**
* This function template is used to expose mesh member functions that are only
* available for a specific type of mesh (i.e. they are available for polygon
* meshes or triangle meshes, but not both).
*
* @tparam Class A boost::python::class type.
*
* @param _class The boost::python::class instance for which the member
* functions are to be defined.
*/
template <class Class>
void expose_type_specific_functions(Class& _class) {
// See the template specializations below
}
/**
* Function template specialization for polygon meshes.
*/
template <>
void expose_type_specific_functions(class_<PolyMesh>& _class) {
typedef PolyMesh::Scalar Scalar;
typedef PolyMesh::Point Point;
typedef PolyMesh::Normal Normal;
typedef PolyMesh::Color Color;
FaceHandle (PolyMesh::*add_face_3_vh)(VertexHandle, VertexHandle, VertexHandle ) = &PolyMesh::add_face;
FaceHandle (PolyMesh::*add_face_4_vh)(VertexHandle, VertexHandle, VertexHandle, VertexHandle) = &PolyMesh::add_face;
FaceHandle (*add_face_list)(PolyMesh&, const list&) = &add_face;
void (PolyMesh::*split_eh_pt)(EdgeHandle, const Point&) = &PolyMesh::split;
void (PolyMesh::*split_eh_vh)(EdgeHandle, VertexHandle) = &PolyMesh::split;
void (PolyMesh::*split_fh_pt)(FaceHandle, const Point&) = &PolyMesh::split;
void (PolyMesh::*split_fh_vh)(FaceHandle, VertexHandle) = &PolyMesh::split;
Normal (PolyMesh::*calc_face_normal_pt)(const Point&, const Point&, const Point&) const = &PolyMesh::calc_face_normal;
_class
.def("add_face", add_face_3_vh)
.def("add_face", add_face_4_vh)
.def("add_face", add_face_list)
.def("split", split_eh_pt)
.def("split", split_eh_vh)
.def("split", split_fh_pt)
.def("split", split_fh_vh)
.def("split_copy", &PolyMesh::split_copy)
.def("calc_face_normal", calc_face_normal_pt)
.def("insert_edge", &PolyMesh::insert_edge)
;
}
/**
* Function template specialization for triangle meshes.
*/
template <>
void expose_type_specific_functions(class_<TriMesh>& _class) {
typedef TriMesh::Scalar Scalar;
typedef TriMesh::Point Point;
typedef TriMesh::Normal Normal;
typedef TriMesh::Color Color;
FaceHandle (TriMesh::*add_face_3_vh)(VertexHandle, VertexHandle, VertexHandle) = &TriMesh::add_face;
FaceHandle (*add_face_list)(TriMesh&, const list&) = &add_face;
VertexHandle (TriMesh::*split_eh_pt)(EdgeHandle, const Point&) = &TriMesh::split;
void (TriMesh::*split_eh_vh)(EdgeHandle, VertexHandle) = &TriMesh::split;
VertexHandle (TriMesh::*split_fh_pt)(FaceHandle, const Point&) = &TriMesh::split;
void (TriMesh::*split_fh_vh)(FaceHandle, VertexHandle) = &TriMesh::split;
VertexHandle (TriMesh::*split_copy_eh_pt)(EdgeHandle, const Point&) = &TriMesh::split_copy;
void (TriMesh::*split_copy_eh_vh)(EdgeHandle, VertexHandle) = &TriMesh::split_copy;
VertexHandle (TriMesh::*split_copy_fh_pt)(FaceHandle, const Point&) = &TriMesh::split_copy;
void (TriMesh::*split_copy_fh_vh)(FaceHandle, VertexHandle) = &TriMesh::split_copy;
HalfedgeHandle (TriMesh::*vertex_split_pt)(Point, VertexHandle, VertexHandle, VertexHandle) = &TriMesh::vertex_split;
HalfedgeHandle (TriMesh::*vertex_split_vh)(VertexHandle, VertexHandle, VertexHandle, VertexHandle) = &TriMesh::vertex_split;
_class
.def("add_face", add_face_3_vh)
.def("add_face", add_face_list)
.def("split", split_eh_pt)
.def("split", split_eh_vh)
.def("split", split_fh_pt)
.def("split", split_fh_vh)
.def("split_copy", split_copy_eh_pt)
.def("split_copy", split_copy_eh_vh)
.def("split_copy", split_copy_fh_pt)
.def("split_copy", split_copy_fh_vh)
.def("opposite_vh", &TriMesh::opposite_vh)
.def("opposite_he_opposite_vh", &TriMesh::opposite_he_opposite_vh)
.def("vertex_split", vertex_split_pt)
.def("vertex_split", vertex_split_vh)
.def("is_flip_ok", &TriMesh::is_flip_ok)
.def("flip", &TriMesh::flip)
;
}
/**
* Expose a mesh type to %Python.
*
* @tparam Mesh A mesh type.
*
* @param _name The name of the mesh type to be exposed.
*/
template <class Mesh>
void expose_mesh(const char *_name) {
using OpenMesh::Attributes::StatusInfo;
typedef typename Mesh::Scalar Scalar;
typedef typename Mesh::Point Point;
typedef typename Mesh::Normal Normal;
typedef typename Mesh::Color Color;
//======================================================================
// KernelT Function Pointers
//======================================================================
// Get the i'th item
VertexHandle (Mesh::*vertex_handle_uint )(unsigned int) const = &Mesh::vertex_handle;
HalfedgeHandle (Mesh::*halfedge_handle_uint)(unsigned int) const = &Mesh::halfedge_handle;
EdgeHandle (Mesh::*edge_handle_uint )(unsigned int) const = &Mesh::edge_handle;
FaceHandle (Mesh::*face_handle_uint )(unsigned int) const = &Mesh::face_handle;
// Delete items
void (Mesh::*garbage_collection_bools)(bool, bool, bool) = &Mesh::garbage_collection;
void (*garbage_collection_lists_bools)(Mesh&, list&, list&, list&, bool, bool, bool) = &garbage_collection;
// Vertex connectivity
HalfedgeHandle (Mesh::*halfedge_handle_vh)(VertexHandle) const = &Mesh::halfedge_handle;
HalfedgeHandle (Mesh::*halfedge_handle_fh)(FaceHandle ) const = &Mesh::halfedge_handle;
// Halfedge connectivity
FaceHandle (Mesh::*face_handle_hh )(HalfedgeHandle) const = &Mesh::face_handle;
HalfedgeHandle (Mesh::*prev_halfedge_handle_hh)(HalfedgeHandle) const = &Mesh::prev_halfedge_handle;
EdgeHandle (Mesh::*edge_handle_hh )(HalfedgeHandle) const = &Mesh::edge_handle;
// Edge connectivity
HalfedgeHandle (Mesh::*halfedge_handle_eh_uint)(EdgeHandle, unsigned int) const = &Mesh::halfedge_handle;
// Set halfedge
void (Mesh::*set_halfedge_handle_vh_hh)(VertexHandle, HalfedgeHandle) = &Mesh::set_halfedge_handle;
void (Mesh::*set_halfedge_handle_fh_hh)(FaceHandle, HalfedgeHandle ) = &Mesh::set_halfedge_handle;
// Handle -> Item
const typename Mesh::Vertex& (Mesh::*vertex )(VertexHandle ) const = &Mesh::vertex;
const typename Mesh::Halfedge& (Mesh::*halfedge)(HalfedgeHandle) const = &Mesh::halfedge;
const typename Mesh::Edge& (Mesh::*edge )(EdgeHandle ) const = &Mesh::edge;
const typename Mesh::Face& (Mesh::*face )(FaceHandle ) const = &Mesh::face;
// Item -> Handle
VertexHandle (Mesh::*handle_v)(const typename Mesh::Vertex& ) const = &Mesh::handle;
HalfedgeHandle (Mesh::*handle_h)(const typename Mesh::Halfedge&) const = &Mesh::handle;
EdgeHandle (Mesh::*handle_e)(const typename Mesh::Edge& ) const = &Mesh::handle;
FaceHandle (Mesh::*handle_f)(const typename Mesh::Face& ) const = &Mesh::handle;
// Get value of a standard property (point, normal, color)
const typename Mesh::Point& (Mesh::*point_vh )(VertexHandle ) const = &Mesh::point;
const typename Mesh::Normal& (Mesh::*normal_vh)(VertexHandle ) const = &Mesh::normal;
const typename Mesh::Normal& (Mesh::*normal_hh)(HalfedgeHandle) const = &Mesh::normal;
const typename Mesh::Normal& (Mesh::*normal_fh)(FaceHandle ) const = &Mesh::normal;
const typename Mesh::Color& (Mesh::*color_vh )(VertexHandle ) const = &Mesh::color;
const typename Mesh::Color& (Mesh::*color_hh )(HalfedgeHandle) const = &Mesh::color;
const typename Mesh::Color& (Mesh::*color_eh )(EdgeHandle ) const = &Mesh::color;
const typename Mesh::Color& (Mesh::*color_fh )(FaceHandle ) const = &Mesh::color;
// Get value of a standard property (texture coordinate)
const typename Mesh::TexCoord1D& (Mesh::*texcoord1D_vh)(VertexHandle ) const = &Mesh::texcoord1D;
const typename Mesh::TexCoord1D& (Mesh::*texcoord1D_hh)(HalfedgeHandle) const = &Mesh::texcoord1D;
const typename Mesh::TexCoord2D& (Mesh::*texcoord2D_vh)(VertexHandle ) const = &Mesh::texcoord2D;
const typename Mesh::TexCoord2D& (Mesh::*texcoord2D_hh)(HalfedgeHandle) const = &Mesh::texcoord2D;
const typename Mesh::TexCoord3D& (Mesh::*texcoord3D_vh)(VertexHandle ) const = &Mesh::texcoord3D;
const typename Mesh::TexCoord3D& (Mesh::*texcoord3D_hh)(HalfedgeHandle) const = &Mesh::texcoord3D;
// Get value of a standard property (status)
const StatusInfo& (Mesh::*status_vh)(VertexHandle ) const = &Mesh::status;
const StatusInfo& (Mesh::*status_hh)(HalfedgeHandle) const = &Mesh::status;
const StatusInfo& (Mesh::*status_eh)(EdgeHandle ) const = &Mesh::status;
const StatusInfo& (Mesh::*status_fh)(FaceHandle ) const = &Mesh::status;
// Set value of a standard property (point, normal, color)
void (Mesh::*set_normal_vh)(VertexHandle, const typename Mesh::Normal&) = &Mesh::set_normal;
void (Mesh::*set_normal_hh)(HalfedgeHandle, const typename Mesh::Normal&) = &Mesh::set_normal;
void (Mesh::*set_normal_fh)(FaceHandle, const typename Mesh::Normal&) = &Mesh::set_normal;
void (Mesh::*set_color_vh )(VertexHandle, const typename Mesh::Color& ) = &Mesh::set_color;
void (Mesh::*set_color_hh )(HalfedgeHandle, const typename Mesh::Color& ) = &Mesh::set_color;
void (Mesh::*set_color_eh )(EdgeHandle, const typename Mesh::Color& ) = &Mesh::set_color;
void (Mesh::*set_color_fh )(FaceHandle, const typename Mesh::Color& ) = &Mesh::set_color;
// Set value of a standard property (texture coordinate)
void (Mesh::*set_texcoord1D_vh)(VertexHandle, const typename Mesh::TexCoord1D&) = &Mesh::set_texcoord1D;
void (Mesh::*set_texcoord1D_hh)(HalfedgeHandle, const typename Mesh::TexCoord1D&) = &Mesh::set_texcoord1D;
void (Mesh::*set_texcoord2D_vh)(VertexHandle, const typename Mesh::TexCoord2D&) = &Mesh::set_texcoord2D;
void (Mesh::*set_texcoord2D_hh)(HalfedgeHandle, const typename Mesh::TexCoord2D&) = &Mesh::set_texcoord2D;
void (Mesh::*set_texcoord3D_vh)(VertexHandle, const typename Mesh::TexCoord3D&) = &Mesh::set_texcoord3D;
void (Mesh::*set_texcoord3D_hh)(HalfedgeHandle, const typename Mesh::TexCoord3D&) = &Mesh::set_texcoord3D;
// Set value of a standard property (status)
void (*set_status_vh)(Mesh&, VertexHandle, const StatusInfo&) = &set_status;
void (*set_status_hh)(Mesh&, HalfedgeHandle, const StatusInfo&) = &set_status;
void (*set_status_eh)(Mesh&, EdgeHandle, const StatusInfo&) = &set_status;
void (*set_status_fh)(Mesh&, FaceHandle, const StatusInfo&) = &set_status;
// Property management - add property
void (Mesh::*add_property_vph)(VPropHandleT<object>&, const std::string&) = &Mesh::add_property;
void (Mesh::*add_property_eph)(EPropHandleT<object>&, const std::string&) = &Mesh::add_property;
void (Mesh::*add_property_hph)(HPropHandleT<object>&, const std::string&) = &Mesh::add_property;
void (Mesh::*add_property_fph)(FPropHandleT<object>&, const std::string&) = &Mesh::add_property;
void (Mesh::*add_property_mph)(MPropHandleT<object>&, const std::string&) = &Mesh::add_property;
// Property management - remove property
void (Mesh::*remove_property_vph)(VPropHandleT<object>&) = &Mesh::remove_property;
void (Mesh::*remove_property_eph)(EPropHandleT<object>&) = &Mesh::remove_property;
void (Mesh::*remove_property_hph)(HPropHandleT<object>&) = &Mesh::remove_property;
void (Mesh::*remove_property_fph)(FPropHandleT<object>&) = &Mesh::remove_property;
void (Mesh::*remove_property_mph)(MPropHandleT<object>&) = &Mesh::remove_property;
// Property management - get property by name
bool (Mesh::*get_property_handle_vph)(VPropHandleT<object>&, const std::string&) const = &Mesh::get_property_handle;
bool (Mesh::*get_property_handle_eph)(EPropHandleT<object>&, const std::string&) const = &Mesh::get_property_handle;
bool (Mesh::*get_property_handle_hph)(HPropHandleT<object>&, const std::string&) const = &Mesh::get_property_handle;
bool (Mesh::*get_property_handle_fph)(FPropHandleT<object>&, const std::string&) const = &Mesh::get_property_handle;
bool (Mesh::*get_property_handle_mph)(MPropHandleT<object>&, const std::string&) const = &Mesh::get_property_handle;
// Property management - get property value for an item
const object& (Mesh::*property_vertex )(VPropHandleT<object>, VertexHandle ) const = &Mesh::property;
const object& (Mesh::*property_edge )(EPropHandleT<object>, EdgeHandle ) const = &Mesh::property;
const object& (Mesh::*property_halfedge)(HPropHandleT<object>, HalfedgeHandle) const = &Mesh::property;
const object& (Mesh::*property_face )(FPropHandleT<object>, FaceHandle ) const = &Mesh::property;
const object& (Mesh::*property_mesh )(MPropHandleT<object> ) const = &Mesh::property;
// Property management - set property value for an item
void (*set_property_vertex )(Mesh&, VPropHandleT<object>, VertexHandle, const object&) = &set_property;
void (*set_property_edge )(Mesh&, EPropHandleT<object>, EdgeHandle, const object&) = &set_property;
void (*set_property_halfedge)(Mesh&, HPropHandleT<object>, HalfedgeHandle, const object&) = &set_property;
void (*set_property_face )(Mesh&, FPropHandleT<object>, FaceHandle, const object&) = &set_property;
void (*set_property_mesh )(Mesh&, MPropHandleT<object>, const object&) = &set_property;
// Low-level adding new items
VertexHandle (Mesh::*new_vertex_void )(void ) = &Mesh::new_vertex;
VertexHandle (Mesh::*new_vertex_point)(const typename Mesh::Point& ) = &Mesh::new_vertex;
FaceHandle (Mesh::*new_face_void )(void ) = &Mesh::new_face;
FaceHandle (Mesh::*new_face_face )(const typename Mesh::Face& ) = &Mesh::new_face;
// Kernel item iterators
IteratorWrapperT<typename Mesh::VertexIter, &Mesh::n_vertices > (*vertices )(Mesh&) = &get_iterator;
IteratorWrapperT<typename Mesh::HalfedgeIter, &Mesh::n_halfedges> (*halfedges)(Mesh&) = &get_iterator;
IteratorWrapperT<typename Mesh::EdgeIter, &Mesh::n_edges > (*edges )(Mesh&) = &get_iterator;
IteratorWrapperT<typename Mesh::FaceIter, &Mesh::n_faces > (*faces )(Mesh&) = &get_iterator;
IteratorWrapperT<typename Mesh::VertexIter, &Mesh::n_vertices > (*svertices )(Mesh&) = &get_skipping_iterator;
IteratorWrapperT<typename Mesh::HalfedgeIter, &Mesh::n_halfedges> (*shalfedges)(Mesh&) = &get_skipping_iterator;
IteratorWrapperT<typename Mesh::EdgeIter, &Mesh::n_edges > (*sedges )(Mesh&) = &get_skipping_iterator;
IteratorWrapperT<typename Mesh::FaceIter, &Mesh::n_faces > (*sfaces )(Mesh&) = &get_skipping_iterator;
//======================================================================
// BaseKernel Function Pointers
//======================================================================
// Copy property
void (Mesh::*copy_property_vprop)(VPropHandleT<object>&, VertexHandle, VertexHandle ) = &Mesh::copy_property;
void (Mesh::*copy_property_hprop)(HPropHandleT<object>, HalfedgeHandle, HalfedgeHandle) = &Mesh::copy_property;
void (Mesh::*copy_property_eprop)(EPropHandleT<object>, EdgeHandle, EdgeHandle ) = &Mesh::copy_property;
void (Mesh::*copy_property_fprop)(FPropHandleT<object>, FaceHandle, FaceHandle ) = &Mesh::copy_property;
// Copy all properties
void (Mesh::*copy_all_properties_vh_vh_bool)(VertexHandle, VertexHandle, bool) = &Mesh::copy_all_properties;
void (Mesh::*copy_all_properties_hh_hh_bool)(HalfedgeHandle, HalfedgeHandle, bool) = &Mesh::copy_all_properties;
void (Mesh::*copy_all_properties_eh_eh_bool)(EdgeHandle, EdgeHandle, bool) = &Mesh::copy_all_properties;
void (Mesh::*copy_all_properties_fh_fh_bool)(FaceHandle, FaceHandle, bool) = &Mesh::copy_all_properties;
//======================================================================
// PolyConnectivity Function Pointers
//======================================================================
// Assign connectivity
void (*assign_connectivity_poly)(Mesh&, const PolyMesh&) = &assign_connectivity;
void (*assign_connectivity_tri )(Mesh&, const TriMesh& ) = &assign_connectivity;
// Vertex and face valence
unsigned int (Mesh::*valence_vh)(VertexHandle) const = &Mesh::valence;
unsigned int (Mesh::*valence_fh)(FaceHandle ) const = &Mesh::valence;
// Triangulate face or mesh
void (Mesh::*triangulate_fh )(FaceHandle) = &Mesh::triangulate;
void (Mesh::*triangulate_void)( ) = &Mesh::triangulate;
// Deleting mesh items and other connectivity/topology modifications
void (Mesh::*delete_vertex)(VertexHandle, bool) = &Mesh::delete_vertex;
void (Mesh::*delete_edge )(EdgeHandle, bool) = &Mesh::delete_edge;
void (Mesh::*delete_face )(FaceHandle, bool) = &Mesh::delete_face;
// Vertex and Face circulators
CirculatorWrapperT<typename Mesh::VertexVertexIter, VertexHandle > (*vv )(Mesh&, VertexHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::VertexIHalfedgeIter, VertexHandle > (*vih)(Mesh&, VertexHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::VertexOHalfedgeIter, VertexHandle > (*voh)(Mesh&, VertexHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::VertexEdgeIter, VertexHandle > (*ve )(Mesh&, VertexHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::VertexFaceIter, VertexHandle > (*vf )(Mesh&, VertexHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::FaceVertexIter, FaceHandle > (*fv )(Mesh&, FaceHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::FaceHalfedgeIter, FaceHandle > (*fh )(Mesh&, FaceHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::FaceEdgeIter, FaceHandle > (*fe )(Mesh&, FaceHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::FaceFaceIter, FaceHandle > (*ff )(Mesh&, FaceHandle ) = &get_circulator;
CirculatorWrapperT<typename Mesh::HalfedgeLoopIter, HalfedgeHandle> (*hl )(Mesh&, HalfedgeHandle) = &get_circulator;
// Boundary and manifold tests
bool (Mesh::*is_boundary_hh)(HalfedgeHandle ) const = &Mesh::is_boundary;
bool (Mesh::*is_boundary_eh)(EdgeHandle ) const = &Mesh::is_boundary;
bool (Mesh::*is_boundary_vh)(VertexHandle ) const = &Mesh::is_boundary;
bool (Mesh::*is_boundary_fh)(FaceHandle, bool) const = &Mesh::is_boundary;
// Generic handle derefertiation
const typename Mesh::Vertex& (Mesh::*deref_vh)(VertexHandle ) const = &Mesh::deref;
const typename Mesh::Halfedge& (Mesh::*deref_hh)(HalfedgeHandle) const = &Mesh::deref;
const typename Mesh::Edge& (Mesh::*deref_eh)(EdgeHandle ) const = &Mesh::deref;
const typename Mesh::Face& (Mesh::*deref_fh)(FaceHandle ) const = &Mesh::deref;
//======================================================================
// PolyMeshT Function Pointers
//======================================================================
void (Mesh::*calc_edge_vector_eh_normal)(EdgeHandle, Normal&) const = &Mesh::calc_edge_vector;
void (Mesh::*calc_edge_vector_hh_normal)(HalfedgeHandle, Normal&) const = &Mesh::calc_edge_vector;
Normal (Mesh::*calc_edge_vector_eh)(EdgeHandle ) const = &Mesh::calc_edge_vector;
Normal (Mesh::*calc_edge_vector_hh)(HalfedgeHandle) const = &Mesh::calc_edge_vector;
Scalar (Mesh::*calc_edge_length_eh)(EdgeHandle ) const = &Mesh::calc_edge_length;
Scalar (Mesh::*calc_edge_length_hh)(HalfedgeHandle) const = &Mesh::calc_edge_length;
Scalar (Mesh::*calc_edge_sqr_length_eh)(EdgeHandle ) const = &Mesh::calc_edge_sqr_length;
Scalar (Mesh::*calc_edge_sqr_length_hh)(HalfedgeHandle) const = &Mesh::calc_edge_sqr_length;
Scalar (Mesh::*calc_dihedral_angle_fast_hh)(HalfedgeHandle) const = &Mesh::calc_dihedral_angle_fast;
Scalar (Mesh::*calc_dihedral_angle_fast_eh)(EdgeHandle ) const = &Mesh::calc_dihedral_angle_fast;
Scalar (Mesh::*calc_dihedral_angle_hh)(HalfedgeHandle) const = &Mesh::calc_dihedral_angle;
Scalar (Mesh::*calc_dihedral_angle_eh)(EdgeHandle ) const = &Mesh::calc_dihedral_angle;
unsigned int (Mesh::*find_feature_edges)(Scalar) = &Mesh::find_feature_edges;
void (Mesh::*split_fh_vh)(FaceHandle, VertexHandle) = &Mesh::split;
void (Mesh::*split_eh_vh)(EdgeHandle, VertexHandle) = &Mesh::split;
void (Mesh::*update_normal_fh)(FaceHandle ) = &Mesh::update_normal;
void (Mesh::*update_normal_hh)(HalfedgeHandle, double) = &Mesh::update_normal;
void (Mesh::*update_normal_vh)(VertexHandle ) = &Mesh::update_normal;
void (Mesh::*update_halfedge_normals)(double) = &Mesh::update_halfedge_normals;
Normal (Mesh::*calc_face_normal )(FaceHandle ) const = &Mesh::calc_face_normal;
Normal (Mesh::*calc_halfedge_normal)(HalfedgeHandle, double) const = &Mesh::calc_halfedge_normal;
void (Mesh::*calc_face_centroid_fh_point)(FaceHandle, Point&) const = &Mesh::calc_face_centroid;
Point (Mesh::*calc_face_centroid_fh )(FaceHandle ) const = &Mesh::calc_face_centroid;
//======================================================================
// Mesh Type
//======================================================================
class_<Mesh> class_mesh(_name);
class_mesh
//======================================================================
// KernelT
//======================================================================
.def("reserve", &Mesh::reserve)
.def("vertex", vertex, return_value_policy<reference_existing_object>())
.def("halfedge", halfedge, return_value_policy<reference_existing_object>())
.def("edge", edge, return_value_policy<reference_existing_object>())
.def("face", face, return_value_policy<reference_existing_object>())
.def("handle", handle_v)
.def("handle", handle_h)
.def("handle", handle_e)
.def("handle", handle_f)
.def("vertex_handle", vertex_handle_uint)
.def("halfedge_handle", halfedge_handle_uint)
.def("edge_handle", edge_handle_uint)
.def("face_handle", face_handle_uint)
.def("clear", &Mesh::clear)
.def("clean", &Mesh::clean)
.def("garbage_collection", garbage_collection_bools, garbage_collection_overloads())
.def("garbage_collection", garbage_collection_lists_bools)
.def("n_vertices", &Mesh::n_vertices)
.def("n_halfedges", &Mesh::n_halfedges)
.def("n_edges", &Mesh::n_edges)
.def("n_faces", &Mesh::n_faces)
.def("vertices_empty", &Mesh::vertices_empty)
.def("halfedges_empty", &Mesh::halfedges_empty)
.def("edges_empty", &Mesh::edges_empty)
.def("faces_empty", &Mesh::faces_empty)
.def("halfedge_handle", halfedge_handle_vh)
.def("set_halfedge_handle", set_halfedge_handle_vh_hh)
.def("to_vertex_handle", &Mesh::to_vertex_handle)
.def("from_vertex_handle", &Mesh::from_vertex_handle)
.def("set_vertex_handle", &Mesh::set_vertex_handle)
.def("face_handle", face_handle_hh)
.def("set_face_handle", &Mesh::set_face_handle)
.def("next_halfedge_handle", &Mesh::next_halfedge_handle)
.def("set_next_halfedge_handle", &Mesh::set_next_halfedge_handle)
.def("prev_halfedge_handle", prev_halfedge_handle_hh)
.def("opposite_halfedge_handle", &Mesh::opposite_halfedge_handle)
.def("ccw_rotated_halfedge_handle", &Mesh::ccw_rotated_halfedge_handle)
.def("cw_rotated_halfedge_handle", &Mesh::cw_rotated_halfedge_handle)
.def("edge_handle", edge_handle_hh)
.def("halfedge_handle", halfedge_handle_eh_uint)
.def("halfedge_handle", halfedge_handle_fh)
.def("set_halfedge_handle", set_halfedge_handle_fh_hh)
.def("point", point_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_point", &Mesh::set_point)
.def("normal", normal_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_normal", set_normal_vh)
.def("normal", normal_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_normal", set_normal_hh)
.def("color", color_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color", set_color_vh)
.def("texcoord1D", texcoord1D_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord1D", set_texcoord1D_vh)
.def("texcoord2D", texcoord2D_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord2D", set_texcoord2D_vh)
.def("texcoord3D", texcoord3D_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord3D", set_texcoord3D_vh)
.def("texcoord1D", texcoord1D_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord1D", set_texcoord1D_hh)
.def("texcoord2D", texcoord2D_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord2D", set_texcoord2D_hh)
.def("texcoord3D", texcoord3D_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_texcoord3D", set_texcoord3D_hh)
.def("status", status_vh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_vh)
.def("status", status_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_hh)
.def("color", color_hh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color", set_color_hh)
.def("color", color_eh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color", set_color_eh)
.def("status", status_eh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_eh)
.def("normal", normal_fh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_normal", set_normal_fh)
.def("color", color_fh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_color", set_color_fh)
.def("status", status_fh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_status", set_status_fh)
.def("request_vertex_normals", &Mesh::request_vertex_normals)
.def("request_vertex_colors", &Mesh::request_vertex_colors)
.def("request_vertex_texcoords1D", &Mesh::request_vertex_texcoords1D)
.def("request_vertex_texcoords2D", &Mesh::request_vertex_texcoords2D)
.def("request_vertex_texcoords3D", &Mesh::request_vertex_texcoords3D)
.def("request_vertex_status", &Mesh::request_vertex_status)
.def("request_halfedge_status", &Mesh::request_halfedge_status)
.def("request_halfedge_normals", &Mesh::request_halfedge_normals)
.def("request_halfedge_colors", &Mesh::request_halfedge_colors)
.def("request_halfedge_texcoords1D", &Mesh::request_halfedge_texcoords1D)
.def("request_halfedge_texcoords2D", &Mesh::request_halfedge_texcoords2D)
.def("request_halfedge_texcoords3D", &Mesh::request_halfedge_texcoords3D)
.def("request_edge_status", &Mesh::request_edge_status)
.def("request_edge_colors", &Mesh::request_edge_colors)
.def("request_face_normals", &Mesh::request_face_normals)
.def("request_face_colors", &Mesh::request_face_colors)
.def("request_face_status", &Mesh::request_face_status)
.def("request_face_texture_index", &Mesh::request_face_texture_index)
.def("release_vertex_normals", &Mesh::release_vertex_normals)
.def("release_vertex_colors", &Mesh::release_vertex_colors)
.def("release_vertex_texcoords1D", &Mesh::release_vertex_texcoords1D)
.def("release_vertex_texcoords2D", &Mesh::release_vertex_texcoords2D)
.def("release_vertex_texcoords3D", &Mesh::release_vertex_texcoords3D)
.def("release_vertex_status", &Mesh::release_vertex_status)
.def("release_halfedge_status", &Mesh::release_halfedge_status)
.def("release_halfedge_normals", &Mesh::release_halfedge_normals)
.def("release_halfedge_colors", &Mesh::release_halfedge_colors)
.def("release_halfedge_texcoords1D", &Mesh::release_halfedge_texcoords1D)
.def("release_halfedge_texcoords2D", &Mesh::release_halfedge_texcoords2D)
.def("release_halfedge_texcoords3D", &Mesh::release_halfedge_texcoords3D)
.def("release_edge_status", &Mesh::release_edge_status)
.def("release_edge_colors", &Mesh::release_edge_colors)
.def("release_face_normals", &Mesh::release_face_normals)
.def("release_face_colors", &Mesh::release_face_colors)
.def("release_face_status", &Mesh::release_face_status)
.def("release_face_texture_index", &Mesh::release_face_texture_index)
.def("has_vertex_normals", &Mesh::has_vertex_normals)
.def("has_vertex_colors", &Mesh::has_vertex_colors)
.def("has_vertex_texcoords1D", &Mesh::has_vertex_texcoords1D)
.def("has_vertex_texcoords2D", &Mesh::has_vertex_texcoords2D)
.def("has_vertex_texcoords3D", &Mesh::has_vertex_texcoords3D)
.def("has_vertex_status", &Mesh::has_vertex_status)
.def("has_halfedge_status", &Mesh::has_halfedge_status)
.def("has_halfedge_normals", &Mesh::has_halfedge_normals)
.def("has_halfedge_colors", &Mesh::has_halfedge_colors)
.def("has_halfedge_texcoords1D", &Mesh::has_halfedge_texcoords1D)
.def("has_halfedge_texcoords2D", &Mesh::has_halfedge_texcoords2D)
.def("has_halfedge_texcoords3D", &Mesh::has_halfedge_texcoords3D)
.def("has_edge_status", &Mesh::has_edge_status)
.def("has_edge_colors", &Mesh::has_edge_colors)
.def("has_face_normals", &Mesh::has_face_normals)
.def("has_face_colors", &Mesh::has_face_colors)
.def("has_face_status", &Mesh::has_face_status)
.def("has_face_texture_index", &Mesh::has_face_texture_index)
.def("add_property", add_property_vph, add_property_overloads())
.def("add_property", add_property_eph, add_property_overloads())
.def("add_property", add_property_hph, add_property_overloads())
.def("add_property", add_property_fph, add_property_overloads())
.def("add_property", add_property_mph, add_property_overloads())
.def("remove_property", remove_property_vph)
.def("remove_property", remove_property_eph)
.def("remove_property", remove_property_hph)
.def("remove_property", remove_property_fph)
.def("remove_property", remove_property_mph)
.def("get_property_handle", get_property_handle_vph)
.def("get_property_handle", get_property_handle_eph)
.def("get_property_handle", get_property_handle_hph)
.def("get_property_handle", get_property_handle_fph)
.def("get_property_handle", get_property_handle_mph)
.def("property", property_vertex, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("property", property_edge, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("property", property_halfedge, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("property", property_face, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("property", property_mesh, OPENMESH_PYTHON_DEFAULT_POLICY)
.def("set_property", set_property_vertex)
.def("set_property", set_property_edge)
.def("set_property", set_property_halfedge)
.def("set_property", set_property_face)
.def("set_property", set_property_mesh)
.def("new_vertex", new_vertex_void)
.def("new_vertex", new_vertex_point)
.def("new_edge", &Mesh::new_edge)
.def("new_face", new_face_void)
.def("new_face", new_face_face)
.def("vertices", vertices)
.def("halfedges", halfedges)
.def("edges", edges)
.def("faces", faces)
.def("svertices", svertices)
.def("shalfedges", shalfedges)
.def("sedges", sedges)
.def("sfaces", sfaces)
//======================================================================
// BaseKernel
//======================================================================
.def("copy_property", copy_property_vprop)
.def("copy_property", copy_property_hprop)
.def("copy_property", copy_property_eprop)
.def("copy_property", copy_property_fprop)
.def("copy_all_properties", copy_all_properties_vh_vh_bool, copy_all_properties_overloads())
.def("copy_all_properties", copy_all_properties_hh_hh_bool, copy_all_properties_overloads())
.def("copy_all_properties", copy_all_properties_eh_eh_bool, copy_all_properties_overloads())
.def("copy_all_properties", copy_all_properties_fh_fh_bool, copy_all_properties_overloads())
//======================================================================
// PolyConnectivity
//======================================================================
.def("assign_connectivity", assign_connectivity_poly)
.def("assign_connectivity", assign_connectivity_tri)
.def("opposite_face_handle", &Mesh::opposite_face_handle)
.def("adjust_outgoing_halfedge", &Mesh::adjust_outgoing_halfedge)
.def("find_halfedge", &Mesh::find_halfedge)
.def("valence", valence_vh)
.def("valence", valence_fh)
.def("collapse", &Mesh::collapse)
.def("is_simple_link", &Mesh::is_simple_link)
.def("is_simply_connected", &Mesh::is_simply_connected)
.def("remove_edge", &Mesh::remove_edge)
.def("reinsert_edge", &Mesh::reinsert_edge)
.def("triangulate", triangulate_fh)
.def("triangulate", triangulate_void)
.def("split_edge", &Mesh::split_edge)
.def("split_edge_copy", &Mesh::split_edge_copy)
.def("add_vertex", &Mesh::add_vertex)
.def("is_collapse_ok", &Mesh::is_collapse_ok)
.def("delete_vertex", delete_vertex, delete_vertex_overloads())
.def("delete_edge", delete_edge, delete_edge_overloads())
.def("delete_face", delete_face, delete_face_overloads())
.def("vv", vv)
.def("vih", vih)
.def("voh", voh)
.def("ve", ve)
.def("vf", vf)
.def("fv", fv)
.def("fh", fh)
.def("fe", fe)
.def("ff", ff)
.def("hl", hl)
.def("is_boundary", is_boundary_hh)
.def("is_boundary", is_boundary_eh)
.def("is_boundary", is_boundary_vh)
.def("is_boundary", is_boundary_fh, is_boundary_overloads())
.def("is_manifold", &Mesh::is_manifold)
.def("deref", deref_vh, return_value_policy<reference_existing_object>())
.def("deref", deref_hh, return_value_policy<reference_existing_object>())
.def("deref", deref_eh, return_value_policy<reference_existing_object>())
.def("deref", deref_fh, return_value_policy<reference_existing_object>())
.def("is_triangles", &Mesh::is_triangles)
.staticmethod("is_triangles")
.def_readonly("InvalidVertexHandle", &Mesh::InvalidVertexHandle)
.def_readonly("InvalidHalfedgeHandle", &Mesh::InvalidHalfedgeHandle)
.def_readonly("InvalidEdgeHandle", &Mesh::InvalidEdgeHandle)
.def_readonly("InvalidFaceHandle", &Mesh::InvalidFaceHandle)
//======================================================================
// PolyMeshT
//======================================================================
.def("add_vertex", &Mesh::add_vertex)
.def("calc_edge_vector", calc_edge_vector_eh_normal)
.def("calc_edge_vector", calc_edge_vector_eh)
.def("calc_edge_vector", calc_edge_vector_hh_normal)
.def("calc_edge_vector", calc_edge_vector_hh)
.def("calc_edge_length", calc_edge_length_eh)
.def("calc_edge_length", calc_edge_length_hh)
.def("calc_edge_sqr_length", calc_edge_sqr_length_eh)
.def("calc_edge_sqr_length", calc_edge_sqr_length_hh)
.def("calc_sector_vectors", &Mesh::calc_sector_vectors)
.def("calc_sector_angle", &Mesh::calc_sector_angle)
.def("calc_sector_normal", &Mesh::calc_sector_normal)
.def("calc_sector_area", &Mesh::calc_sector_area)
.def("calc_dihedral_angle_fast", calc_dihedral_angle_fast_hh)
.def("calc_dihedral_angle_fast", calc_dihedral_angle_fast_eh)
.def("calc_dihedral_angle", calc_dihedral_angle_hh)
.def("calc_dihedral_angle", calc_dihedral_angle_eh)
.def("find_feature_edges", find_feature_edges, find_feature_edges_overloads())
.def("split", split_fh_vh)
.def("split", split_eh_vh)
.def("update_normals", &Mesh::update_normals)
.def("update_normal", update_normal_fh)
.def("update_face_normals", &Mesh::update_face_normals)
.def("calc_face_normal", calc_face_normal)
.def("calc_face_centroid", calc_face_centroid_fh_point)
.def("calc_face_centroid", calc_face_centroid_fh)
.def("update_normal", update_normal_hh, update_normal_overloads())
.def("update_halfedge_normals", update_halfedge_normals, update_halfedge_normals_overloads())
.def("calc_halfedge_normal", calc_halfedge_normal, calc_halfedge_normal_overloads())
.def("is_estimated_feature_edge", &Mesh::is_estimated_feature_edge)
.def("update_normal", update_normal_vh)
.def("update_vertex_normals", &Mesh::update_vertex_normals)
.def("calc_vertex_normal", &Mesh::calc_vertex_normal)
.def("calc_vertex_normal_fast", &Mesh::calc_vertex_normal_fast)
.def("calc_vertex_normal_correct", &Mesh::calc_vertex_normal_correct)
.def("calc_vertex_normal_loop", &Mesh::calc_vertex_normal_loop)
.def("is_polymesh", &Mesh::is_polymesh)
.staticmethod("is_polymesh")
.def("is_trimesh", &Mesh::is_trimesh)
.staticmethod("is_trimesh")
;
expose_type_specific_functions(class_mesh);
//======================================================================
// Nested Types
//======================================================================
// Enter mesh scope
scope scope_mesh = class_mesh;
// Point
const boost::python::type_info point_info = type_id<typename Mesh::Point>();
const converter::registration * point_registration = converter::registry::query(point_info);
scope_mesh.attr("Point") = handle<>(point_registration->m_class_object);
// Normal
const boost::python::type_info normal_info = type_id<typename Mesh::Normal>();
const converter::registration * normal_registration = converter::registry::query(normal_info);
scope_mesh.attr("Normal") = handle<>(normal_registration->m_class_object);
// Color
const boost::python::type_info color_info = type_id<typename Mesh::Color>();
const converter::registration * color_registration = converter::registry::query(color_info);
scope_mesh.attr("Color") = handle<>(color_registration->m_class_object);
// TexCoord2D
const boost::python::type_info texcoord2d_info = type_id<typename Mesh::TexCoord2D>();
const converter::registration * texcoord2d_registration = converter::registry::query(texcoord2d_info);
scope_mesh.attr("TexCoord2D") = handle<>(texcoord2d_registration->m_class_object);
// TexCoord3D
const boost::python::type_info texcoord3d_info = type_id<typename Mesh::TexCoord3D>();
const converter::registration * texcoord3d_registration = converter::registry::query(texcoord3d_info);
scope_mesh.attr("TexCoord3D") = handle<>(texcoord3d_registration->m_class_object);
}
} // namespace OpenMesh
} // namespace Python
#endif

View File

@@ -1,143 +0,0 @@
#ifndef OPENMESH_PYTHON_PROPERTYMANAGER_HH
#define OPENMESH_PYTHON_PROPERTYMANAGER_HH
#include "Python/Bindings.hh"
#include "OpenMesh/Core/Utils/PropertyManager.hh"
namespace OpenMesh {
namespace Python {
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(retain_overloads, retain, 0, 1)
/**
* Implementation of %Python's \_\_getitem\_\_ magic method.
*
* @tparam PropertyManager A property manager type.
* @tparam IndexHandle The appropriate handle type.
*
* @param _self The property manager instance that is to be used.
* @param _handle The index of the property value to be returned.
*
* @return The requested property value.
*/
template <class PropertyManager, class IndexHandle>
object propman_get_item(PropertyManager& _self, IndexHandle _handle) {
return _self[_handle];
}
/**
* Implementation of %Python's \_\_setitem\_\_ magic method.
*
* @tparam PropertyManager A property manager type.
* @tparam IndexHandle The appropriate handle type.
*
* @param _self The property manager instance that is to be used.
* @param _handle The index of the property value to be set.
* @param _value The property value to be set.
*/
template <class PropertyManager, class IndexHandle>
void propman_set_item(PropertyManager& _self, IndexHandle _handle, object _value) {
_self[_handle] = _value;
}
/**
* Conveniently set the property value for an entire range of mesh items
* using a %Python iterator.
*
* @tparam PropertyManager A property manager type.
* @tparam Iterator A %Python iterator type.
*
* @param _self The property manager instance that is to be used.
* @param _it An iterator that iterates over the items in the range.
* @param _value The value the range will be set to.
*/
template <class PropertyManager, class Iterator>
void propman_set_range(PropertyManager& _self, Iterator _it, object _value) {
try {
while (true) {
_self[_it.next()] = _value;
}
}
catch (error_already_set exception) {
// This is expected behavior
PyErr_Clear();
}
}
/**
* Thin wrapper for propertyExists.
*
* @tparam PropertyManager A property manager type.
* @tparam Mesh A mesh type.
*
* @param _mesh The mesh that is used to check if the property exists.
* @param _propname The name of the property.
*/
template <class PropertyManager, class Mesh>
bool property_exists(Mesh& _mesh, const char *_propname) {
return PropertyManager::propertyExists(_mesh, _propname);
}
/**
* Expose a property manager type to %Python.
*
* This function template is used to expose property managers to %Python. The
* template parameters are used to instantiate the appropriate property manager
* type.
*
* @tparam PropHandle A property handle type (e.g. %VPropHandle\<object\>).
* @tparam IndexHandle The appropriate handle type (e.g. %VertexHandle for
* %VPropHandle\<object\>).
* @tparam Iterator A %Python iterator type. This type is used to instantiate
* the propman_set_range function.
*
* @param _name The name of the property manager type to be exposed.
*/
template <class PropHandle, class IndexHandle, class Iterator>
void expose_property_manager(const char *_name) {
// Convenience typedef
typedef PropertyManager<PropHandle, PolyConnectivity> PropertyManager;
// Function pointers
void (PropertyManager::*retain)(bool) = &PropertyManager::retain;
object (*getitem)(PropertyManager&, IndexHandle ) = &propman_get_item;
void (*setitem)(PropertyManager&, IndexHandle, object) = &propman_set_item;
void (*set_range)(PropertyManager&, Iterator, object) = &propman_set_range;
bool (*property_exists_poly)(PolyMesh&, const char *) = &property_exists<PropertyManager, PolyMesh>;
bool (*property_exists_tri )(TriMesh&, const char *) = &property_exists<PropertyManager, TriMesh >;
// Expose property manager
class_<PropertyManager, boost::noncopyable>(_name)
.def(init<PolyMesh&, const char *, optional<bool> >()[with_custodian_and_ward<1,2>()])
.def(init<TriMesh&, const char *, optional<bool> >()[with_custodian_and_ward<1,2>()])
.def("swap", &PropertyManager::swap)
.def("is_valid", &PropertyManager::isValid)
.def("__bool__", &PropertyManager::operator bool)
.def("__nonzero__", &PropertyManager::operator bool)
.def("get_raw_property", &PropertyManager::getRawProperty, return_value_policy<copy_const_reference>())
.def("get_name", &PropertyManager::getName, return_value_policy<copy_const_reference>())
.def("get_mesh", &PropertyManager::getMesh, return_value_policy<reference_existing_object>())
.def("retain", retain, retain_overloads())
.def("__getitem__", getitem)
.def("__setitem__", setitem)
.def("set_range", set_range)
.def("property_exists", property_exists_poly)
.def("property_exists", property_exists_tri)
.staticmethod("property_exists")
;
}
} // namespace OpenMesh
} // namespace Python
#endif

View File

@@ -1,334 +0,0 @@
import unittest
import openmesh
class AddFace(unittest.TestCase):
def test_add_triangles_to_trimesh(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
# Check setup
self.assertEqual(self.mesh.n_vertices(), 4)
self.assertEqual(self.mesh.n_faces(), 2)
def test_add_quad_to_trimesh(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
# Check setup
self.assertEqual(self.mesh.n_vertices(), 4)
self.assertEqual(self.mesh.n_faces(), 2)
def test_create_triangle_mesh_cube(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
def test_create_strange_config(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# 2 x-----------x 1
# \ /
# \ /
# \ /
# \ /
# \ /
# 0 x ---x 6
# /|\ |
# / | \ |
# / | \ |
# / | \|
# x----x x
# 3 4 5
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 2, 2)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 3, 3)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 4, 4)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(5, 5, 5)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(6, 6, 6)))
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[5], self.vhandle[6])
# non-manifold!
invalid_fh = self.mesh.add_face(self.vhandle[3], self.vhandle[0], self.vhandle[4])
# Check setup
self.assertEqual(self.mesh.n_vertices(), 7)
self.assertEqual(self.mesh.n_faces(), 3)
self.assertEqual(invalid_fh, openmesh.TriMesh.InvalidFaceHandle)
def test_add_quad_to_polymesh(self):
self.mesh = openmesh.PolyMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add one face
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | |
# | |
# | |
# 0 === 3
# Check setup
self.assertEqual(self.mesh.n_vertices(), 4)
self.assertEqual(self.mesh.n_faces(), 1)
def test_create_poly_mesh_cube(self):
self.mesh = openmesh.PolyMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 12)
self.assertEqual(self.mesh.n_halfedges(), 24)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(AddFace)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,86 +0,0 @@
import unittest
import openmesh
class BoundaryTriangleMesh(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
# Single point
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-2, 0)))
# Add five faces
self.fhandle = []
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.fhandle.append(self.mesh.add_face(face_vhandles))
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.fhandle.append(self.mesh.add_face(face_vhandles))
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
self.fhandle.append(self.mesh.add_face(face_vhandles))
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
self.fhandle.append(self.mesh.add_face(face_vhandles))
face_vhandles = []
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[4])
self.fhandle.append(self.mesh.add_face(face_vhandles))
# Test setup:
# 0 ==== 2
# |\ 0 /|\
# | \ / | \
# |2 1 3|4 5
# | / \ | /
# |/ 1 \|/
# 3 ==== 4
#
# Vertex 6 single
def test_boundary_vertex(self):
self.assertTrue (self.mesh.is_boundary(self.vhandle[0]))
self.assertFalse(self.mesh.is_boundary(self.vhandle[1]))
self.assertTrue (self.mesh.is_boundary(self.vhandle[2]))
self.assertTrue (self.mesh.is_boundary(self.vhandle[3]))
self.assertTrue (self.mesh.is_boundary(self.vhandle[4]))
self.assertTrue (self.mesh.is_boundary(self.vhandle[5]))
self.assertTrue (self.mesh.is_boundary(self.vhandle[6]))
def test_boundary_face(self):
self.assertTrue (self.mesh.is_boundary(self.fhandle[0]))
self.assertTrue (self.mesh.is_boundary(self.fhandle[1]))
self.assertTrue (self.mesh.is_boundary(self.fhandle[2]))
self.assertFalse(self.mesh.is_boundary(self.fhandle[3]))
self.assertTrue (self.mesh.is_boundary(self.fhandle[4]))
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(BoundaryTriangleMesh)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,530 +0,0 @@
import unittest
import openmesh
class DeleteFaceTriangleMesh(unittest.TestCase):
def test_delete_half_triangle_mesh_cube_no_edge_status(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# =====================================================
# Now we delete half of the mesh
# =====================================================
self.mesh.request_face_status()
self.mesh.request_vertex_status()
self.mesh.request_halfedge_status()
n_face_to_delete = self.mesh.n_faces() / 2
# Check the variable
self.assertEqual(n_face_to_delete, 6)
for i in range(int(n_face_to_delete)):
self.mesh.delete_face(self.mesh.face_handle(i))
# =====================================================
# Check config afterwards
# =====================================================
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# =====================================================
# Cleanup and recheck
# =====================================================
self.mesh.garbage_collection()
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
def test_delete_half_triangle_mesh_cube_with_edge_status(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
#=======================
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# =====================================================
# Now we delete half of the mesh
# =====================================================
self.mesh.request_face_status()
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_halfedge_status()
n_face_to_delete = self.mesh.n_faces() / 2
# Check the variable
self.assertEqual(n_face_to_delete, 6)
for i in range(int(n_face_to_delete)):
self.mesh.delete_face(self.mesh.face_handle(i))
# =====================================================
# Check config afterwards
# =====================================================
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# =====================================================
# Cleanup and recheck
# =====================================================
self.mesh.garbage_collection()
self.assertEqual(self.mesh.n_edges(), 13)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
def test_deletete_half_poly_mesh_cube_without_edge_status(self):
self.mesh = openmesh.PolyMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 12)
self.assertEqual(self.mesh.n_halfedges(), 24)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
# =====================================================
# Now we delete half of the mesh
# =====================================================
self.mesh.request_face_status()
self.mesh.request_vertex_status()
self.mesh.request_halfedge_status()
n_face_to_delete = self.mesh.n_faces() / 2
# Check the variable
self.assertEqual(n_face_to_delete, 3)
for i in range(int(n_face_to_delete)):
self.mesh.delete_face(self.mesh.face_handle(i))
# =====================================================
# Check config afterwards
# =====================================================
self.assertEqual(self.mesh.n_edges(), 12)
self.assertEqual(self.mesh.n_halfedges(), 24)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
# =====================================================
# Cleanup and recheck
# =====================================================
self.mesh.garbage_collection()
self.assertEqual(self.mesh.n_edges(), 12)
self.assertEqual(self.mesh.n_halfedges(), 24)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 3)
def test_deletete_half_poly_mesh_cube_with_edge_status(self):
self.mesh = openmesh.PolyMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[5])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[6])
face_vhandles.append(self.vhandle[7])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[7])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 12)
self.assertEqual(self.mesh.n_halfedges(), 24)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
# =====================================================
# Now we delete half of the mesh
# =====================================================
self.mesh.request_face_status()
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_halfedge_status()
n_face_to_delete = self.mesh.n_faces() / 2
# Check the variable
self.assertEqual(n_face_to_delete, 3)
for i in range(int(n_face_to_delete)):
self.mesh.delete_face(self.mesh.face_handle(i))
# =====================================================
# Check config afterwards
# =====================================================
self.assertEqual(self.mesh.n_edges(), 12)
self.assertEqual(self.mesh.n_halfedges(), 24)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 6)
# =====================================================
# Cleanup and recheck
# =====================================================
self.mesh.garbage_collection()
self.assertEqual(self.mesh.n_edges(), 10)
self.assertEqual(self.mesh.n_halfedges(), 20)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 3)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(DeleteFaceTriangleMesh)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,289 +0,0 @@
import unittest
import openmesh
class Property(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_vertex_property_copy_properties_int(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
# Check setup
self.assertEqual(self.mesh.n_vertices(), 4)
self.assertEqual(self.mesh.n_faces(), 2)
# Add a vertex property
intHandle = openmesh.VPropHandle()
self.assertFalse(self.mesh.get_property_handle(intHandle, "intProp"))
self.mesh.add_property(intHandle, "intProp")
self.assertTrue(self.mesh.get_property_handle(intHandle, "intProp"))
# Fill property
for vh in self.mesh.vertices():
self.mesh.set_property(intHandle, vh, vh.idx())
# Check if property it is ok
v_it = self.mesh.vertices()
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 0)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3)
# Check vertex positions
v_it = self.mesh.vertices()
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
# Copy from vertex 1 to 0, with skipping build in properties
self.mesh.copy_all_properties(self.vhandle[1], self.vhandle[0])
v_it = self.mesh.vertices()
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
v_it = self.mesh.vertices()
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3)
# Copy from vertex 2 to 3, including build in properties
self.mesh.copy_all_properties(self.vhandle[2], self.vhandle[3], True)
v_it = self.mesh.vertices()
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
v_it = self.mesh.vertices()
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
def test_check_status_properties_halfedge_edge_all_deleted(self):
self.mesh.request_vertex_status()
self.mesh.request_face_status()
self.mesh.request_halfedge_status()
self.mesh.request_edge_status()
# Define positions
p1 = openmesh.Vec3d(0, 0, 0)
p2 = openmesh.Vec3d(0, 1, 0)
p3 = openmesh.Vec3d(1, 1, 0)
p4 = openmesh.Vec3d(0, 0, 1)
# Add some vertices
vh1 = self.mesh.add_vertex(p1)
vh2 = self.mesh.add_vertex(p2)
vh3 = self.mesh.add_vertex(p3)
vh4 = self.mesh.add_vertex(p4)
# Add some faces
f1 = self.mesh.add_face(vh1, vh3, vh2)
f2 = self.mesh.add_face(vh1, vh2, vh4)
f3 = self.mesh.add_face(vh2, vh3, vh4)
f4 = self.mesh.add_face(vh3, vh1, vh4)
# Delete all faces
self.mesh.delete_face(f1)
self.mesh.delete_face(f2)
self.mesh.delete_face(f3)
self.mesh.delete_face(f4)
for heh in self.mesh.halfedges():
self.assertTrue(self.mesh.status(self.mesh.edge_handle(heh)).deleted())
self.assertTrue(self.mesh.status(heh).deleted())
def test_copy_all_properties_vertex_after_remove_of_property(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
# Check setup
self.assertEqual(self.mesh.n_vertices(), 4)
self.assertEqual(self.mesh.n_faces(), 2)
# Add a double vertex property
doubleHandle = openmesh.VPropHandle()
self.assertFalse(self.mesh.get_property_handle(doubleHandle, "doubleProp"))
self.mesh.add_property(doubleHandle, "doubleProp")
self.assertTrue(self.mesh.get_property_handle(doubleHandle, "doubleProp"))
# Add a int vertex property
intHandle = openmesh.VPropHandle()
self.assertFalse(self.mesh.get_property_handle(intHandle, "intProp"))
self.mesh.add_property(intHandle, "intProp")
self.assertTrue(self.mesh.get_property_handle(intHandle, "intProp"))
# Now remove the double property again
self.mesh.remove_property(doubleHandle)
# Fill int property
for vh in self.mesh.vertices():
self.mesh.set_property(intHandle, vh, vh.idx())
# Check if property it is ok
v_it = self.mesh.vertices()
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 0)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3)
# Check vertex positions
v_it = self.mesh.vertices()
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
# Copy from vertex 1 to 0, with skipping build in properties
self.mesh.copy_all_properties(self.vhandle[1], self.vhandle[0])
v_it = self.mesh.vertices()
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
v_it = self.mesh.vertices()
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 3)
# Copy from vertex 2 to 3, including build in properties
self.mesh.copy_all_properties(self.vhandle[2], self.vhandle[3], True)
v_it = self.mesh.vertices()
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 0)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 0)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
vh = v_it.next()
self.assertEqual(self.mesh.point(vh)[0], 1)
self.assertEqual(self.mesh.point(vh)[1], 1)
self.assertEqual(self.mesh.point(vh)[2], 0)
v_it = self.mesh.vertices()
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 1)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
self.assertEqual(self.mesh.property(intHandle, v_it.next()), 2)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(Property)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,71 +0,0 @@
import unittest
import openmesh
class Python(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces using Python lists
vertex_list = [self.vhandle[0], self.vhandle[1], self.vhandle[2]]
self.mesh.add_face(vertex_list)
vertex_list = [self.vhandle[1], self.vhandle[3], self.vhandle[4]]
self.mesh.add_face(vertex_list)
vertex_list = [self.vhandle[0], self.vhandle[3], self.vhandle[1]]
self.mesh.add_face(vertex_list)
vertex_list = [self.vhandle[2], self.vhandle[1], self.vhandle[4]]
self.mesh.add_face(vertex_list)
# Test setup:
# 0 ==== 2
# |\ 0 /|
# | \ / |
# |2 1 3|
# | / \ |
# |/ 1 \|
# 3 ==== 4
def test_python_iterator(self):
# Iterate over all vertices
indices = [0, 1, 2, 3, 4]
for v, idx in zip(self.mesh.vertices(), indices):
self.assertEqual(v.idx(), idx)
def test_python_circulator(self):
# Iterate around vertex 1 at the middle
indices = [4, 3, 0, 2]
for v, idx in zip(self.mesh.vv(self.vhandle[1]), indices):
self.assertEqual(v.idx(), idx)
def test_property_manager(self):
# Check if vertex property exists
self.assertFalse(openmesh.VPropertyManager.property_exists(self.mesh, "prop"))
# Create a new vertex property
propman = openmesh.VPropertyManager(self.mesh, "prop")
self.assertTrue(propman.property_exists(self.mesh, "prop"))
# Check initial property values
for v in self.mesh.vertices():
self.assertEqual(propman[v], None)
# Set property values
propman.set_range(self.mesh.vertices(), 0.0)
# Check again
for v in self.mesh.vertices():
self.assertEqual(propman[v], 0.0)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(Python)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,229 +0,0 @@
import unittest
import openmesh
class ReadWriteOBJ(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
def test_load_simple_obj(self):
ok = openmesh.read_mesh(self.mesh, "cube-minimal.obj")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
def test_load_simple_obj_check_halfedge_and_vertex_normals(self):
self.mesh.request_halfedge_normals()
self.mesh.request_vertex_normals()
options = openmesh.Options()
options += openmesh.Options.VertexNormal
file_name = "cube-minimal.obj"
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.n_halfedges(), 36)
# =====================================================
# Check vertex normals
# =====================================================
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[1], -1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[1], -1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[2], 1.0)
# =====================================================
# Check halfedge normals
# =====================================================
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle( 0))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle( 0))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle( 0))[2], -1.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(10))[0], -1.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(10))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(10))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(19))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(19))[1], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(19))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(24))[0], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(24))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(24))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(30))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(30))[1], -1.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(30))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(35))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(35))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.halfedge_handle(35))[2], 1.0)
self.mesh.release_vertex_normals()
self.mesh.release_halfedge_normals()
def test_load_simple_obj_force_vertex_colors_although_not_available(self):
self.mesh.request_vertex_colors()
file_name = "cube-minimal.obj"
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.n_halfedges(), 36)
def test_load_simple_obj_check_texcoords(self):
self.mesh.request_halfedge_texcoords2D()
options = openmesh.Options()
options += openmesh.Options.FaceTexCoord
file_name = "cube-minimal-texCoords.obj"
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle( 0))[0], 1.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle( 0))[1], 1.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(10))[0], 3.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(10))[1], 3.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(19))[0], 6.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(19))[1], 6.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(24))[0], 7.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(24))[1], 7.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(30))[0], 9.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(30))[1], 9.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(35))[0], 12.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.halfedge_handle(35))[1], 12.0)
self.mesh.release_halfedge_texcoords2D()
def test_load_obj_with_material(self):
self.mesh.request_face_colors()
options = openmesh.Options()
options += openmesh.Options.FaceColor
file_name = "square_material.obj"
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
fh = self.mesh.face_handle(self.mesh.halfedge_handle(0))
self.assertTrue(fh.is_valid())
self.assertAlmostEqual(self.mesh.color(fh)[0], 0.5, 2)
self.assertAlmostEqual(self.mesh.color(fh)[1], 0.5, 2)
self.assertAlmostEqual(self.mesh.color(fh)[2], 0.5, 2)
self.mesh.release_face_colors()
def test_load_simple_obj_with_vertex_colors_after_vertices(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
file_name = "cube-minimal-vertex-colors-after-vertex-definition.obj"
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.mesh.release_vertex_colors()
def test_load_simple_obj_with_vertex_colors_as_vc_lines(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
file_name = "cube-minimal-vertex-colors-as-vc-lines.obj"
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.mesh.release_vertex_colors()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteOBJ)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,163 +0,0 @@
import unittest
import openmesh
class ReadWriteOFF(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
def test_load_simple_off_file(self):
ok = openmesh.read_mesh(self.mesh, "cube1.off")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 7526)
self.assertEqual(self.mesh.n_edges(), 22572)
self.assertEqual(self.mesh.n_faces(), 15048)
def test_write_and_read_vertex_colors_to_and_from_off_file(self):
self.mesh.request_vertex_colors()
self.mesh.add_vertex(openmesh.Vec3d(0, 0, 1))
self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))
self.mesh.add_vertex(openmesh.Vec3d(0, 1, 1))
self.mesh.add_vertex(openmesh.Vec3d(1, 0, 1))
# Using the default openmesh Python color type
testColor = openmesh.Vec4f(1.0, 0.5, 0.25, 1.0)
# Setting colors (different from black)
for v in self.mesh.vertices():
self.mesh.set_color(v, testColor)
# Check if the colors are correctly set
count = 0
for v in self.mesh.vertices():
color = self.mesh.color(v)
if color[0] != testColor[0] or color[1] != testColor[1] or color[2] != testColor[2]:
count += 1
self.assertEqual(count, 0)
options = openmesh.Options()
options += openmesh.Options.VertexColor
options += openmesh.Options.ColorFloat
openmesh.write_mesh(self.mesh, "temp.off", options)
openmesh.read_mesh(self.mesh, "temp.off", options)
# Check if vertices still have the same color
count = 0
for v in self.mesh.vertices():
color = self.mesh.color(v)
if color[0] != testColor[0] or color[1] != testColor[1] or color[2] != testColor[2]:
count += 1
self.assertEqual(count, 0)
self.mesh.release_vertex_colors()
def test_write_and_read_float_vertex_colors_to_and_from_off_file(self):
self.mesh.request_vertex_colors()
options = openmesh.Options(openmesh.Options.VertexColor)
ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options)
self.assertTrue(ok)
options.clear()
options += openmesh.Options.VertexColor
options += openmesh.Options.ColorFloat
# Write the mesh
ok = openmesh.write_mesh(self.mesh, "cube_floating.off", options)
self.assertTrue(ok)
ok = openmesh.read_mesh(self.mesh, "cube_floating.off", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.assertTrue(options.color_is_float())
self.mesh.release_vertex_colors()
def test_write_and_read_binary_float_vertex_colors_to_and_from_off_file(self):
self.mesh.request_vertex_colors()
options = openmesh.Options(openmesh.Options.VertexColor)
ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options)
self.assertTrue(ok)
options.clear()
options += openmesh.Options.VertexColor
options += openmesh.Options.Binary
options += openmesh.Options.ColorFloat
# Write the mesh
ok = openmesh.write_mesh(self.mesh, "cube_floating_binary.off", options)
self.assertTrue(ok)
self.mesh.clear()
options.clear()
options += openmesh.Options.VertexColor
options += openmesh.Options.Binary
options += openmesh.Options.ColorFloat
ok = openmesh.read_mesh(self.mesh, "cube_floating_binary.off", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertFalse(options.face_has_color())
self.assertTrue(options.vertex_has_color())
self.assertTrue(options.color_is_float())
self.assertTrue(options.is_binary())
self.mesh.release_vertex_colors()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteOFF)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,201 +0,0 @@
import unittest
import openmesh
import os
class ReadWriteOM(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
def test_load_simple_om_force_vertex_colors_although_not_available(self):
self.mesh.request_vertex_colors()
file_name = "cube-minimal.om"
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertFalse(options.vertex_has_color())
def test_load_simple_om_with_texcoords(self):
self.mesh.request_vertex_texcoords2D()
options = openmesh.Options()
options += openmesh.Options.VertexTexCoord
ok = openmesh.read_mesh(self.mesh, "cube-minimal-texCoords.om", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[0], 10.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[1], 10.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[0], 6.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[1], 6.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[0], 9.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[1], 9.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[0], 12.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[1], 12.0)
self.assertFalse(options.vertex_has_normal())
self.assertTrue(options.vertex_has_texcoord())
self.assertFalse(options.vertex_has_color())
self.mesh.release_vertex_texcoords2D()
def test_load_simple_om_with_vertex_colors(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, "cube-minimal-vertexColors.om", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.mesh.release_vertex_colors()
def test_write_triangle(self):
filename = "triangle-minimal.om";
# Generate data
v1 = self.mesh.add_vertex(openmesh.Vec3d(1.0, 0.0, 0.0))
v2 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 1.0, 0.0))
v3 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 0.0, 1.0))
self.mesh.add_face(v1, v2, v3)
# Save
ok = openmesh.write_mesh(self.mesh, filename)
self.assertTrue(ok)
# Reset
self.mesh.clear()
# Load
ok = openmesh.read_mesh(self.mesh, filename)
self.assertTrue(ok)
# Compare
self.assertEqual(self.mesh.n_vertices(), 3)
self.assertEqual(self.mesh.n_edges(), 3)
self.assertEqual(self.mesh.n_faces(), 1)
self.assertEqual(self.mesh.point(v1), openmesh.Vec3d(1.0, 0.0, 0.0))
self.assertEqual(self.mesh.point(v2), openmesh.Vec3d(0.0, 1.0, 0.0))
self.assertEqual(self.mesh.point(v3), openmesh.Vec3d(0.0, 0.0, 1.0))
# Cleanup
os.remove(filename)
def test_write_triangle_vertex_integer_color(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
options += openmesh.Options.ColorFloat
filename = "triangle-minimal-ColorsPerVertex.om"
# Generate data
v1 = self.mesh.add_vertex(openmesh.Vec3d(1.0, 0.0, 0.0))
v2 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 1.0, 0.0))
v3 = self.mesh.add_vertex(openmesh.Vec3d(0.0, 0.0, 1.0))
self.mesh.add_face(v1, v2, v3)
c1 = openmesh.Vec4f(0.00, 0.00, 0.50, 1.00)
c2 = openmesh.Vec4f(0.25, 0.00, 0.00, 1.00)
c3 = openmesh.Vec4f(0.00, 0.75, 0.00, 1.00)
self.mesh.set_color(v1, c1)
self.mesh.set_color(v2, c2)
self.mesh.set_color(v3, c3)
# Save
ok = openmesh.write_mesh(self.mesh, filename, options)
self.assertTrue(ok)
self.mesh.release_vertex_colors()
# Load
cmpMesh = openmesh.TriMesh()
cmpMesh.request_vertex_colors()
ok = openmesh.read_mesh(cmpMesh, filename, options)
self.assertTrue(ok)
self.assertTrue(cmpMesh.has_vertex_colors())
# Compare
self.assertEqual(self.mesh.n_vertices(), 3)
self.assertEqual(self.mesh.n_edges(), 3)
self.assertEqual(self.mesh.n_faces(), 1)
self.assertEqual(cmpMesh.point(v1), openmesh.Vec3d(1.0, 0.0, 0.0))
self.assertEqual(cmpMesh.point(v2), openmesh.Vec3d(0.0, 1.0, 0.0))
self.assertEqual(cmpMesh.point(v3), openmesh.Vec3d(0.0, 0.0, 1.0))
self.assertAlmostEqual(cmpMesh.color(v1)[0], c1[0], 2)
self.assertAlmostEqual(cmpMesh.color(v1)[1], c1[1], 2)
self.assertAlmostEqual(cmpMesh.color(v1)[2], c1[2], 2)
self.assertAlmostEqual(cmpMesh.color(v1)[3], c1[3], 2)
self.assertAlmostEqual(cmpMesh.color(v2)[0], c2[0], 2)
self.assertAlmostEqual(cmpMesh.color(v2)[1], c2[1], 2)
self.assertAlmostEqual(cmpMesh.color(v2)[2], c2[2], 2)
self.assertAlmostEqual(cmpMesh.color(v2)[3], c2[3], 2)
self.assertAlmostEqual(cmpMesh.color(v3)[0], c3[0], 2)
self.assertAlmostEqual(cmpMesh.color(v3)[1], c3[1], 2)
self.assertAlmostEqual(cmpMesh.color(v3)[2], c3[2], 2)
self.assertAlmostEqual(cmpMesh.color(v3)[3], c3[3], 2)
# Clean up
cmpMesh.release_vertex_colors()
os.remove(filename)
# TODO property tests
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteOM)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,342 +0,0 @@
import unittest
import openmesh
class ReadWritePLY(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
def test_load_simple_point_ply_file_with_bad_encoding(self):
ok = openmesh.read_mesh(self.mesh, "pointCloudBadEncoding.ply")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 10)
self.assertEqual(self.mesh.n_edges(), 0)
self.assertEqual(self.mesh.n_faces(), 0)
def test_load_simple_point_ply_file_with_good_encoding(self):
ok = openmesh.read_mesh(self.mesh, "pointCloudGoodEncoding.ply")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 10)
self.assertEqual(self.mesh.n_edges(), 0)
self.assertEqual(self.mesh.n_faces(), 0)
def test_load_simple_ply(self):
ok = openmesh.read_mesh(self.mesh, "cube-minimal.ply")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
def test_load_simple_ply_force_vertex_colors_although_not_available(self):
self.mesh.request_vertex_colors()
file_name = "cube-minimal.ply"
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, file_name, options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertFalse(options.vertex_has_color())
def test_load_simple_ply_with_vertex_colors(self):
self.mesh.request_vertex_colors()
file_name = "cube-minimal.ply"
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, "cube-minimal-vertexColors.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.mesh.release_vertex_colors()
def test_load_ply_from_mesh_lab_with_vertex_colors(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.mesh.release_vertex_colors()
def test_write_and_read_binary_ply_with_vertex_colors(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options)
self.assertTrue(ok)
options += openmesh.Options.Binary
ok = openmesh.write_mesh(self.mesh, "meshlab_binary.ply", options)
self.assertTrue(ok)
self.mesh.clear
ok = openmesh.read_mesh(self.mesh, "meshlab_binary.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.mesh.release_vertex_colors()
def test_write_and_read_ply_with_float_vertex_colors(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options)
self.assertTrue(ok)
options += openmesh.Options.ColorFloat
ok = openmesh.write_mesh(self.mesh, "meshlab_float.ply", options)
self.assertTrue(ok)
self.mesh.clear
ok = openmesh.read_mesh(self.mesh, "meshlab_float.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.assertTrue(options.color_is_float())
self.mesh.release_vertex_colors()
def test_write_and_read_binary_ply_with_float_vertex_colors(self):
self.mesh.request_vertex_colors()
options = openmesh.Options()
options += openmesh.Options.VertexColor
ok = openmesh.read_mesh(self.mesh, "meshlab.ply", options)
self.assertTrue(ok)
options += openmesh.Options.ColorFloat
options += openmesh.Options.Binary
ok = openmesh.write_mesh(self.mesh, "meshlab_binary_float.ply", options)
self.assertTrue(ok)
self.mesh.clear
ok = openmesh.read_mesh(self.mesh, "meshlab_binary_float.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(3))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[0], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[1], 0.0)
self.assertEqual(self.mesh.color(self.mesh.vertex_handle(7))[2], 1.0)
self.assertFalse(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertTrue(options.vertex_has_color())
self.assertTrue(options.color_is_float())
self.assertTrue(options.is_binary())
self.mesh.release_vertex_colors()
def test_load_simple_ply_with_texcoords(self):
self.mesh.request_vertex_texcoords2D()
options = openmesh.Options()
options += openmesh.Options.VertexTexCoord
ok = openmesh.read_mesh(self.mesh, "cube-minimal-texCoords.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[0], 10.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(0))[1], 10.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[0], 6.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(2))[1], 6.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[0], 9.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(4))[1], 9.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[0], 12.0)
self.assertEqual(self.mesh.texcoord2D(self.mesh.vertex_handle(7))[1], 12.0)
self.assertFalse(options.vertex_has_normal())
self.assertTrue(options.vertex_has_texcoord())
self.assertFalse(options.vertex_has_color())
self.mesh.release_vertex_texcoords2D()
def test_load_simple_ply_with_normals(self):
self.mesh.request_vertex_normals()
options = openmesh.Options()
options += openmesh.Options.VertexNormal
ok = openmesh.read_mesh(self.mesh, "cube-minimal-normals.ply", options)
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_faces(), 12)
self.assertTrue(options.vertex_has_normal())
self.assertFalse(options.vertex_has_texcoord())
self.assertFalse(options.vertex_has_color())
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[0], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(0))[2], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[0], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(3))[2], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[0], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[1], 0.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(4))[2], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[0], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[1], 1.0)
self.assertEqual(self.mesh.normal(self.mesh.vertex_handle(7))[2], 2.0)
self.mesh.release_vertex_normals()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(ReadWritePLY)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,75 +0,0 @@
import unittest
import openmesh
class ReadWriteSTL(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
def test_load_simple_stl_file(self):
ok = openmesh.read_mesh(self.mesh, "cube1.stl")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 7526)
self.assertEqual(self.mesh.n_edges(), 22572)
self.assertEqual(self.mesh.n_faces(), 15048)
def test_load_simple_stl_file_with_normals(self):
self.mesh.request_face_normals()
options = openmesh.Options()
options += openmesh.Options.FaceNormal
ok = openmesh.read_mesh(self.mesh, "cube1.stl", options)
self.assertTrue(ok)
self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[0], -0.038545)
self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[1], -0.004330)
self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[2], 0.999247)
self.assertEqual(self.mesh.n_vertices(), 7526)
self.assertEqual(self.mesh.n_edges(), 22572)
self.assertEqual(self.mesh.n_faces(), 15048)
self.mesh.release_face_normals()
def test_load_simple_stl_binary_file(self):
ok = openmesh.read_mesh(self.mesh, "cube1Binary.stl")
self.assertTrue(ok)
self.assertEqual(self.mesh.n_vertices(), 7526)
self.assertEqual(self.mesh.n_edges(), 22572)
self.assertEqual(self.mesh.n_faces(), 15048)
def test_load_simple_stl_binary_file_with_normals(self):
self.mesh.request_face_normals()
options = openmesh.Options()
options += openmesh.Options.FaceNormal
options += openmesh.Options.Binary
ok = openmesh.read_mesh(self.mesh, "cube1Binary.stl", options)
self.assertTrue(ok)
self.assertTrue(options.is_binary())
self.assertTrue(options.face_has_normal())
self.assertFalse(options.vertex_has_normal())
self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[0], -0.038545, 5)
self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[1], -0.004330, 5)
self.assertAlmostEqual(self.mesh.normal(self.mesh.face_handle(0))[2], 0.999247, 5)
self.assertEqual(self.mesh.n_vertices(), 7526)
self.assertEqual(self.mesh.n_edges(), 22572)
self.assertEqual(self.mesh.n_faces(), 15048)
self.mesh.release_face_normals()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(ReadWriteSTL)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,87 +0,0 @@
import unittest
import openmesh
class SplitCopy(unittest.TestCase):
def test_split_copy_triangle_mesh(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0.25, 0.25, 0)))
# Add one face
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
fh = self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | /
# | /
# | /
# 0
# Set property
fprop_int = openmesh.FPropHandle()
self.mesh.add_property(fprop_int)
self.mesh.set_property(fprop_int, fh, 999)
# Split face with new vertex
self.mesh.split_copy(fh, self.vhandle[3])
# Check setup
for f in self.mesh.faces():
self.assertEqual(self.mesh.property(fprop_int, f), 999)
def test_split_copy_polymesh(self):
self.mesh = openmesh.PolyMesh()
self.vhandle = []
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0.5, 0.5, 0)))
# Add one face
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
fh = self.mesh.add_face(face_vhandles)
# Test setup:
# 1 === 2
# | |
# | |
# | |
# 0 === 3
# Set property
fprop_int = openmesh.FPropHandle()
self.mesh.add_property(fprop_int)
self.mesh.set_property(fprop_int, fh, 999)
# Split face with new vertex
self.mesh.split_copy(fh, self.vhandle[4])
# Check setup
for f in self.mesh.faces():
self.assertEqual(self.mesh.property(fprop_int, f), 999)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SplitCopy)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,269 +0,0 @@
import unittest
import openmesh
class TrimeshCirculatorCurrentHalfedgeHandleReplacement(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_dereference(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
# 0 ==== 2
# |\ 0 /|
# | \ / |
# |2 1 3|
# | / \ |
# |/ 1 \|
# 3 ==== 4
# Starting vertex is 1->4
# output from fh_it.current_halfedge_handle()
current_halfedge_handles = [4, 0, 2, 10, 6, 8, 1, 12, 7, 14, 3, 11]
i = 0
for f in self.mesh.faces():
for he in self.mesh.fh(f):
self.assertEqual(he.idx(), current_halfedge_handles[i])
i += 1
def test_vv_iter(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
# 0 ==== 2
# |\ 0 /|
# | \ / |
# |2 1 3|
# | / \ |
# |/ 1 \|
# 3 ==== 4
# Starting vertex is 1->4
# output from vv_it.current_halfedge_handle()
current_halfedge_handles = [5, 0, 12, 11, 6, 1, 2, 15, 3, 4, 13, 7, 8, 9, 10, 14]
eh0 = []
eh1 = []
i = 0
for v in self.mesh.vertices():
for vv in self.mesh.vv(v):
he = openmesh.HalfedgeHandle(current_halfedge_handles[i])
eh0.append(self.mesh.edge_handle(he))
i += 1
for v in self.mesh.vertices():
for he in self.mesh.voh(v):
eh1.append(self.mesh.edge_handle(he))
self.assertEqual(len(eh0), len(eh1))
for i in range(len(eh0)):
self.assertEqual(eh0[i], eh1[i])
def test_fe_iter(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
# 0 ==== 2
# |\ 0 /|
# | \ / |
# |2 1 3|
# | / \ |
# |/ 1 \|
# 3 ==== 4
# Starting vertex is 1->4
# output from fe_it.current_halfedge_handle()
current_halfedge_handles = [4, 0, 2, 10, 6, 8, 1, 12, 7, 14, 3, 11]
heh0 = []
heh1 = []
i = 0
for f in self.mesh.faces():
for e in self.mesh.fe(f):
heh0.append(openmesh.HalfedgeHandle(current_halfedge_handles[i]))
i += 1
for f in self.mesh.faces():
for he in self.mesh.fh(f):
heh1.append(he)
self.assertEqual(len(heh0), len(heh1))
for i in range(len(heh0)):
self.assertEqual(heh0[i], heh1[i])
def test_vf_iter_boundary(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add three faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 0 ------ 2 ------ 4
# \ / \ /
# \ 0 / \ 1 /
# \ / \ /
# 1 ------- 3
# \ /
# \ 2 /
# \ /
# \ /
# 5
# output from fe_it.current_halfedge_handle()
current_halfedge_handles = [0, 2, 12, 4, 6, 8, 16, 10, 14]
fh0 = []
fh1 = []
i = 0
for v in self.mesh.vertices():
for f in self.mesh.vf(v):
he = openmesh.HalfedgeHandle(current_halfedge_handles[i])
fh0.append(self.mesh.face_handle(he))
i += 1
for v in self.mesh.vertices():
for f in self.mesh.vf(v):
fh1.append(f)
self.assertEqual(len(fh0), len(fh1))
for i in range(len(fh0)):
self.assertEqual(fh0[i], fh1[i])
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TrimeshCirculatorCurrentHalfedgeHandleReplacement)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,50 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorFaceEdge(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[3])
self.mesh.add_face(self.vhandle[2], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[5], self.vhandle[3])
'''
Test setup:
0 ------ 2 ------ 4
\ / \ /
\ 0 / \ 2 /
\ / 1 \ /
1 ------- 3
\ /
\ 3 /
\ /
\ /
5
'''
def test_face_edge_iter_without_holes_increment(self):
# Iterate around face 1 at the middle
fe_it = openmesh.FaceEdgeIter(self.mesh, self.mesh.face_handle(1))
self.assertEqual(fe_it.__next__().idx(), 4)
self.assertEqual(fe_it.__next__().idx(), 1)
self.assertEqual(fe_it.__next__().idx(), 3)
self.assertRaises(StopIteration, fe_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorFaceEdge)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,156 +0,0 @@
import unittest
import openmesh
class TrimeshCirculatorFaceFace(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_face_face_iter_with_holes(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
# Add three faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 0 ------ 2 ------ 4
# \ / \ /
# \ 0 / \ 2 /
# \ / 1 \ /
# 1 ------- 3
ff_it = self.mesh.ff(self.mesh.face_handle(1))
self.assertEqual(ff_it.__next__().idx(), 2)
self.assertEqual(ff_it.__next__().idx(), 0)
self.assertRaises(StopIteration, ff_it.__next__)
def test_face_face_iter_without_holes(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# 0 ------ 2 ------ 4
# \ / \ /
# \ 0 / \ 2 /
# \ / 1 \ /
# 1 ------- 3
# \ /
# \ 3 /
# \ /
# \ /
# 5
ff_it = self.mesh.ff(self.mesh.face_handle(1))
self.assertEqual(ff_it.__next__().idx(), 2)
self.assertEqual(ff_it.__next__().idx(), 0)
self.assertEqual(ff_it.__next__().idx(), 3)
self.assertRaises(StopIteration, ff_it.__next__)
def test_face_face_iter_without_holes(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
fh1 = self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
fh2 = self.mesh.add_face(face_vhandles)
# Test setup:
#
# 1 -------- 2
# | f0 / |
# | / f1 |
# 0 -------- 3
# Check setup
self.assertEqual(self.mesh.n_vertices(), 4)
self.assertEqual(self.mesh.n_faces(), 2)
face_iter = self.mesh.ff(fh1)
# Get the face via the handle
faceHandle1 = face_iter.__next__()
face1 = self.mesh.face(faceHandle1)
self.assertEqual(faceHandle1.idx(), 1)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TrimeshCirculatorFaceFace)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,50 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorFaceHalfEdge(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[3])
self.mesh.add_face(self.vhandle[2], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[5], self.vhandle[3])
'''
Test setup:
0 ------ 2 ------ 4
\ / \ /
\ 0 / \ 2 /
\ / 1 \ /
1 ------- 3
\ /
\ 3 /
\ /
\ /
5
'''
def test_face_halfedge_iter_without_holes_increment(self):
# Iterate around face 1 at the middle
fh_it = openmesh.FaceHalfedgeIter(self.mesh, self.mesh.face_handle(1))
self.assertEqual(fh_it.__next__().idx(), 8)
self.assertEqual(fh_it.__next__().idx(), 3)
self.assertEqual(fh_it.__next__().idx(), 6)
self.assertRaises(StopIteration, fh_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorFaceHalfEdge)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,48 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorFaceVertex(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.fh0 = self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
'''
def test_face_vertex_iter_without_increment(self):
self.assertEqual(self.fh0.idx(), 0)
# Iterate around face 0 at the top
fv_it = openmesh.FaceVertexIter(self.mesh, self.fh0)
self.assertEqual(fv_it.__next__().idx(), 0)
self.assertEqual(fv_it.__next__().idx(), 1)
self.assertEqual(fv_it.__next__().idx(), 2)
self.assertRaises(StopIteration, fv_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorFaceVertex)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,131 +0,0 @@
import unittest
import openmesh
class TrimeshCirculatorHalfedgeLoop(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_halfedge_loop_with_face(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# edge x => halfedge x/x+1
# i.e. edge 0 => halfedge 0/1
#
# 0 --4--- 2 ------ 4
# \ / \ /
# 0 0 2 6 2 /
# \ / 1 \ /
# 1 ---8--- 3
# \ /
# \ 3 /
# \ /
# \ /
# 5
# Circle around face 1
hl_it = self.mesh.hl(self.mesh.halfedge_handle(3))
self.assertEqual(hl_it.__next__().idx(), 3)
self.assertEqual(hl_it.__next__().idx(), 6)
self.assertEqual(hl_it.__next__().idx(), 8)
self.assertRaises(StopIteration, hl_it.__next__)
def test_halfedge_loop_without_face(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(3, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(4, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
# Add three faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# Test setup:
#
# H => hole (no face)
# fx => face #x
# edge 0 => halfedge 0/1
#
# 0 --4--- 2 -10--- 4
# \ / \ /
# 0 f0 2 6 f2 8
# \ / H \ /
# 1 ---16---3
# \ /
# 12 f3 14
# \ /
# \ /
# 5
# Circle around the hole
hl_it = self.mesh.hl(self.mesh.halfedge_handle(3))
self.assertEqual(hl_it.__next__().idx(), 3)
self.assertEqual(hl_it.__next__().idx(), 17)
self.assertEqual(hl_it.__next__().idx(), 7)
self.assertRaises(StopIteration, hl_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TrimeshCirculatorHalfedgeLoop)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,55 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorVertexEdge(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
'''
def test_vertex_edge_iter_without_holes_increment(self):
# Iterate around vertex 1 at the middle
ve_it = openmesh.VertexEdgeIter(self.mesh, self.vhandle[1])
self.assertEqual(ve_it.__next__().idx(), 5)
self.assertEqual(ve_it.__next__().idx(), 3)
self.assertEqual(ve_it.__next__().idx(), 0)
self.assertEqual(ve_it.__next__().idx(), 1)
self.assertRaises(StopIteration, ve_it.__next__)
def test_vertex_edge_iter_boundary_increment(self):
# Iterate around vertex 2 at the boundary
ve_it = openmesh.VertexEdgeIter(self.mesh, self.vhandle[2])
self.assertEqual(ve_it.__next__().idx(), 7)
self.assertEqual(ve_it.__next__().idx(), 1)
self.assertEqual(ve_it.__next__().idx(), 2)
self.assertRaises(StopIteration, ve_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexEdge)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,93 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorVertexFace(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
def test_vertex_face_iter_with_holes_increment(self):
# Add two faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
'''
Test setup:
0 ==== 2
\ /
\ /
1
/ \
/ \
3 ==== 4
'''
# Iterate around vertex 1 at the middle (with holes in between)
vf_it = openmesh.VertexFaceIter(self.mesh, self.vhandle[1])
self.assertEqual(vf_it.__next__().idx(), 0)
self.assertEqual(vf_it.__next__().idx(), 1)
self.assertRaises(StopIteration, vf_it.__next__)
def test_vertex_face_iter_without_holes_increment(self):
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
'''
# Iterate around vertex 1 at the middle (without holes in between)
vf_it = openmesh.VertexFaceIter(self.mesh, self.vhandle[1])
self.assertEqual(vf_it.__next__().idx(), 3)
self.assertEqual(vf_it.__next__().idx(), 1)
self.assertEqual(vf_it.__next__().idx(), 2)
self.assertEqual(vf_it.__next__().idx(), 0)
self.assertRaises(StopIteration, vf_it.__next__)
def test_vertex_face_iter_boundary_increment(self):
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
'''
# Iterate around vertex 2 at the boundary (without holes in between)
vf_it = openmesh.VertexFaceIter(self.mesh, self.vhandle[2])
self.assertEqual(vf_it.__next__().idx(), 3)
self.assertEqual(vf_it.__next__().idx(), 0)
self.assertRaises(StopIteration, vf_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexFace)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,80 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorVertexIHalfEdge(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
Starting halfedge is 1->4
'''
def test_vertex_incoming_halfedge_without_holes_increment(self):
# Iterate around vertex 1 at the middle
vih_it = openmesh.VertexIHalfedgeIter(self.mesh, self.vhandle[1])
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 10)
self.assertEqual(self.mesh.face_handle(heh).idx(), 1)
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 7)
self.assertEqual(self.mesh.face_handle(heh).idx(), 2)
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 0)
self.assertEqual(self.mesh.face_handle(heh).idx(), 0)
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 3)
self.assertEqual(self.mesh.face_handle(heh).idx(), 3)
self.assertRaises(StopIteration, vih_it.__next__)
def test_vertex_incoming_halfedge_boundary_increment(self):
# Iterate around vertex 2 at the boundary
vih_it = openmesh.VertexIHalfedgeIter(self.mesh, self.vhandle[2])
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 14)
self.assertEqual(self.mesh.face_handle(heh).idx(), 3)
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 2)
self.assertEqual(self.mesh.face_handle(heh).idx(), 0)
heh = vih_it.__next__()
self.assertEqual(heh.idx(), 5)
self.assertEqual(self.mesh.face_handle(heh).idx(), -1)
self.assertRaises(StopIteration, vih_it.__next__)
def test_vertex_incoming_halfedge_dereference_increment(self):
# Iterate around vertex 1 at the middle
vih_it = openmesh.VertexIHalfedgeIter(self.mesh, self.vhandle[1])
heh = vih_it.__next__()
eh = self.mesh.edge_handle(heh)
vh = self.mesh.to_vertex_handle(heh)
self.assertEqual(heh.idx(), 10)
self.assertEqual(eh.idx(), 5)
self.assertEqual(vh.idx(), 1)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexIHalfEdge)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,80 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorVertexOHalfEdge(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
Starting halfedge is 1->4
'''
def test_vertex_outgoing_halfedge_without_holes_increment(self):
# Iterate around vertex 1 at the middle
voh_it = openmesh.VertexOHalfedgeIter(self.mesh, self.vhandle[1])
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 11)
self.assertEqual(self.mesh.face_handle(heh).idx(), 3)
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 6)
self.assertEqual(self.mesh.face_handle(heh).idx(), 1)
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 1)
self.assertEqual(self.mesh.face_handle(heh).idx(), 2)
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 2)
self.assertEqual(self.mesh.face_handle(heh).idx(), 0)
self.assertRaises(StopIteration, voh_it.__next__)
def test_vertex_outgoing_halfedge_boundary_increment(self):
# Iterate around vertex 2 at the boundary
voh_it = openmesh.VertexOHalfedgeIter(self.mesh, self.vhandle[2])
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 15)
self.assertEqual(self.mesh.face_handle(heh).idx(), -1)
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 3)
self.assertEqual(self.mesh.face_handle(heh).idx(), 3)
heh = voh_it.__next__()
self.assertEqual(heh.idx(), 4)
self.assertEqual(self.mesh.face_handle(heh).idx(), 0)
self.assertRaises(StopIteration, voh_it.__next__)
def test_vertex_outgoing_halfedge_dereference_increment(self):
# Iterate around vertex 1 at the middle
voh_it = openmesh.VertexOHalfedgeIter(self.mesh, self.vhandle[1])
heh = voh_it.__next__()
eh = self.mesh.edge_handle(heh)
vh = self.mesh.to_vertex_handle(heh)
self.assertEqual(heh.idx(), 11)
self.assertEqual(eh.idx(), 5)
self.assertEqual(vh.idx(), 4)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexOHalfEdge)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,56 +0,0 @@
import unittest
import openmesh
class TriMeshCirculatorVertexVertex(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0,-1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2,-1, 0)))
# Add four faces
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[2])
self.mesh.add_face(self.vhandle[1], self.vhandle[3], self.vhandle[4])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[1])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[4])
'''
Test setup:
0 ==== 2
|\ 0 /|
| \ / |
|2 1 3|
| / \ |
|/ 1 \|
3 ==== 4
Starting vertex is 1->4
'''
def test_vertex_vertex_increment(self):
# Iterate around vertex 1 at the middle
vv_it = openmesh.VertexVertexIter(self.mesh, self.vhandle[1])
self.assertEqual(vv_it.__next__().idx(), 4)
self.assertEqual(vv_it.__next__().idx(), 3)
self.assertEqual(vv_it.__next__().idx(), 0)
self.assertEqual(vv_it.__next__().idx(), 2)
self.assertRaises(StopIteration, vv_it.__next__)
def test_vertex_vertex_boundary_increment(self):
# Iterate around vertex 2 at the boundary
vv_it = openmesh.VertexVertexIter(self.mesh, self.vhandle[2])
self.assertEqual(vv_it.__next__().idx(), 4)
self.assertEqual(vv_it.__next__().idx(), 1)
self.assertEqual(vv_it.__next__().idx(), 0)
self.assertRaises(StopIteration, vv_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshCirculatorVertexVertex)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,516 +0,0 @@
import unittest
import openmesh
class Collapse(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_collapse_quad_with_center(self):
# 0--------1
# |\ /|
# | \ / |
# | \ / |
# | 2 |
# | / \ |
# | / \ |
# 3--------4
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 2, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 2, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_face_status()
# Get the halfedge
v2v1 = self.mesh.find_halfedge(self.vhandle[2], self.vhandle[1])
self.assertTrue(v2v1.is_valid())
self.assertTrue(self.mesh.is_collapse_ok(v2v1))
# Execute it as a crash test
self.mesh.collapse(v2v1)
def test_collapse_tetrahedron_complex(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_face_status()
v0v1 = self.mesh.halfedge_handle(0)
v1v0 = self.mesh.opposite_halfedge_handle(v0v1)
v1vL = self.mesh.next_halfedge_handle(v0v1)
vLv1 = self.mesh.opposite_halfedge_handle(v1vL)
vLv0 = self.mesh.next_halfedge_handle(v1vL)
v0vL = self.mesh.opposite_halfedge_handle(vLv0)
vLvR = self.mesh.next_halfedge_handle(v0vL)
vRvL = self.mesh.opposite_halfedge_handle(vLvR)
v0vR = self.mesh.next_halfedge_handle(v1v0)
vRv0 = self.mesh.opposite_halfedge_handle(v0vR)
vRv1 = self.mesh.next_halfedge_handle(v0vR)
v1vR = self.mesh.opposite_halfedge_handle(vRv1)
v0 = self.mesh.from_vertex_handle(v0v1)
v1 = self.mesh.to_vertex_handle(v0v1)
vL = self.mesh.to_vertex_handle(self.mesh.next_halfedge_handle(v0v1))
vR = self.mesh.to_vertex_handle(self.mesh.next_halfedge_handle(v1v0))
# ===================================================================
# Check preconditions
# ===================================================================
self.assertTrue(self.mesh.is_collapse_ok(v0v1))
self.assertTrue(self.mesh.is_collapse_ok(v1v0))
# Test the Vertex indices
self.assertEqual(v0.idx(), 0)
self.assertEqual(v1.idx(), 1)
self.assertEqual(vL.idx(), 2)
self.assertEqual(vR.idx(), 3)
# Check the halfedges
self.assertEqual(v0v1.idx(), 0)
self.assertEqual(v1v0.idx(), 1)
self.assertEqual(v1vL.idx(), 2)
self.assertEqual(vLv1.idx(), 3)
self.assertEqual(vLv0.idx(), 4)
self.assertEqual(v0vL.idx(), 5)
self.assertEqual(vLvR.idx(), 6)
self.assertEqual(vRvL.idx(), 7)
self.assertEqual(vRv0.idx(), 8)
self.assertEqual(v0vR.idx(), 9)
self.assertEqual(v1vR.idx(), 10)
self.assertEqual(vRv1.idx(), 11)
# ===================================================================
# Execute collapse
# ===================================================================
self.mesh.collapse(v0v1)
# ===================================================================
# Check configuration afterwards
# ===================================================================
# Now the configuration should look like this:
# The numbers at the side denote the halfedges
# 1
# / \
# / \
# // \\
# 3/2 11\10
# // \\
# / 6--> \
# 2 ----------- 3
# <--7
self.assertEqual(self.mesh.n_faces(), 4)
# Check if the right vertices got deleted
self.assertTrue(self.mesh.status(self.mesh.face_handle(0)).deleted())
self.assertFalse(self.mesh.status(self.mesh.face_handle(1)).deleted())
self.assertFalse(self.mesh.status(self.mesh.face_handle(2)).deleted())
self.assertTrue(self.mesh.status(self.mesh.face_handle(3)).deleted())
# Check the vertices of the two remaining faces
fh_1 = self.mesh.face_handle(1)
fh_2 = self.mesh.face_handle(2)
fv_it = self.mesh.fv(fh_1)
self.assertTrue(fv_it.__next__().idx(), 1)
self.assertTrue(fv_it.__next__().idx(), 2)
self.assertTrue(fv_it.__next__().idx(), 3)
fv_it = self.mesh.fv(fh_2)
self.assertTrue(fv_it.__next__().idx(), 2)
self.assertTrue(fv_it.__next__().idx(), 1)
self.assertTrue(fv_it.__next__().idx(), 3)
# Get the first halfedge of face 1
fh_1_he = self.mesh.halfedge_handle(fh_1)
self.assertEqual(fh_1_he.idx(), 11)
self.assertEqual(self.mesh.to_vertex_handle(fh_1_he).idx(), 1)
next = self.mesh.next_halfedge_handle(fh_1_he)
self.assertEqual(next.idx(), 2)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 2)
next = self.mesh.next_halfedge_handle(next)
self.assertEqual(next.idx(), 6)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 3)
# Get the first halfedge of face 2
fh_2_he = self.mesh.halfedge_handle(fh_2)
self.assertEqual(fh_2_he.idx(), 7)
self.assertEqual(self.mesh.to_vertex_handle(fh_2_he).idx(), 2)
next = self.mesh.next_halfedge_handle(fh_2_he)
self.assertEqual(next.idx(), 3)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 1)
next = self.mesh.next_halfedge_handle(next)
self.assertEqual(next.idx(), 10)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 3)
# Vertex 1 outgoing
voh_it = self.mesh.voh(self.mesh.vertex_handle(1))
self.assertEqual(voh_it.__next__().idx(), 10)
self.assertEqual(voh_it.__next__().idx(), 2)
self.assertRaises(StopIteration, voh_it.__next__)
# Vertex 2 outgoing
voh_it = self.mesh.voh(self.mesh.vertex_handle(2))
self.assertEqual(voh_it.__next__().idx(), 3)
self.assertEqual(voh_it.__next__().idx(), 6)
self.assertRaises(StopIteration, voh_it.__next__)
# Vertex 2 outgoing
voh_it = self.mesh.voh(self.mesh.vertex_handle(3))
self.assertEqual(voh_it.__next__().idx(), 11)
self.assertEqual(voh_it.__next__().idx(), 7)
self.assertRaises(StopIteration, voh_it.__next__)
# ===================================================================
# Cleanup
# ===================================================================
self.mesh.garbage_collection()
# ===================================================================
# Check configuration afterwards
# ===================================================================
# Now the configuration should look like this:
# The numbers at the side denote the halfedges
# 0
# / \
# / \
# // \\
# 4/5 0\1
# // \\
# / 3--> \
# 2 ----------- 1
# <--2
self.assertEqual(self.mesh.n_faces(), 2)
# Check the vertices of the two remaining faces
fh_0 = self.mesh.face_handle(0)
fh_1 = self.mesh.face_handle(1)
fv_it = self.mesh.fv(fh_0)
self.assertEqual(fv_it.__next__().idx(), 2)
self.assertEqual(fv_it.__next__().idx(), 1)
self.assertEqual(fv_it.__next__().idx(), 0)
fv_it = self.mesh.fv(fh_1)
self.assertEqual(fv_it.__next__().idx(), 1)
self.assertEqual(fv_it.__next__().idx(), 2)
self.assertEqual(fv_it.__next__().idx(), 0)
# Get the first halfedge of face 1
fh_0_he = self.mesh.halfedge_handle(fh_0)
self.assertEqual(fh_0_he.idx(), 5)
self.assertEqual(self.mesh.to_vertex_handle(fh_0_he).idx(), 2)
next = self.mesh.next_halfedge_handle(fh_0_he)
self.assertEqual(next.idx(), 3)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 1)
next = self.mesh.next_halfedge_handle(next)
self.assertEqual(next.idx(), 0)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 0)
# Get the first halfedge of face 1
fh_1_he = self.mesh.halfedge_handle(fh_1)
self.assertEqual(fh_1_he.idx(), 1)
self.assertEqual(self.mesh.to_vertex_handle(fh_1_he).idx(), 1)
next = self.mesh.next_halfedge_handle(fh_1_he)
self.assertEqual(next.idx(), 2)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 2)
next = self.mesh.next_halfedge_handle(next)
self.assertEqual(next.idx(), 4)
self.assertEqual(self.mesh.to_vertex_handle(next).idx(), 0)
# Vertex 0 outgoing
voh_it = self.mesh.voh(self.mesh.vertex_handle(0))
self.assertEqual(voh_it.__next__().idx(), 1)
self.assertEqual(voh_it.__next__().idx(), 5)
self.assertRaises(StopIteration, voh_it.__next__)
# Vertex 1 outgoing
voh_it = self.mesh.voh(self.mesh.vertex_handle(1))
self.assertEqual(voh_it.__next__().idx(), 0)
self.assertEqual(voh_it.__next__().idx(), 2)
self.assertRaises(StopIteration, voh_it.__next__)
# Vertex 2 outgoing
voh_it = self.mesh.voh(self.mesh.vertex_handle(2))
self.assertEqual(voh_it.__next__().idx(), 3)
self.assertEqual(voh_it.__next__().idx(), 4)
self.assertRaises(StopIteration, voh_it.__next__)
self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(0)))
self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(1)))
self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(2)))
self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(3)))
self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(4)))
self.assertFalse(self.mesh.is_collapse_ok(self.mesh.halfedge_handle(5)))
def test_collapse_tetrahedron(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, -1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 0, 0)))
# Add six faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_face_status()
# =============================================
# Collapse halfedge from 0 to 4
# =============================================
heh_collapse1 = self.mesh.halfedge_handle(0)
self.assertEqual(self.mesh.to_vertex_handle(heh_collapse1).idx(), 4)
self.assertEqual(self.mesh.from_vertex_handle(heh_collapse1).idx(), 0)
self.assertTrue(self.mesh.is_collapse_ok(heh_collapse1))
self.mesh.collapse(heh_collapse1)
heh_collapse2 = self.mesh.halfedge_handle(2)
self.assertEqual(self.mesh.to_vertex_handle(heh_collapse2).idx(), 2)
self.assertEqual(self.mesh.from_vertex_handle(heh_collapse2).idx(), 4)
self.assertTrue(self.mesh.is_collapse_ok(heh_collapse2))
self.mesh.collapse(heh_collapse2)
heh_collapse3 = self.mesh.halfedge_handle(6)
self.assertEqual(self.mesh.to_vertex_handle(heh_collapse3).idx(), 2)
self.assertEqual(self.mesh.from_vertex_handle(heh_collapse3).idx(), 3)
self.assertFalse(self.mesh.is_collapse_ok(heh_collapse3))
def test_large_collapse_halfedge(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 2, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 0, -1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 2, -1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 3, 0, 0)))
# Add six faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[1])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[5])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[4])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[4])
face_vhandles.append(self.vhandle[6])
self.mesh.add_face(face_vhandles)
# Test setup:
# 0 ==== 2
# / \ /|\
# / \ / | \
# 5 --- 1 | 6
# \ / \ | /
# \ / \|/
# 3 ==== 4
# Request the status bits
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_face_status()
# =============================================
# Collapse halfedge from 1 to 4
# =============================================
heh_collapse = openmesh.HalfedgeHandle()
for he in self.mesh.halfedges():
if self.mesh.from_vertex_handle(he).idx() == 1 and self.mesh.to_vertex_handle(he).idx() == 4:
heh_collapse = he
# Check our halfedge
self.assertEqual(self.mesh.to_vertex_handle(heh_collapse).idx(), 4)
self.assertEqual(self.mesh.from_vertex_handle(heh_collapse).idx(), 1)
self.assertTrue(self.mesh.is_collapse_ok(heh_collapse))
# Remember the end vertices
vh_from = self.mesh.from_vertex_handle(heh_collapse)
vh_to = self.mesh.to_vertex_handle(heh_collapse)
# Collapse it
self.mesh.collapse(heh_collapse)
self.assertTrue(self.mesh.status(vh_from).deleted())
self.assertFalse(self.mesh.status(vh_to).deleted())
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(Collapse)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,168 +0,0 @@
import unittest
import openmesh
class TriMeshGarbageCollection(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_halfedge_status()
self.mesh.request_face_status()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3])
self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3])
self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5])
self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5])
self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6])
self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6])
self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7])
self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4])
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
def test_standard_garbage_collection(self):
# Check setup
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
self.mesh.delete_vertex(self.vhandle[0])
# Check setup
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
self.mesh.garbage_collection()
# Check setup
self.assertEqual(self.mesh.n_vertices(), 7)
self.assertEqual(self.mesh.n_faces(), 8)
def test_tracked_garbage_collection(self):
# Check setup
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
#==================================================
# Create lists containing the current handles
#==================================================
vertexHandles = []
for v in self.mesh.vertices():
vertexHandles.append(v)
halfedgeHandles = []
for he in self.mesh.halfedges():
halfedgeHandles.append(he)
faceHandles = []
for f in self.mesh.faces():
faceHandles.append(f)
# Deleting vertex 0
self.mesh.delete_vertex(self.vhandle[0])
# Check setup
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
self.mesh.garbage_collection(vertexHandles, halfedgeHandles, faceHandles, True, True, True)
# Check setup
self.assertEqual(self.mesh.n_vertices(), 7)
self.assertEqual(self.mesh.n_faces(), 8)
# Check setup of vertices
self.assertEqual(vertexHandles[0].idx(), -1)
self.assertEqual(vertexHandles[1].idx(), 1)
self.assertEqual(vertexHandles[2].idx(), 2)
self.assertEqual(vertexHandles[3].idx(), 3)
self.assertEqual(vertexHandles[4].idx(), 4)
self.assertEqual(vertexHandles[5].idx(), 5)
self.assertEqual(vertexHandles[6].idx(), 6)
self.assertEqual(vertexHandles[7].idx(), 0)
# Check setup of halfedge handles
self.assertEqual(halfedgeHandles[0 ].idx(), -1)
self.assertEqual(halfedgeHandles[1 ].idx(), -1)
self.assertEqual(halfedgeHandles[2 ].idx(), 2)
self.assertEqual(halfedgeHandles[3 ].idx(), 3)
self.assertEqual(halfedgeHandles[4 ].idx(), -1)
self.assertEqual(halfedgeHandles[5 ].idx(), -1)
self.assertEqual(halfedgeHandles[6 ].idx(), 6)
self.assertEqual(halfedgeHandles[7 ].idx(), 7)
self.assertEqual(halfedgeHandles[8 ].idx(), 8)
self.assertEqual(halfedgeHandles[9 ].idx(), 9)
self.assertEqual(halfedgeHandles[10].idx(), 10)
self.assertEqual(halfedgeHandles[11].idx(), 11)
self.assertEqual(halfedgeHandles[12].idx(), 12)
self.assertEqual(halfedgeHandles[13].idx(), 13)
self.assertEqual(halfedgeHandles[14].idx(), 14)
self.assertEqual(halfedgeHandles[15].idx(), 15)
self.assertEqual(halfedgeHandles[16].idx(), 16)
self.assertEqual(halfedgeHandles[17].idx(), 17)
self.assertEqual(halfedgeHandles[18].idx(), 18)
self.assertEqual(halfedgeHandles[19].idx(), 19)
self.assertEqual(halfedgeHandles[20].idx(), -1)
self.assertEqual(halfedgeHandles[21].idx(), -1)
self.assertEqual(halfedgeHandles[22].idx(), 22)
self.assertEqual(halfedgeHandles[23].idx(), 23)
self.assertEqual(halfedgeHandles[24].idx(), 24)
self.assertEqual(halfedgeHandles[25].idx(), 25)
self.assertEqual(halfedgeHandles[26].idx(), 26)
self.assertEqual(halfedgeHandles[27].idx(), 27)
self.assertEqual(halfedgeHandles[28].idx(), 20)
self.assertEqual(halfedgeHandles[29].idx(), 21)
self.assertEqual(halfedgeHandles[30].idx(), 4)
self.assertEqual(halfedgeHandles[31].idx(), 5)
self.assertEqual(halfedgeHandles[32].idx(), 0)
self.assertEqual(halfedgeHandles[33].idx(), 1)
self.assertEqual(halfedgeHandles[34].idx(), -1)
self.assertEqual(halfedgeHandles[35].idx(), -1)
# Check setup of faces
self.assertEqual(faceHandles[0 ].idx(), -1)
self.assertEqual(faceHandles[1 ].idx(), 1)
self.assertEqual(faceHandles[2 ].idx(), 2)
self.assertEqual(faceHandles[3 ].idx(), 3)
self.assertEqual(faceHandles[4 ].idx(), -1)
self.assertEqual(faceHandles[5 ].idx(), 5)
self.assertEqual(faceHandles[6 ].idx(), 6)
self.assertEqual(faceHandles[7 ].idx(), 7)
self.assertEqual(faceHandles[8 ].idx(), 4)
self.assertEqual(faceHandles[9 ].idx(), 0)
self.assertEqual(faceHandles[10].idx(), -1)
self.assertEqual(faceHandles[11].idx(), -1)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshGarbageCollection)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,396 +0,0 @@
import unittest
import openmesh
class TriMeshIterators(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_vertex_iter(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0])
self.mesh.add_face(self.vhandle[2], self.vhandle[0], self.vhandle[3])
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
v_it = self.mesh.vertices()
self.assertEqual(v_it.__next__().idx(), 0)
self.assertEqual(v_it.__next__().idx(), 1)
self.assertEqual(v_it.__next__().idx(), 2)
self.assertEqual(v_it.__next__().idx(), 3)
self.assertRaises(StopIteration, v_it.__next__)
def test_vertex_iter_start_position(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0])
self.mesh.add_face(self.vhandle[2], self.vhandle[0], self.vhandle[3])
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
v_it = openmesh.VertexIter(self.mesh, self.mesh.vertex_handle(2))
self.assertEqual(v_it.__next__().idx(), 2)
self.assertEqual(v_it.__next__().idx(), 3)
self.assertRaises(StopIteration, v_it.__next__)
def test_edge_iter(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0])
self.mesh.add_face(self.vhandle[2], self.vhandle[0], self.vhandle[3])
# Test setup:
# 1 === 2
# | / |
# | / |
# | / |
# 0 === 3
e_it = self.mesh.edges()
e = e_it.__next__()
self.assertEqual(e.idx(), 0)
he = self.mesh.halfedge_handle(e, 0)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 1)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2)
he = self.mesh.halfedge_handle(e, 1)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 2)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 1)
e = e_it.__next__()
self.assertEqual(e.idx(), 1)
he = self.mesh.halfedge_handle(e, 0)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 1)
he = self.mesh.halfedge_handle(e, 1)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 1)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 0)
e = e_it.__next__()
self.assertEqual(e.idx(), 2)
he = self.mesh.halfedge_handle(e, 0)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 2)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 0)
he = self.mesh.halfedge_handle(e, 1)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2)
e = e_it.__next__()
self.assertEqual(e.idx(), 3)
he = self.mesh.halfedge_handle(e, 0)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 3)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 0)
he = self.mesh.halfedge_handle(e, 1)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 3)
e = e_it.__next__()
self.assertEqual(e.idx(), 4)
he = self.mesh.halfedge_handle(e, 0)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 2)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 3)
he = self.mesh.halfedge_handle(e, 1)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 3)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2)
def test_halfedge_iter_skipping(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3])
self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3])
self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5])
self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5])
self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6])
self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6])
self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7])
self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4])
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# Run over all halfedges
heCounter = 0
self.mesh.request_face_status()
self.mesh.request_vertex_status()
self.mesh.request_halfedge_status()
# Get second edge
eh = self.mesh.edge_handle(2)
# Delete one edge
self.mesh.delete_edge(eh)
# Check setup ( No garbage collection, so nothing should change!)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# =====================================================
# Check skipping iterator
# =====================================================
ok_4 = True
ok_5 = True
count = 0
for he in self.mesh.shalfedges():
if he.idx() == 4:
ok_4 = False
if he.idx() == 5:
ok_5 = False
count += 1
self.assertEqual(count, 34)
self.assertTrue(ok_4)
self.assertTrue(ok_5)
# =====================================================
# Check non skipping iterator
# =====================================================
ok_4 = False
ok_5 = False
count = 0
for he in self.mesh.halfedges():
if he.idx() == 4:
ok_4 = True
if he.idx() == 5:
ok_5 = True
count += 1
self.assertEqual(count, 36)
self.assertTrue(ok_4)
self.assertTrue(ok_5)
def test_halfedge_iter_skipping_low_level(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1)))
# Add six faces to form a cube
self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3])
self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3])
self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5])
self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4])
self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5])
self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5])
self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6])
self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6])
self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7])
self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7])
self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4])
# Test setup:
#
# 3 ======== 2
# / /|
# / / | z
# 0 ======== 1 | |
# | | | | y
# | 7 | 6 | /
# | | / | /
# | |/ |/
# 4 ======== 5 -------> x
# Check setup
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# Run over all halfedges
heCounter = 0
self.mesh.request_face_status()
self.mesh.request_vertex_status()
self.mesh.request_halfedge_status()
# Get second edge
eh = self.mesh.edge_handle(2)
# Delete one edge
self.mesh.delete_edge(eh)
# Check setup ( No garbage collection, so nothing should change!)
self.assertEqual(self.mesh.n_edges(), 18)
self.assertEqual(self.mesh.n_halfedges(), 36)
self.assertEqual(self.mesh.n_vertices(), 8)
self.assertEqual(self.mesh.n_faces(), 12)
# =====================================================
# Try to add low level edge with invalid incidents and
# check skipping iterator
# =====================================================
# Add a low level edge without handles
eh_test = self.mesh.edge_handle(self.mesh.new_edge(openmesh.VertexHandle(), openmesh.VertexHandle()))
count = 0
found_4 = False
found_5 = False
found_36 = False
found_37 = False
for he in self.mesh.shalfedges():
if he.idx() == 4:
found_4 = True
if he.idx() == 5:
found_5 = True
if he.idx() == 36:
found_36 = True
if he.idx() == 37:
found_37 = True
count += 1
self.assertEqual(count, 36)
self.assertFalse(found_4)
self.assertFalse(found_5)
self.assertTrue(found_36)
self.assertTrue(found_37)
# =====================================================
# Try to delete one edge with invalid incidents and
# check skipping iterator
# =====================================================
# Delete one edge and recheck (Halfedges 4 and 5)
self.mesh.delete_edge(eh_test)
count = 0
found_4 = False
found_5 = False
found_36 = False
found_37 = False
for he in self.mesh.shalfedges():
if he.idx() == 4:
found_4 = True
if he.idx() == 5:
found_5 = True
if he.idx() == 36:
found_36 = True
if he.idx() == 37:
found_37 = True
count += 1
self.assertEqual(count, 34)
self.assertFalse(found_4)
self.assertFalse(found_5)
self.assertFalse(found_36)
self.assertFalse(found_37)
def test_face_iter_empty_mesh_one_deleted_face(self):
# Request delete_face capability
self.mesh.request_vertex_status()
self.mesh.request_edge_status()
self.mesh.request_face_status()
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
# Add one face
fh = self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[0])
is_delete_isolated_vertex = False
self.mesh.delete_face(fh, is_delete_isolated_vertex)
# Test setup:
# 1 === 2
# | /
# | /
# | /
# 0
# Normal iterators
f_it = self.mesh.faces()
self.assertEqual(f_it.__next__().idx(), 0)
self.assertRaises(StopIteration, f_it.__next__)
# Same with skipping iterators
f_it = self.mesh.sfaces()
self.assertRaises(StopIteration, f_it.__next__)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TriMeshIterators)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,103 +0,0 @@
import unittest
import openmesh
class Normals(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
# Add some vertices
self.vhandle = []
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 1)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
def test_normal_calculations(self):
# Check one Request only vertex normals
# Face normals are required for vertex and halfedge normals, so
# that prevent access to non existing properties are in place
self.mesh.request_vertex_normals()
self.mesh.request_halfedge_normals()
# Check blocks
self.mesh.update_normals()
# Request required face normals
self.mesh.request_face_normals()
# Automatically compute all normals
# As only vertex normals are requested and no face normals, this will compute nothing.
self.mesh.update_normals()
# Face normals alone
self.mesh.update_face_normals()
# Vertex normals alone (require valid face normals)
self.mesh.update_vertex_normals()
# Halfedge normals alone (require valid face normals)
self.mesh.update_halfedge_normals()
def test_calc_vertex_normal_fast(self):
self.mesh.request_vertex_normals()
self.mesh.request_halfedge_normals()
self.mesh.request_face_normals()
normal = openmesh.Vec3d()
self.mesh.calc_vertex_normal_fast(self.vhandle[2], normal)
def test_calc_vertex_normal_correct(self):
self.mesh.request_vertex_normals()
self.mesh.request_halfedge_normals()
self.mesh.request_face_normals()
normal = openmesh.Vec3d()
self.mesh.calc_vertex_normal_correct(self.vhandle[2], normal)
def test_calc_vertex_normal_loop(self):
self.mesh.request_vertex_normals()
self.mesh.request_halfedge_normals()
self.mesh.request_face_normals()
normal = openmesh.Vec3d()
self.mesh.calc_vertex_normal_loop(self.vhandle[2], normal)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(Normals)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,129 +0,0 @@
import unittest
import openmesh
from math import pi, fabs
class Others(unittest.TestCase):
def setUp(self):
self.mesh = openmesh.TriMesh()
self.vhandle = []
def test_is_estimated_feature_edge(self):
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 1)))
# Add four faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[3])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[0])
self.mesh.add_face(face_vhandles)
# ===============================================
# Setup complete
# ===============================================
# Check one Request only vertex normals
# Face normals are required for vertex and halfedge normals, so
# that prevent access to non existing properties are in place
self.mesh.request_vertex_normals()
self.mesh.request_halfedge_normals()
self.mesh.request_face_normals()
# Automatically compute all normals
# As only vertex normals are requested and no face normals, this will compute nothing.
self.mesh.update_normals()
he = self.mesh.halfedges().__next__()
self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.0))
self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.125 * pi))
self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.250 * pi))
self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.375 * pi))
self.assertTrue(self.mesh.is_estimated_feature_edge(he, 0.500 * pi))
self.assertFalse(self.mesh.is_estimated_feature_edge(he, 0.625 * pi))
self.assertFalse(self.mesh.is_estimated_feature_edge(he, 0.750 * pi))
self.assertFalse(self.mesh.is_estimated_feature_edge(he, 0.875 * pi))
self.assertFalse(self.mesh.is_estimated_feature_edge(he, 1.000 * pi))
def test_is_estimated_feature_edge(self):
# Test setup:
# 1 -- 2
# | / |
# | / |
# 0 -- 3
# Add some vertices
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 0, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 1, 0)))
self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0)))
# Add two faces
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[1])
face_vhandles.append(self.vhandle[2])
self.mesh.add_face(face_vhandles)
face_vhandles = []
face_vhandles.append(self.vhandle[0])
face_vhandles.append(self.vhandle[2])
face_vhandles.append(self.vhandle[3])
self.mesh.add_face(face_vhandles)
# ===============================================
# Setup complete
# ===============================================
he = self.mesh.halfedge_handle(4)
self.assertEqual(self.mesh.to_vertex_handle(he).idx(), 0)
self.assertEqual(self.mesh.from_vertex_handle(he).idx(), 2)
self.assertEqual(self.mesh.edge_handle(he).idx(), 2)
eh = self.mesh.edge_handle(he)
self.assertEqual(self.mesh.calc_dihedral_angle(eh), 0.0)
# Modify point
tmp = (openmesh.Vec3d(0.0, 0.0, -1.0) + openmesh.Vec3d(1.0, 1.0, -1.0)) * 0.5
self.mesh.set_point(self.vhandle[2], tmp)
difference = fabs(1.36944 - self.mesh.calc_dihedral_angle(eh))
self.assertTrue(difference < 0.00001)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(Others)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,46 +0,0 @@
import unittest
import openmesh
class VectorTest(unittest.TestCase):
def test_compute_triangle_surface_with_cross_product(self):
# vec1
# y
# |
# |
# |
# x------>x vec2
vec1 = openmesh.Vec3d(0.0, 1.0, 0.0)
vec2 = openmesh.Vec3d(1.0, 0.0, 0.0)
area = 0.5 * openmesh.cross(vec1, vec2).norm()
self.assertEqual(area, 0.5)
area = 0.5 * (vec1 % vec2).norm()
self.assertEqual(area, 0.5)
def test_equality_operator_vec3d(self):
vec1 = openmesh.Vec3d(0.0, 1.0, 0.0)
vec2 = openmesh.Vec3d(1.0, 0.0, 0.0)
vec3 = openmesh.Vec3d(1.0, 0.0, 0.0)
self.assertFalse(vec1==vec2)
self.assertTrue(vec3==vec2)
def test_equality_operator_vec3f(self):
vec1 = openmesh.Vec3f(0.0, 1.0, 0.0)
vec2 = openmesh.Vec3f(1.0, 0.0, 0.0)
vec3 = openmesh.Vec3f(1.0, 0.0, 0.0)
self.assertFalse(vec1==vec2)
self.assertTrue(vec3==vec2)
def test_abs_test(self):
vec1 = openmesh.Vec3d(0.5, 0.5, -0.5)
self.assertEqual(vec1.l8_norm(), 0.5)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(VectorTest)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@@ -1,193 +0,0 @@
#ifndef OPENMESH_PYTHON_VECTOR_HH
#define OPENMESH_PYTHON_VECTOR_HH
#include "Python/Bindings.hh"
namespace OpenMesh {
namespace Python {
template <class Vector, class Scalar>
void set_item(Vector& _vec, int _index, Scalar _value) {
if (_index < 0) {
_index += _vec.size();
}
if ((size_t)_index < _vec.size()) {
_vec[_index] = _value;
}
else {
PyErr_SetString(PyExc_IndexError, "Index out of range.");
throw_error_already_set();
}
}
template <class Vector, class Scalar>
Scalar get_item(Vector& _vec, int _index) {
if (_index < 0) {
_index += _vec.size();
}
if ((size_t)_index < _vec.size()) {
return _vec[_index];
}
else {
PyErr_SetString(PyExc_IndexError, "Index out of range.");
throw_error_already_set();
}
return 0.0;
}
namespace {
template<class Scalar>
struct Factory {
typedef OpenMesh::VectorT<Scalar, 2> Vector2;
typedef OpenMesh::VectorT<Scalar, 3> Vector3;
typedef OpenMesh::VectorT<Scalar, 4> Vector4;
static Vector2 *vec2_default() {
return new Vector2(Scalar(), Scalar());
}
static Vector2 *vec2_user_defined(const Scalar& _v0, const Scalar& _v1) {
return new Vector2(_v0, _v1);
}
static Vector3 *vec3_default() {
return new Vector3(Scalar(), Scalar(), Scalar());
}
static Vector3 *vec3_user_defined(const Scalar& _v0, const Scalar& _v1, const Scalar& _v2) {
return new Vector3(_v0, _v1, _v2);
}
static Vector4 *vec4_default() {
return new Vector4(Scalar(), Scalar(), Scalar(), Scalar());
}
static Vector4 *vec4_user_defined(const Scalar& _v0, const Scalar& _v1, const Scalar& _v2, const Scalar& _v3) {
return new Vector4(_v0, _v1, _v2, _v3);
}
};
}
template<class Scalar, class Vector>
void defInitMod(class_< OpenMesh::VectorT<Scalar, 2> > &classVector) {
classVector
.def("__init__", make_constructor(&Factory<Scalar>::vec2_default))
.def("__init__", make_constructor(&Factory<Scalar>::vec2_user_defined))
;
}
template<class Scalar, class Vector>
void defInitMod(class_< OpenMesh::VectorT<Scalar, 3> > &classVector) {
Vector (Vector::*cross)(const Vector&) const = &Vector::operator%;
classVector
.def("__init__", make_constructor(&Factory<Scalar>::vec3_default))
.def("__init__", make_constructor(&Factory<Scalar>::vec3_user_defined))
.def("__mod__", cross)
;
def("cross", cross);
}
template<class Scalar, class Vector>
void defInitMod(class_< OpenMesh::VectorT<Scalar, 4> > &classVector) {
classVector
.def("__init__", make_constructor(&Factory<Scalar>::vec4_default))
.def("__init__", make_constructor(&Factory<Scalar>::vec4_user_defined))
;
}
/**
* Expose a vector type to %Python.
*
* This function template is used to expose vectors to %Python. The template
* parameters are used to instantiate the appropriate vector type.
*
* @tparam Scalar A scalar type.
* @tparam N The dimension of the vector.
*
* @param _name The name of the vector type to be exposed.
*
* @note N must be either 2, 3 or 4.
*/
template<class Scalar, int N>
void expose_vec(const char *_name) {
typedef OpenMesh::VectorT<Scalar, N> Vector;
Scalar (Vector::*min_void)() const = &Vector::min;
Scalar (Vector::*max_void)() const = &Vector::max;
Vector (Vector::*max_vector)(const Vector&) const = &Vector::max;
Vector (Vector::*min_vector)(const Vector&) const = &Vector::min;
Scalar (Vector::*dot )(const Vector&) const = &Vector::operator|;
Scalar (Vector::*norm )(void ) const = &Vector::norm;
Scalar (Vector::*length )(void ) const = &Vector::length;
Scalar (Vector::*sqrnorm )(void ) const = &Vector::sqrnorm;
Vector& (Vector::*normalize )(void ) = &Vector::normalize;
Vector& (Vector::*normalize_cond)(void ) = &Vector::normalize_cond;
#if (_MSC_VER >= 1800 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
Vector (Vector::*normalized)() const = &Vector::normalized;
#else
const Vector (Vector::*normalized)() const = &Vector::normalized;
#endif
class_<Vector> classVector = class_<Vector>(_name);
classVector
.def("__setitem__", &set_item<Vector, Scalar>)
.def("__getitem__", &get_item<Vector, Scalar>)
.def(self == self)
.def(self != self)
.def(self *= Scalar())
.def(self /= Scalar())
.def(self * Scalar())
.def(Scalar() * self)
.def(self / Scalar())
.def(self *= self)
.def(self /= self)
.def(self -= self)
.def(self += self)
.def(self * self)
.def(self / self)
.def(self + self)
.def(self - self)
.def(-self)
.def(self | self)
.def("vectorize", &Vector::vectorize, return_internal_reference<>())
.def(self < self)
.def("dot", dot)
.def("norm", norm)
.def("length", length)
.def("sqrnorm", sqrnorm)
.def("normalized", normalized)
.def("normalize", normalize, return_internal_reference<>())
.def("normalize_cond", normalize_cond, return_internal_reference<>())
.def("l1_norm", &Vector::l1_norm)
.def("l8_norm", &Vector::l8_norm)
.def("max", max_void)
.def("max_abs", &Vector::max_abs)
.def("min", min_void)
.def("min_abs", &Vector::min_abs)
.def("mean", &Vector::mean)
.def("mean_abs", &Vector::mean_abs)
.def("minimize", &Vector::minimize, return_internal_reference<>())
.def("minimized", &Vector::minimized)
.def("maximize", &Vector::maximize, return_internal_reference<>())
.def("maximized", &Vector::maximized)
.def("min", min_vector)
.def("max", max_vector)
.def("size", &Vector::size)
.staticmethod("size")
.def("vectorized", &Vector::vectorized)
.staticmethod("vectorized")
;
defInitMod<Scalar, Vector>(classVector);
}
} // namespace OpenMesh
} // namespace Python
#endif