Merge branch 'rm-python' into 'master'
remove the python bindings from this project See merge request OpenMesh/OpenMesh!159
This commit is contained in:
@@ -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
|
||||
|
||||
112
CI/ci-mac.sh
112
CI/ci-mac.sh
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -129,12 +129,6 @@ endif()
|
||||
|
||||
add_subdirectory (Doc)
|
||||
|
||||
# ========================================================================
|
||||
# Include Python interface
|
||||
# ========================================================================
|
||||
|
||||
add_subdirectory (src/Python)
|
||||
|
||||
# ========================================================================
|
||||
# Bundle generation (Targets exist, now configure them)
|
||||
# ========================================================================
|
||||
|
||||
@@ -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"
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
**/
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user