Commit 8dc194e8 authored by Alexander Dielen's avatar Alexander Dielen

Merge branch 'master' into 'BuildPythonWindows'

# Conflicts:
#   src/Python/Vector.hh
parents f90c6da1 4f209d9f
Pipeline #2809 passed with stage
in 21 minutes and 8 seconds
......@@ -7,6 +7,14 @@ if("${PROJECT_NAME}" STREQUAL "")
project (OpenMesh)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.9" OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "4.9")
message(WARNING "Your version of GCC contains an optimizer bug. Please verify that you do not use -O3!")
string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE_NEW "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE_NEW}" CACHE STRING "" FORCE)
endif()
endif()
if ( WIN32 )
# This is the base directory for windows library search used in the finders we ship.
set(CMAKE_WINDOWS_LIBS_DIR "c:/libs" CACHE STRING "Default Library search dir on windows." )
......
......@@ -9,6 +9,28 @@
<tr valign=top><td><b>6.3</b> (?/?/?)</td><td>
<b>Core</b>
<ul>
<li>Fixed type pun warning with gcc-6</li>
<li>Fixed incorrect type of hash function for boost causing a warning with clang</li>
</ul>
<b>IO</b>
<ul>
<li>STL Reader: Identify stl files containing solid keyword as ASCII type</li>
</ul>
<b>General</b>
<ul>
<li>Fixed undefined MSVC macro warning (Thanks to Xan for the patch)</li>
</ul>
<b>Build System</b>
<ul>
<li>Removed unnecessary include dir from Core Cmakelist (Thanks to Xan for the patch)</li>
</ul>
</tr>
<tr valign=top><td><b>6.2</b> (2016/07/11)</td><td>
......
......@@ -114,7 +114,7 @@ public:
typedef Decimater::ModNormalFlippingT< mesh_t >::Handle mod_nf_t;
// object types
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
typedef std::unique_ptr< decimater_t > decimater_o;
#else
typedef std::auto_ptr< decimater_t > decimater_o;
......
......@@ -131,7 +131,7 @@ public:
bool bind( osg::GeometryPtr geo )
{
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
std::unique_ptr<mesh_t> obj(new mesh_t);
#else
std::auto_ptr<mesh_t> obj(new mesh_t);
......
......@@ -851,7 +851,7 @@ compute_screen_space_error(VHierarchyNodeHandle node_handle, VHierarchyNodeHandl
Vec3f residual;
Vec3f res;
Vec3f lp;
#if (_MSC_VER >= 1900 )
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) )
// Workaround for internal compiler error
Vec3f tri[3]{ {},{},{} };
#else
......
......@@ -3,7 +3,6 @@ include (ACGCommon)
include_directories (
../..
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# source code directories
......
......@@ -366,8 +366,8 @@ class VectorT {
template<typename OtherScalar>
auto operator% (const VectorT<OtherScalar, DIM> &_rhs) const ->
typename std::enable_if<DIM == 3,
VectorT<decltype(this->values_[0] * _rhs[0] -
this->values_[0] * _rhs[0]),
VectorT<decltype((*this)[0] * _rhs[0] -
(*this)[0] * _rhs[0]),
DIM>>::type {
return {
values_[1] * _rhs[2] - values_[2] * _rhs[1],
......
......@@ -60,7 +60,7 @@
// macro expansion and preprocessor defines
// don't work properly.
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
#include "Vector11T.hh"
#else
#ifndef DOXYGEN
......
......@@ -55,12 +55,20 @@
#include <float.h>
#include <fstream>
#include <cstring>
// OpenMesh
#include <OpenMesh/Core/IO/BinaryHelper.hh>
#include <OpenMesh/Core/IO/reader/STLReader.hh>
#include <OpenMesh/Core/IO/IOManager.hh>
//comppare strings crossplatform ignorign case
#ifdef _WIN32
#define strnicmp _strnicmp
#else
#define strnicmp strncasecmp
#endif
//=== NAMESPACES ==============================================================
......@@ -447,41 +455,62 @@ _STLReader_::STL_Type
_STLReader_::
check_stl_type(const std::string& _filename) const
{
// assume it's binary stl, then file size is known from #triangles
// if size matches, it's really binary
// open file
FILE* in = fopen(_filename.c_str(), "rb");
if (!in) return NONE;
// determine endian mode
union { unsigned int i; unsigned char c[4]; } endian_test;
endian_test.i = 1;
bool swapFlag = (endian_test.c[3] == 1);
// read number of triangles
char dummy[100];
fread(dummy, 1, 80, in);
size_t nT = read_int(in, swapFlag);
// compute file size from nT
size_t binary_size = 84 + nT*50;
// get actual file size
size_t file_size(0);
rewind(in);
while (!feof(in))
file_size += fread(dummy, 1, 100, in);
fclose(in);
// if sizes match -> it's STLB
return (binary_size == file_size ? STLB : STLA);
// open file
std::ifstream ifs (_filename.c_str(), std::ifstream::binary);
if(!ifs.good())
{
omerr() << "could not open file" << _filename << std::endl;
return NONE;
}
//find first non whitespace character
std::string line = "";
std::size_t firstChar;
while(line.empty() && ifs.good())
{
std::getline(ifs,line);
firstChar = line.find_first_not_of("\t ");
}
//check for ascii keyword solid
if(strnicmp("solid",&line[firstChar],5) == 0)
{
return STLA;
}
ifs.close();
//if the file does not start with solid it is probably STLB
//check the file size to verify it.
//open the file
FILE* in = fopen(_filename.c_str(), "rb");
if (!in) return NONE;
// determine endian mode
union { unsigned int i; unsigned char c[4]; } endian_test;
endian_test.i = 1;
bool swapFlag = (endian_test.c[3] == 1);
// read number of triangles
char dummy[100];
fread(dummy, 1, 80, in);
size_t nT = read_int(in, swapFlag);
// compute file size from nT
size_t binary_size = 84 + nT*50;
// get actual file size
size_t file_size(0);
rewind(in);
while (!feof(in))
file_size += fread(dummy, 1, 100, in);
fclose(in);
// if sizes match -> it's STLB
return (binary_size == file_size ? STLB : NONE);
}
......
......@@ -170,7 +170,7 @@ class GenericIteratorT {
return cpy;
}
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
template<class T = value_handle>
auto operator+=(int amount) ->
typename std::enable_if<
......
......@@ -102,7 +102,7 @@
typedef unsigned int uint;
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__))
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__))
#define OM_HAS_HASH
#endif
......
......@@ -70,7 +70,7 @@
#include <string>
#include <algorithm>
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#include <mutex>
#endif
......@@ -189,7 +189,7 @@ protected:
virtual int sync()
{
// If working on multiple threads, we need to serialize the output correctly (requires c++11 headers)
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
std::lock_guard<std::mutex> lck (serializer_);
#endif
......@@ -214,7 +214,7 @@ protected:
char c = traits_type::to_char_type(_c);
// If working on multiple threads, we need to serialize the output correctly (requires c++11 headers)
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
{
std::lock_guard<std::mutex> lck (serializer_);
buffer_.push_back(c);
......@@ -264,7 +264,7 @@ private:
bool enabled_;
// If working on multiple threads, we need to serialize the output correctly (requires c++11 headers)
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
std::mutex serializer_;
#endif
......
......@@ -204,7 +204,7 @@ public:
* In C++11 an beyond we can introduce more efficient and more legible
* implementations of the following methods.
*/
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
/**
* Reserves space for \p _n elements in all property vectors.
*/
......
......@@ -92,7 +92,7 @@ namespace OpenMesh {
*/
template<typename PROPTYPE, typename MeshT>
class PropertyManager {
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
public:
PropertyManager(const PropertyManager&) = delete;
PropertyManager& operator=(const PropertyManager&) = delete;
......@@ -167,7 +167,7 @@ class PropertyManager {
MeshT &getMesh() const { return *mesh_; }
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
/// Only for pre C++11 compatibility.
typedef PropertyManager<PROPTYPE, MeshT> Proxy;
......@@ -208,6 +208,42 @@ class PropertyManager {
return std::move(pm);
}
/**
* Like createIfNotExists() with two parameters except, if the property
* doesn't exist, it is initialized with the supplied value over
* the supplied range after creation. If the property already exists,
* this method has the exact same effect as the two parameter version.
* Lifecycle management is disabled in any case.
*
* @see makePropertyManagerFromExistingOrNew
*/
template<typename PROP_VALUE, typename ITERATOR_TYPE>
static PropertyManager createIfNotExists(MeshT &mesh, const char *propname,
const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
const PROP_VALUE &init_value) {
const bool exists = propertyExists(mesh, propname);
PropertyManager pm(mesh, propname, exists);
pm.retain();
if (!exists)
pm.set_range(begin, end, init_value);
return std::move(pm);
}
/**
* Like createIfNotExists() with two parameters except, if the property
* doesn't exist, it is initialized with the supplied value over
* the supplied range after creation. If the property already exists,
* this method has the exact same effect as the two parameter version.
* Lifecycle management is disabled in any case.
*
* @see makePropertyManagerFromExistingOrNew
*/
template<typename PROP_VALUE, typename ITERATOR_RANGE>
static PropertyManager createIfNotExists(MeshT &mesh, const char *propname,
const ITERATOR_RANGE &range, const PROP_VALUE &init_value) {
return createIfNotExists(
mesh, propname, range.begin(), range.end(), init_value);
}
PropertyManager duplicate(const char *clone_name) {
PropertyManager pm(*mesh_, clone_name, false);
......@@ -267,6 +303,27 @@ class PropertyManager {
return (Proxy)pm;
}
/**
* Like createIfNotExists() with two parameters except, if the property
* doesn't exist, it is initialized with the supplied value over
* the supplied range after creation. If the property already exists,
* this method has the exact same effect as the two parameter version.
* Lifecycle management is disabled in any case.
*
* @see makePropertyManagerFromExistingOrNew
*/
template<typename PROP_VALUE, typename ITERATOR_TYPE>
static Proxy createIfNotExists(MeshT &mesh, const char *propname,
const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
const PROP_VALUE &init_value) {
const bool exists = propertyExists(mesh, propname);
PropertyManager pm(mesh, propname, exists);
pm.retain();
if (!exists)
pm.set_range(begin, end, init_value);
return (Proxy)pm;
}
Proxy duplicate(const char *clone_name) {
PropertyManager pm(*mesh_, clone_name, false);
pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
......@@ -353,6 +410,14 @@ class PropertyManager {
(*this)[*begin] = value;
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
template<typename HandleTypeIteratorRange, typename PROP_VALUE>
void set_range(const HandleTypeIteratorRange &range,
const PROP_VALUE &value) {
set_range(range.begin(), range.end(), value);
}
#endif
/**
* Conveniently transfer the values managed by one property manager
* onto the values managed by a different property manager.
......@@ -466,5 +531,47 @@ PropertyManager<PROPTYPE, MeshT> makePropertyManagerFromExistingOrNew(MeshT &mes
return PropertyManager<PROPTYPE, MeshT>::createIfNotExists(mesh, propname);
}
/** \relates PropertyManager
* Like the two parameter version of makePropertyManagerFromExistingOrNew()
* except it initializes the property with the specified value over the
* specified range if it needs to be created. If the property already exists,
* this function has the exact same effect as the two parameter version.
*
* Creates a non-owning wrapper for a mesh property (no lifecycle management).
* If the given property does not exist, it is created.
*
* Intended for creating or accessing persistent properties.
*/
template<typename PROPTYPE, typename MeshT,
typename ITERATOR_TYPE, typename PROP_VALUE>
PropertyManager<PROPTYPE, MeshT> makePropertyManagerFromExistingOrNew(
MeshT &mesh, const char *propname,
const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
const PROP_VALUE &init_value) {
return PropertyManager<PROPTYPE, MeshT>::createIfNotExists(
mesh, propname, begin, end, init_value);
}
/** \relates PropertyManager
* Like the two parameter version of makePropertyManagerFromExistingOrNew()
* except it initializes the property with the specified value over the
* specified range if it needs to be created. If the property already exists,
* this function has the exact same effect as the two parameter version.
*
* Creates a non-owning wrapper for a mesh property (no lifecycle management).
* If the given property does not exist, it is created.
*
* Intended for creating or accessing persistent properties.
*/
template<typename PROPTYPE, typename MeshT,
typename ITERATOR_RANGE, typename PROP_VALUE>
PropertyManager<PROPTYPE, MeshT> makePropertyManagerFromExistingOrNew(
MeshT &mesh, const char *propname,
const ITERATOR_RANGE &range,
const PROP_VALUE &init_value) {
return makePropertyManagerFromExistingOrNew<PROPTYPE, MeshT>(
mesh, propname, range.begin(), range.end(), init_value);
}
} /* namespace OpenMesh */
#endif /* PROPERTYMANAGER_HH_ */
......@@ -78,7 +78,7 @@ template<class Mesh>
DecimaterT<Mesh>::DecimaterT(Mesh& _mesh) :
BaseDecimaterT<Mesh>(_mesh),
mesh_(_mesh),
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
heap_(nullptr)
#else
heap_(NULL)
......@@ -178,7 +178,7 @@ size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
// initialize heap
HeapInterface HI(mesh_, priority_, heap_position_);
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
heap_ = std::unique_ptr<DeciHeap>(new DeciHeap(HI));
#else
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
......@@ -282,7 +282,7 @@ size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
// initialize heap
HeapInterface HI(mesh_, priority_, heap_position_);
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
heap_ = std::unique_ptr<DeciHeap>(new DeciHeap(HI));
#else
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
......
......@@ -195,7 +195,7 @@ private: //------------------------------------------------------- private data
Mesh& mesh_;
// heap
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
std::unique_ptr<DeciHeap> heap_;
#else
std::auto_ptr<DeciHeap> heap_;
......
......@@ -79,7 +79,7 @@
#include "Config.hh"
#include <vector>
#include <OpenMesh/Core/System/omstream.hh>
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#include <utility>
#endif
......@@ -150,7 +150,7 @@ public:
/// Constructor
HeapT() : HeapVector() {}
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
/// Construct with a given \c HeapIterface.
HeapT(HeapInterface _interface)
: HeapVector(), interface_(std::move(_interface))
......
......@@ -92,7 +92,7 @@ update_viewing_configurations()
Vec3f trans;
// Workaround for internal compiler error on Visual Studio 2015 Update 1
#if (_MSC_VER >= 1900 )
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) )
Vec3f inv_rot[3]{ {},{},{} };
Vec3f normal[4]{ {},{},{},{} };
#else
......
......@@ -190,4 +190,4 @@ void expose_vec(const char *_name) {
} // namespace OpenMesh
} // namespace Python
#endif
#endif
\ No newline at end of file
......@@ -53,7 +53,7 @@ class OpenMesh_Triangle : public OpenMeshBase {
* ====================================================================
*/
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
/*
*/
......
......@@ -60,36 +60,76 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) {
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
OpenMesh::PropertyManager<
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
for (int i = 0; i < 4; ++i)
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
OpenMesh::PropertyManager<
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_FALSE(pm_e_bool[*e_it]);
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), true);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_TRUE(pm_e_bool[*e_it]);
OpenMesh::PropertyManager<
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_FALSE(pm_f_bool[*f_it]);
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), true);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_TRUE(pm_f_bool[*f_it]);
{
OpenMesh::PropertyManager<
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
for (int i = 0; i < 4; ++i)
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
OpenMesh::PropertyManager<
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_FALSE(pm_e_bool[*e_it]);
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), true);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_TRUE(pm_e_bool[*e_it]);
OpenMesh::PropertyManager<
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_FALSE(pm_f_bool[*f_it]);
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), true);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_TRUE(pm_f_bool[*f_it]);
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
/*
* Same thing again, this time with C++11 ranges.
*/
{
OpenMesh::PropertyManager<
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool2");
pm_v_bool.set_range(mesh_.vertices(), false);
for (int i = 0; i < 4; ++i)
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
pm_v_bool.set_range(mesh_.vertices(), true);
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
OpenMesh::PropertyManager<
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool2");
pm_e_bool.set_range(mesh_.edges(), false);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_FALSE(pm_e_bool[*e_it]);
pm_e_bool.set_range(mesh_.edges(), true);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_TRUE(pm_e_bool[*e_it]);
OpenMesh::PropertyManager<
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool2");
pm_f_bool.set_range(mesh_.faces(), false);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_FALSE(pm_f_bool[*f_it]);
pm_f_bool.set_range(mesh_.faces(), true);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_TRUE(pm_f_bool[*f_it]);
}
#endif
}
/*
......@@ -97,7 +137,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) {
* C++11 Specific Tests
* ====================================================================
*/
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
template<typename PropHandle, typename Mesh>
bool has_property(const Mesh& _mesh, const std::string& _name) {
......
......@@ -3,6 +3,10 @@
#include <iostream>
#include <list>
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#include <cstdint>
#endif
namespace {
class OpenMeshVectorTest : public testing::Test {
......@@ -84,7 +88,7 @@ TEST_F(OpenMeshVectorTest, VectorCasting) {
}
#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
TEST_F(OpenMeshVectorTest, cpp11_constructors) {
OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 };
......@@ -323,4 +327,76 @@ TEST_F(OpenMeshVectorTest, size_dim) {
EXPECT_EQ(2, v2i.dim());
}
class OpenMeshVectorGCCBugTest;
void trigger_alignment_bug(OpenMeshVectorGCCBugTest &obj);
/**
* This is a regression test for a GCC compiler bug.
* @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66598
* @see https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh/issues/32
*/
class OpenMeshVectorGCCBugTest : public testing::Test {
protected:
virtual void SetUp() {
/*
* WARNING: DO NOT CHANGE ANYTHGIN! Every single line, as
* pointless as it may look, is carefully crafted to provoke
* the GCC optimizer bug mentioned above.
*/
testfn = trigger_alignment_bug;
vec1 = OpenMesh::Vec4f(1.0f, 2.0f, 3.0f, 4.0f);
vec2 = OpenMesh::Vec4f(5.0f, 6.0f, 7.0f, 8.0f);
padding = 42;
}
virtual void TearDown() {
// Do some final stuff with the member data here...
}
public:
/*
* WARNING: DO NOT CHANGE ANYTHGIN! Every single line, as
* pointless as it may look, is carefully crafted to provoke
* the GCC optimizer bug mentioned above.
*/
int32_t padding;
OpenMesh::Vec4f vec1, vec2;
void (*testfn)(OpenMeshVectorGCCBugTest &obj);
OpenMesh::Vec4f &get_vec1() { return vec1; }
OpenMesh::Vec4f &get_vec2() { return vec2; }
};
void trigger_alignment_bug(OpenMeshVectorGCCBugTest &obj) {
/*
* WARNING: DO NOT CHANGE ANYTHGIN! Every single line, as
* pointless as it may look, is carefully crafted to provoke
* the GCC optimizer bug mentioned above.
*/
int x1 = 1;
OpenMesh::Vec4f vec3 = obj.get_vec1();
OpenMesh::Vec4f vec4 = obj.get_vec2();
vec3 += vec4;