Merge branch 'master' into use_cmake_GTest_finder

This commit is contained in:
Jan Möbius
2018-10-30 10:19:51 +01:00
15 changed files with 1016 additions and 189 deletions

View File

@@ -38,13 +38,13 @@ IF "%BUILD_PLATFORM%" == "VS2013" (
set GENERATOR=Visual Studio 12%ARCH_VS% set GENERATOR=Visual Studio 12%ARCH_VS%
set VS_PATH="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com" set VS_PATH="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com"
IF "%ARCHITECTURE%" == "x64" ( IF "%ARCHITECTURE%" == "x64" (
set QT_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_64_opengl set QT_INSTALL_PATH=E:\Qt\Qt5.7.0\5.7\msvc2013_64
set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_64_opengl set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.7.0\5.7\msvc2013_64
) )
IF "%ARCHITECTURE%" == "x32" ( IF "%ARCHITECTURE%" == "x32" (
set QT_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_opengl set QT_INSTALL_PATH=E:\Qt\Qt5.7.0\5.7\msvc2013
set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.3.1-vs2013-%STRING_ARCH%\5.3\msvc2013_opengl set QT_BASE_CONFIG=-DQT5_INSTALL_PATH=E:\Qt\Qt5.7.0\5.7\msvc2013
) )
) )
@@ -98,6 +98,7 @@ IF "%APPS%" == "ON" (
ECHO "=============================================================" ECHO "============================================================="
ECHO "=============================================================" ECHO "============================================================="
ECHO "Building with :" ECHO "Building with :"
whoami
ECHO "ARCHITECTURE : %ARCHITECTURE%" ECHO "ARCHITECTURE : %ARCHITECTURE%"
ECHO "BUILD_PLATFORM : %BUILD_PLATFORM%" ECHO "BUILD_PLATFORM : %BUILD_PLATFORM%"
ECHO "GTESTVERSION : %GTESTVERSION%" ECHO "GTESTVERSION : %GTESTVERSION%"

View File

@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.6) cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
# Set and enforce C++-11 flags # Set and enforce C++-11 flags

View File

@@ -9,9 +9,25 @@
<tr valign=top><td><b>7.2</b> (?/?/?)</td><td> <tr valign=top><td><b>7.2</b> (?/?/?)</td><td>
<b>Core</b>
<ul>
<li>TriConnectivity: Added two functions split_edge and split_edge_copy to mask the PolyConnectivity functions of the same name (Prevents creation of valence 2 vertices on trimeshes)</li>
</ul>
<b>IO</b> <b>IO</b>
<ul> <ul>
<li>PLY Reader: Allowing the PLY reader to read custom face ( Thanks to morgan Leborgne for the patch)</li> <li>PLY Reader: Allowing the PLY reader to read custom face ( Thanks to morgan Leborgne for the patch)</li>
<li>PLY Reader: Fixed endless loop on unknown property list type</li>
</ul>
<b>Tools</b>
<ul>
<li>SmartTagger: Added the SmartTagger class to tag primitives (O(1) reset )</li>
</ul>
<b>Build System</b>
<ul>
<li>Rename the DEPRECATED macro into OM_DEPRECATED to prevent a macro clash with Intel MKL (Thanks to Morgan Leborgne for the patch)</li>
</ul> </ul>

View File

@@ -6,6 +6,7 @@
\li \subpage subdivider_docu \li \subpage subdivider_docu
\li \subpage vdpm_docu \li \subpage vdpm_docu
\li \subpage smoother_docu \li \subpage smoother_docu
\li \subpage smarttagger_docu
\li Miscellaneous \li Miscellaneous
OpenMesh::StripifierT OpenMesh::StripifierT

View File

@@ -30,12 +30,14 @@ function (acg_print_configure_header _id _name)
acg_color_message ("${_escape}[40;37m* Package : ${_escape}[32m${_project} ${_escape}[37m *${_escape}[0m") acg_color_message ("${_escape}[40;37m* Package : ${_escape}[32m${_project} ${_escape}[37m *${_escape}[0m")
acg_color_message ("${_escape}[40;37m* Version : ${_escape}[32m${_version} ${_escape}[37m *${_escape}[0m") acg_color_message ("${_escape}[40;37m* Version : ${_escape}[32m${_version} ${_escape}[37m *${_escape}[0m")
if ( NOT WIN32 )
# Just artistic. remove 2 spaces for release to make it look nicer ;-) # Just artistic. remove 2 spaces for release to make it look nicer ;-)
if (${CMAKE_BUILD_TYPE} MATCHES "Debug") if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m") acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m")
else() else()
acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m") acg_color_message ("${_escape}[40;37m* Type : ${_escape}[32m${CMAKE_BUILD_TYPE} ${_escape}[37m *${_escape}[0m")
endif() endif()
endif()
acg_color_message ("${_escape}[40;37m************************************************************${_escape}[0m") acg_color_message ("${_escape}[40;37m************************************************************${_escape}[0m")
endfunction () endfunction ()

View File

@@ -82,6 +82,7 @@
#include <OpenMesh/Core/IO/writer/STLWriter.hh> #include <OpenMesh/Core/IO/writer/STLWriter.hh>
#include <OpenMesh/Core/IO/writer/OMWriter.hh> #include <OpenMesh/Core/IO/writer/OMWriter.hh>
#include <OpenMesh/Core/IO/writer/PLYWriter.hh> #include <OpenMesh/Core/IO/writer/PLYWriter.hh>
#include <OpenMesh/Core/IO/writer/VTKWriter.hh>
//=== NAMESPACES ============================================================== //=== NAMESPACES ==============================================================
@@ -104,6 +105,7 @@ static BaseWriter* OFFWriterInstance = &OFFWriter();
static BaseWriter* STLWriterInstance = &STLWriter(); static BaseWriter* STLWriterInstance = &STLWriter();
static BaseWriter* OMWriterInstance = &OMWriter(); static BaseWriter* OMWriterInstance = &OMWriter();
static BaseWriter* PLYWriterInstance = &PLYWriter(); static BaseWriter* PLYWriterInstance = &PLYWriter();
static BaseWriter* VTKWriterInstance = &VTKWriter();
//============================================================================= //=============================================================================

View File

@@ -1240,13 +1240,15 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
if (listIndexType == "uint8") { if (listIndexType == "uint8") {
indexType = ValueTypeUINT8; indexType = ValueTypeUINT8;
} else if (listIndexType == "uint16") {
indexType = ValueTypeUINT16;
} else if (listIndexType == "uchar") { } else if (listIndexType == "uchar") {
indexType = ValueTypeUCHAR; indexType = ValueTypeUCHAR;
} else if (listIndexType == "int") { } else if (listIndexType == "int") {
indexType = ValueTypeINT; indexType = ValueTypeINT;
} else { } else {
omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl; omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl;
continue; return false;
} }
entryType = get_property_type(listEntryType, listEntryType); entryType = get_property_type(listEntryType, listEntryType);

View File

@@ -470,7 +470,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
To be save, you can use the CW/CCW circulator definitions, which behave\ To be save, you can use the CW/CCW circulator definitions, which behave\
the same as the original ones, without the previously mentioned issues." the same as the original ones, without the previously mentioned issues."
DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
#endif // NO_DECREMENT_DEPRECATED_WARNINGS #endif // NO_DECREMENT_DEPRECATED_WARNINGS
GenericCirculatorT_DEPRECATED& operator--() { GenericCirculatorT_DEPRECATED& operator--() {
assert(this->mesh_); assert(this->mesh_);
@@ -488,7 +488,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
/// Post-decrement /// Post-decrement
#ifndef NO_DECREMENT_DEPRECATED_WARNINGS #ifndef NO_DECREMENT_DEPRECATED_WARNINGS
DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
#undef DECREMENT_DEPRECATED_WARNINGS_TEXT #undef DECREMENT_DEPRECATED_WARNINGS_TEXT
#endif //NO_DECREMENT_DEPRECATED_WARNINGS #endif //NO_DECREMENT_DEPRECATED_WARNINGS
GenericCirculatorT_DEPRECATED operator--(int) { GenericCirculatorT_DEPRECATED operator--(int) {
@@ -542,7 +542,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_); return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
} }
DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.") OM_DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
/** /**
* \deprecated * \deprecated
* current_halfedge_handle() is an implementation detail and should not * current_halfedge_handle() is an implementation detail and should not
@@ -552,7 +552,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
return this->heh_; return this->heh_;
} }
DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.") OM_DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
/** /**
* \deprecated * \deprecated
* Do not use this error prone implicit cast. Compare to the * Do not use this error prone implicit cast. Compare to the
@@ -567,7 +567,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
* \deprecated * \deprecated
* This function clutters your code. Use dereferencing operators -> and * instead. * This function clutters your code. Use dereferencing operators -> and * instead.
*/ */
DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
value_type handle() const { value_type handle() const {
return **this; return **this;
} }
@@ -578,7 +578,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
* Implicit casts of iterators are unsafe. Use dereferencing operators * Implicit casts of iterators are unsafe. Use dereferencing operators
* -> and * instead. * -> and * instead.
*/ */
DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
operator value_type() const { operator value_type() const {
return **this; return **this;
} }

View File

@@ -126,7 +126,7 @@ class GenericIteratorT {
* \deprecated * \deprecated
* This function clutters your code. Use dereferencing operators -> and * instead. * This function clutters your code. Use dereferencing operators -> and * instead.
*/ */
DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
value_handle handle() const { value_handle handle() const {
return hnd_; return hnd_;
} }
@@ -137,7 +137,7 @@ class GenericIteratorT {
* Implicit casts of iterators are unsafe. Use dereferencing operators * Implicit casts of iterators are unsafe. Use dereferencing operators
* -> and * instead. * -> and * instead.
*/ */
DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
operator value_handle() const { operator value_handle() const {
return hnd_; return hnd_;
} }

View File

@@ -162,27 +162,63 @@ public:
* *
* \note The properties of the new edges, halfedges, and faces will be undefined! * \note The properties of the new edges, halfedges, and faces will be undefined!
* *
* @param _eh Edge handle that should be splitted * @param _eh Edge handle that should be split
* @param _vh Vertex handle that will be inserted at the edge * @param _vh Vertex handle that will be inserted at the edge
*/ */
void split(EdgeHandle _eh, VertexHandle _vh); void split(EdgeHandle _eh, VertexHandle _vh);
/** \brief Edge split (= 2-to-4 split) /** \brief Edge split (= 2-to-4 split)
*
* *
* The function will introduce two new faces ( non-boundary case) or * The function will introduce two new faces ( non-boundary case) or
* one additional face (if edge is boundary) * one additional face (if edge is boundary)
* *
* \note The properties of the new edges will be adjusted to the properties of the original edge * \note The properties of the new edges, halfedges, and faces will be undefined!
* \note The properties of the new faces and halfedges will be undefined
* *
* @param _eh Edge handle that should be splitted * \note This is an override to prevent a direct call to PolyConnectivity split_edge,
* which would introduce a singular vertex with valence 2 which is not allowed
* on TriMeshes
*
* @param _eh Edge handle that should be split
* @param _vh Vertex handle that will be inserted at the edge
*/
inline void split_edge(EdgeHandle _eh, VertexHandle _vh) { TriConnectivity::split(_eh, _vh); }
/** \brief Edge split (= 2-to-4 split)
*
* The function will introduce two new faces ( non-boundary case) or
* one additional face (if edge is boundary)
*
* \note The properties of the new edges and faces will be adjusted to the
* properties of the original edge and face
* \note The properties of the new halfedges will be undefined
*
* @param _eh Edge handle that should be split
* @param _vh Vertex handle that will be inserted at the edge * @param _vh Vertex handle that will be inserted at the edge
*/ */
void split_copy(EdgeHandle _eh, VertexHandle _vh); void split_copy(EdgeHandle _eh, VertexHandle _vh);
/** \brief Edge split (= 2-to-4 split)
*
* The function will introduce two new faces ( non-boundary case) or
* one additional face (if edge is boundary)
*
* \note The properties of the new edges and faces will be adjusted to the
* properties of the original edge and face
* \note The properties of the new halfedges will be undefined
*
* \note This is an override to prevent a direct call to PolyConnectivity split_edge_copy,
* which would introduce a singular vertex with valence 2 which is not allowed
* on TriMeshes
*
* @param _eh Edge handle that should be split
* @param _vh Vertex handle that will be inserted at the edge
*/
inline void split_edge_copy(EdgeHandle _eh, VertexHandle _vh) { TriConnectivity::split_copy(_eh, _vh); }
/** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function). /** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function).
* *
* @param _fh Face handle that should be splitted * @param _fh Face handle that should be split
* @param _vh Vertex handle that will be inserted at the face * @param _vh Vertex handle that will be inserted at the face
*/ */
inline void split(FaceHandle _fh, VertexHandle _vh) inline void split(FaceHandle _fh, VertexHandle _vh)
@@ -190,7 +226,7 @@ public:
/** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function). /** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function).
* *
* @param _fh Face handle that should be splitted * @param _fh Face handle that should be split
* @param _vh Vertex handle that will be inserted at the face * @param _vh Vertex handle that will be inserted at the face
*/ */
inline void split_copy(FaceHandle _fh, VertexHandle _vh) inline void split_copy(FaceHandle _fh, VertexHandle _vh)

View File

@@ -83,17 +83,17 @@
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
# define DEPRECATED(msg) __declspec(deprecated(msg)) # define OM_DEPRECATED(msg) __declspec(deprecated(msg))
#elif defined(__GNUC__) #elif defined(__GNUC__)
# if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40500 /* Test for GCC >= 4.5.0 */ # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40500 /* Test for GCC >= 4.5.0 */
# define DEPRECATED(msg) __attribute__ ((deprecated(msg))) # define OM_DEPRECATED(msg) __attribute__ ((deprecated(msg)))
# else # else
# define DEPRECATED(msg) __attribute__ ((deprecated)) # define OM_DEPRECATED(msg) __attribute__ ((deprecated))
# endif # endif
#elif defined(__clang__) #elif defined(__clang__)
# define DEPRECATED(msg) __attribute__ ((deprecated(msg))) # define OM_DEPRECATED(msg) __attribute__ ((deprecated(msg)))
#else #else
# define DEPRECATED(msg) # define OM_DEPRECATED(msg)
#endif #endif
typedef unsigned int uint; typedef unsigned int uint;

View File

@@ -0,0 +1,212 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#define OPENMESH_SMARTTAGGERT_C
//== INCLUDES =================================================================
#include "SmartTaggerT.hh"
#include <iostream>
#include <limits>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== IMPLEMENTATION ==========================================================
template <class Mesh, class EHandle, class EPHandle>
SmartTaggerT<Mesh, EHandle, EPHandle>::
SmartTaggerT(Mesh& _mesh, unsigned int _tag_range)
: mesh_(_mesh),
current_base_(0),
tag_range_(_tag_range)
{
// add new property
mesh_.add_property(ep_tag_);
// reset all tags once
all_tags_to_zero();
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
SmartTaggerT<Mesh, EHandle, EPHandle>::
~SmartTaggerT()
{
mesh_.remove_property(ep_tag_);
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
void
SmartTaggerT<Mesh, EHandle, EPHandle>::
untag_all()
{
unsigned int max_uint = std::numeric_limits<unsigned int>::max();
if( current_base_ < max_uint - 2*tag_range_)
current_base_ += tag_range_;
else
{
//overflow -> reset all tags
#ifdef STV_DEBUG_CHECKS
std::cerr << "Tagging Overflow occured...\n";
#endif
current_base_ = 0;
all_tags_to_zero();
}
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
void
SmartTaggerT<Mesh, EHandle, EPHandle>::
untag_all( const unsigned int _new_tag_range)
{
set_tag_range(_new_tag_range);
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
void
SmartTaggerT<Mesh, EHandle, EPHandle>::
set_tag ( const EHandle _eh, unsigned int _tag)
{
#ifdef STV_DEBUG_CHECKS
if( _tag > tag_range_)
std::cerr << "ERROR in set_tag tag range!!!\n";
#endif
mesh_.property(ep_tag_, _eh) = current_base_ + _tag;
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
unsigned int
SmartTaggerT<Mesh, EHandle, EPHandle>::
get_tag ( const EHandle _eh) const
{
unsigned int t = mesh_.property(ep_tag_, _eh);
#ifdef STV_DEBUG_CHECKS
if( t > current_base_ + tag_range_)
std::cerr << "ERROR in get_tag tag range!!!\n";
#endif
if( t<= current_base_) return 0;
else return t-current_base_;
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
bool
SmartTaggerT<Mesh, EHandle, EPHandle>::
is_tagged( const EHandle _eh) const
{
return bool(get_tag(_eh));
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
void
SmartTaggerT<Mesh, EHandle, EPHandle>::
set_tag_range( const unsigned int _tag_range)
{
if( _tag_range <= tag_range_)
{
untag_all();
tag_range_ = _tag_range;
}
else
{
tag_range_ = _tag_range;
untag_all();
}
}
//-----------------------------------------------------------------------------
template <class Mesh, class EHandle, class EPHandle>
void
SmartTaggerT<Mesh, EHandle, EPHandle>::
all_tags_to_zero()
{
// iterate over property vector
for(unsigned int i=0; i<mesh_.property(ep_tag_).n_elements(); ++i)
{
mesh_.property(ep_tag_)[i] = 0;
}
}
//=============================================================================
} // namespace OpenMesh
//=============================================================================

View File

@@ -0,0 +1,249 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#pragma once
//== INCLUDES =================================================================
// OpenMesh
#include <OpenMesh/Core/Utils/Property.hh>
#include <OpenMesh/Core/System/omstream.hh>
//== DEFINES ==================================================================
#define STV_DEBUG_CHECKS
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== FORWARD DECLARATIONS =====================================================
// Smarttagging for vertices
template< class Mesh> class SmartTaggerVT;
// Smarttagging for edges
template< class Mesh> class SmartTaggerET;
// Smarttagging for faces
template< class Mesh> class SmartTaggerFT;
// Smarttagging for halfedges
template< class Mesh> class SmartTaggerHT;
//== CLASS DEFINITION =========================================================
/** \page smarttagger_docu Smart Tagger
The smart tagger can be used to tag vertices/halfedges/edges/faces on the mesh. It provides
an O(1) reset function to untag all primitives at once.
Usage:
\code
SmartTaggerVT< MeshType > tagger(mesh);
// Reset tagged flag on all vertices
tagger.untag_all();
// Check if something is tagged
bool tag = tagger.is_tagged(vh);
// Set tagged:
tagger.set_tag(vh);
\endcode
For details see OpenMesh::SmartTaggerT
*/
/** \brief Smart Tagger
*
* A tagger class to be used on OpenMesh. It provides an O(1) reset function for the property.
* - Smarttagging for vertices: SmartTaggerVT;
* - Smarttagging for edges: SmartTaggerET;
* - Smarttagging for faces: SmartTaggerFT;
* - Smarttagging for halfedges: SmartTaggerHT;
*
* Usage:
*
* \code
* SmartTaggerVT< MeshType >* tagger = new SmartTaggerVT< MeshType > (mesh_);
*
* // Reset tagged flag on all vertices
* tagger.untag_all();
*
* // Check if something is tagged
* bool tag = tagger.is_tagged(vh);
*
* // Set tagged:
* tagger.set_tag(vh);
* \endcode
*/
template <class Mesh, class EHandle, class EPHandle>
class SmartTaggerT
{
public:
/// Constructor
SmartTaggerT(Mesh& _mesh, unsigned int _tag_range = 1);
/// Destructor
~SmartTaggerT();
/** \brief untag all elements
*
*/
inline void untag_all();
/** \brief untag all elements and set new tag_range
*
* @param _new_tag_range New tag range of the tagger
*/
inline void untag_all( const unsigned int _new_tag_range);
/** \brief set tag to a value in [0..tag_range]
*
* @param _eh Edge handle for the tag
* @param _tag Tag value
*/
inline void set_tag ( const EHandle _eh, unsigned int _tag = 1);
/** \brief get tag value in range [0..tag_range]
*
* @param _eh Edge handle for the tag
* @return Current tag value at that edge
*/
inline unsigned int get_tag ( const EHandle _eh) const;
/** \brief overloaded member for boolean tags
*
* @param _eh Edge handle for the tag
* @return Current tag value at that edge
*/
inline bool is_tagged( const EHandle _eh) const;
/** \brief set new tag range and untag_all
*
* Set new tag range and reset tagger
*
* @param _tag_range New tag range of the tagger
*/
inline void set_tag_range( const unsigned int _tag_range);
protected:
inline void all_tags_to_zero();
protected:
// Reference to Mesh
Mesh& mesh_;
// property which holds the current tags
EPHandle ep_tag_;
// current tags range is [current_base_+1...current_base_+tag_range_]
unsigned int current_base_;
// number of different tagvalues available
unsigned int tag_range_;
};
//== SPECIALIZATION ===========================================================
// define standard Tagger
template< class Mesh>
class SmartTaggerVT
: public SmartTaggerT< Mesh, typename Mesh::VertexHandle, OpenMesh::VPropHandleT<unsigned int> >
{
public:
typedef SmartTaggerT< Mesh, typename Mesh::VertexHandle, OpenMesh::VPropHandleT<unsigned int> > BaseType;
SmartTaggerVT(Mesh& _mesh, unsigned int _tag_range = 1) : BaseType(_mesh, _tag_range) {}
};
template< class Mesh>
class SmartTaggerET
: public SmartTaggerT< Mesh, typename Mesh::EdgeHandle, OpenMesh::EPropHandleT<unsigned int> >
{
public:
typedef SmartTaggerT< Mesh, typename Mesh::EdgeHandle, OpenMesh::EPropHandleT<unsigned int> > BaseType;
SmartTaggerET(Mesh& _mesh, unsigned int _tag_range = 1) : BaseType(_mesh, _tag_range) {}
};
template< class Mesh>
class SmartTaggerFT
: public SmartTaggerT< Mesh, typename Mesh::FaceHandle, OpenMesh::FPropHandleT<unsigned int> >
{
public:
typedef SmartTaggerT< Mesh, typename Mesh::FaceHandle, OpenMesh::FPropHandleT<unsigned int> > BaseType;
SmartTaggerFT(Mesh& _mesh, unsigned int _tag_range = 1): BaseType(_mesh, _tag_range) {}
};
template< class Mesh>
class SmartTaggerHT
: public SmartTaggerT< Mesh, typename Mesh::HalfedgeHandle, OpenMesh::HPropHandleT<unsigned int> >
{
public:
typedef SmartTaggerT< Mesh, typename Mesh::HalfedgeHandle, OpenMesh::HPropHandleT<unsigned int> > BaseType;
SmartTaggerHT(Mesh& _mesh, unsigned int _tag_range = 1): BaseType(_mesh, _tag_range){}
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SMARTTAGGERT_C)
#define OPENMESH_SMARTTAGGERT_TEMPLATES
#include "SmartTaggerT.cc"
#endif

View File

@@ -728,4 +728,58 @@ TEST_F(OpenMeshReadWritePLY, LoadSimpleBinaryPLYWithExtraElements) {
EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!"; EXPECT_EQ(12u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
} }
/*
* Ignore a file that does not contain vertices and faces
*/
TEST_F(OpenMeshReadWritePLY, IgnoreNonMeshPlyFile) {
mesh_.clear();
std::stringstream data;
data << "ply" << "\n";
data << "format binary_little_endian 1.0" << "\n";
data << "comment Image data" << "\n";
data << "element image 0" << "\n";
data << "property list uint16 uint16 row" << "\n";
data << "end_header" << "\n";
OpenMesh::IO::Options options = OpenMesh::IO::Options::Binary;
bool ok = OpenMesh::IO::read_mesh(mesh_, data, ".ply", options);
EXPECT_TRUE(ok) << "This empty file should be readable without an error!";
EXPECT_EQ(0u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
EXPECT_EQ(0u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
EXPECT_EQ(0u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
}
/*
* Ignore a file that does not contain vertices and faces
*/
TEST_F(OpenMeshReadWritePLY, FailOnUnknownPropertyTypeForLists) {
mesh_.clear();
std::stringstream data;
data << "ply" << "\n";
data << "format binary_little_endian 1.0" << "\n";
data << "comment Image data" << "\n";
data << "element image 0" << "\n";
data << "property list blibb blubb row" << "\n";
data << "end_header" << "\n";
OpenMesh::IO::Options options = OpenMesh::IO::Options::Binary;
bool ok = OpenMesh::IO::read_mesh(mesh_, data, ".ply", options);
EXPECT_FALSE(ok) << "This file should fail to read!";
EXPECT_EQ(0u, mesh_.n_vertices()) << "The number of loaded vertices is not correct!";
EXPECT_EQ(0u, mesh_.n_edges()) << "The number of loaded edges is not correct!";
EXPECT_EQ(0u, mesh_.n_faces()) << "The number of loaded faces is not correct!";
}
} }

View File

@@ -0,0 +1,252 @@
#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <iostream>
#include <OpenMesh/Tools/SmartTagger/SmartTaggerT.hh>
namespace {
class OpenMeshSmartTagger : public OpenMeshBase {
protected:
// This function is called before each test is run
virtual void SetUp() {
// Do some initial stuff with the member data here...
}
// This function is called after all tests are through
virtual void TearDown() {
// Do some final stuff with the member data here...
}
// Member already defined in OpenMeshBase
//Mesh mesh_;
};
/*
* ====================================================================
* Define tests below
* ====================================================================
*/
/* Checks SmartTagger on vertices
*/
TEST_F(OpenMeshSmartTagger, SmartTaggerVertices) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[7];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
vhandle[5] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[4]);
mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ /|\
| \ / | \
| 1 | 5
| / \ | /
|/ \|/
3 ==== 4
*/
OpenMesh::SmartTaggerVT< Mesh > tagger(mesh_);
EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged after init!";
// Reset tagged flag on all vertices
tagger.untag_all();
EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged after first untag_all!";
// Set tagged:
tagger.set_tag(vhandle[2]);
tagger.set_tag(vhandle[4]);
EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged!";
EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged!";
EXPECT_TRUE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be tagged!";
EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged!";
EXPECT_TRUE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be tagged!";
EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged!";
// Reset tagged flag on all vertices
tagger.untag_all();
EXPECT_FALSE( tagger.is_tagged(vhandle[0] ) ) << "Vertex should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[1] ) ) << "Vertex should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[2] ) ) << "Vertex should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[3] ) ) << "Vertex should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[4] ) ) << "Vertex should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged(vhandle[5] ) ) << "Vertex should be untagged after second untag_all!";
}
/* Checks SmartTagger on vertices
*/
TEST_F(OpenMeshSmartTagger, SmartTaggerFaces) {
mesh_.clear();
// Add some vertices
Mesh::VertexHandle vhandle[7];
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0));
vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0));
vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0));
vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0));
vhandle[5] = mesh_.add_vertex(Mesh::Point(3, 0, 0));
// Add two faces
std::vector<Mesh::VertexHandle> face_vhandles;
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
Mesh::FaceHandle fh1 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[4]);
Mesh::FaceHandle fh2 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
Mesh::FaceHandle fh3 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[4]);
Mesh::FaceHandle fh4 = mesh_.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[4]);
Mesh::FaceHandle fh5 = mesh_.add_face(face_vhandles);
/* Test setup:
0 ==== 2
|\ /|\
| \ / | \
| 1 | 5
| / \ | /
|/ \|/
3 ==== 4
*/
OpenMesh::SmartTaggerFT< Mesh > tagger(mesh_);
EXPECT_FALSE( tagger.is_tagged( fh1 ) ) << "Face should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged( fh2 ) ) << "Face should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged( fh3 ) ) << "Face should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged( fh4 ) ) << "Face should be untagged after init!";
EXPECT_FALSE( tagger.is_tagged( fh5 ) ) << "Face should be untagged after init!";
// Reset tagged flag on all vertices
tagger.untag_all();
EXPECT_FALSE( tagger.is_tagged( fh1 ) ) << "Face should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh2 ) ) << "Face should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh3 ) ) << "Face should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh4 ) ) << "Face should be untagged after first untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh5 ) ) << "Face should be untagged after first untag_all!";
// Set tagged:
tagger.set_tag(fh3);
tagger.set_tag(fh5);
EXPECT_FALSE( tagger.is_tagged(fh1 ) ) << "Face should be untagged!";
EXPECT_FALSE( tagger.is_tagged(fh2 ) ) << "Face should be untagged!";
EXPECT_TRUE( tagger.is_tagged(fh3 ) ) << "Face should be tagged!";
EXPECT_FALSE( tagger.is_tagged(fh4 ) ) << "Face should be tagged!";
EXPECT_TRUE( tagger.is_tagged(fh5 ) ) << "Face should be tagged!";
// Reset tagged flag on all vertices
tagger.untag_all();
EXPECT_FALSE( tagger.is_tagged( fh1 ) ) << "Face should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh2 ) ) << "Face should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh3 ) ) << "Face should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh4 ) ) << "Face should be untagged after second untag_all!";
EXPECT_FALSE( tagger.is_tagged( fh5 ) ) << "Face should be untagged after second untag_all!";
}
}