diff --git a/CMakeLists.txt b/CMakeLists.txt
index c05a6284..ac86b67e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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." )
diff --git a/Doc/changelog.docu b/Doc/changelog.docu
index cf4bb4e4..d940fae4 100644
--- a/Doc/changelog.docu
+++ b/Doc/changelog.docu
@@ -9,6 +9,28 @@
| 6.2 (2016/07/11) |
diff --git a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh
index dd54f59d..9b8fa4d9 100644
--- a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh
+++ b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh
@@ -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;
diff --git a/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc b/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc
index c5f8a9d0..e5d4a87f 100644
--- a/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc
+++ b/src/OpenMesh/Apps/Unsupported/OsgViewer/osgviewer.cc
@@ -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 obj(new mesh_t);
#else
std::auto_ptr obj(new mesh_t);
diff --git a/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc b/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc
index b261c6b6..c939fb39 100644
--- a/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc
+++ b/src/OpenMesh/Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc
@@ -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
diff --git a/src/OpenMesh/Core/CMakeLists.txt b/src/OpenMesh/Core/CMakeLists.txt
index 67c37ea1..83b11eb2 100644
--- a/src/OpenMesh/Core/CMakeLists.txt
+++ b/src/OpenMesh/Core/CMakeLists.txt
@@ -3,7 +3,6 @@ include (ACGCommon)
include_directories (
../..
${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/src
)
# source code directories
diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh
index 28ad0b71..0f771fd4 100644
--- a/src/OpenMesh/Core/Geometry/Vector11T.hh
+++ b/src/OpenMesh/Core/Geometry/Vector11T.hh
@@ -366,8 +366,8 @@ class VectorT {
template
auto operator% (const VectorT &_rhs) const ->
typename std::enable_ifvalues_[0] * _rhs[0] -
- this->values_[0] * _rhs[0]),
+ VectorT>::type {
return {
values_[1] * _rhs[2] - values_[2] * _rhs[1],
diff --git a/src/OpenMesh/Core/Geometry/VectorT.hh b/src/OpenMesh/Core/Geometry/VectorT.hh
index b79882b4..d8c8f2b1 100644
--- a/src/OpenMesh/Core/Geometry/VectorT.hh
+++ b/src/OpenMesh/Core/Geometry/VectorT.hh
@@ -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
diff --git a/src/OpenMesh/Core/IO/reader/STLReader.cc b/src/OpenMesh/Core/IO/reader/STLReader.cc
index 8e4b9b63..6dd8569b 100644
--- a/src/OpenMesh/Core/IO/reader/STLReader.cc
+++ b/src/OpenMesh/Core/IO/reader/STLReader.cc
@@ -55,12 +55,20 @@
#include
#include
+#include
// OpenMesh
#include
#include
#include
+//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
+ 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);
- // open file
- FILE* in = fopen(_filename.c_str(), "rb");
- if (!in) return NONE;
+ // read number of triangles
+ char dummy[100];
+ fread(dummy, 1, 80, in);
+ size_t nT = read_int(in, swapFlag);
- // determine endian mode
- union { unsigned int i; unsigned char c[4]; } endian_test;
- endian_test.i = 1;
- bool swapFlag = (endian_test.c[3] == 1);
+ // 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);
- // 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);
+ // if sizes match -> it's STLB
+ return (binary_size == file_size ? STLB : NONE);
}
diff --git a/src/OpenMesh/Core/Mesh/IteratorsT.hh b/src/OpenMesh/Core/Mesh/IteratorsT.hh
index d12e5eb0..ca0d31e9 100644
--- a/src/OpenMesh/Core/Mesh/IteratorsT.hh
+++ b/src/OpenMesh/Core/Mesh/IteratorsT.hh
@@ -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
auto operator+=(int amount) ->
typename std::enable_if<
diff --git a/src/OpenMesh/Core/System/config.h b/src/OpenMesh/Core/System/config.h
index b247f812..8662bde1 100644
--- a/src/OpenMesh/Core/System/config.h
+++ b/src/OpenMesh/Core/System/config.h
@@ -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
diff --git a/src/OpenMesh/Core/System/mostream.hh b/src/OpenMesh/Core/System/mostream.hh
index f079b454..c197a49b 100644
--- a/src/OpenMesh/Core/System/mostream.hh
+++ b/src/OpenMesh/Core/System/mostream.hh
@@ -70,7 +70,7 @@
#include
#include
-#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
+#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ )
#include
#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 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 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
diff --git a/src/OpenMesh/Core/Utils/PropertyContainer.hh b/src/OpenMesh/Core/Utils/PropertyContainer.hh
index 53584bb2..ae8d9dfc 100644
--- a/src/OpenMesh/Core/Utils/PropertyContainer.hh
+++ b/src/OpenMesh/Core/Utils/PropertyContainer.hh
@@ -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.
*/
diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh
index f05903a9..2f38ca40 100644
--- a/src/OpenMesh/Core/Utils/PropertyManager.hh
+++ b/src/OpenMesh/Core/Utils/PropertyManager.hh
@@ -92,7 +92,7 @@ namespace OpenMesh {
*/
template
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 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
+ 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
+ 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
+ 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
+ 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 makePropertyManagerFromExistingOrNew(MeshT &mes
return PropertyManager::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
+PropertyManager makePropertyManagerFromExistingOrNew(
+ MeshT &mesh, const char *propname,
+ const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
+ const PROP_VALUE &init_value) {
+ return PropertyManager::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
+PropertyManager makePropertyManagerFromExistingOrNew(
+ MeshT &mesh, const char *propname,
+ const ITERATOR_RANGE &range,
+ const PROP_VALUE &init_value) {
+ return makePropertyManagerFromExistingOrNew(
+ mesh, propname, range.begin(), range.end(), init_value);
+}
+
} /* namespace OpenMesh */
#endif /* PROPERTYMANAGER_HH_ */
diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.cc b/src/OpenMesh/Tools/Decimater/DecimaterT.cc
index 31c47103..a7e18dce 100644
--- a/src/OpenMesh/Tools/Decimater/DecimaterT.cc
+++ b/src/OpenMesh/Tools/Decimater/DecimaterT.cc
@@ -78,7 +78,7 @@ template
DecimaterT::DecimaterT(Mesh& _mesh) :
BaseDecimaterT(_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::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(new DeciHeap(HI));
#else
heap_ = std::auto_ptr(new DeciHeap(HI));
@@ -282,7 +282,7 @@ size_t DecimaterT::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(new DeciHeap(HI));
#else
heap_ = std::auto_ptr(new DeciHeap(HI));
diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.hh b/src/OpenMesh/Tools/Decimater/DecimaterT.hh
index c31b2be6..2c71a093 100644
--- a/src/OpenMesh/Tools/Decimater/DecimaterT.hh
+++ b/src/OpenMesh/Tools/Decimater/DecimaterT.hh
@@ -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 heap_;
#else
std::auto_ptr heap_;
diff --git a/src/OpenMesh/Tools/Utils/HeapT.hh b/src/OpenMesh/Tools/Utils/HeapT.hh
index 47e0b184..5a28ff7f 100644
--- a/src/OpenMesh/Tools/Utils/HeapT.hh
+++ b/src/OpenMesh/Tools/Utils/HeapT.hh
@@ -79,7 +79,7 @@
#include "Config.hh"
#include
#include
-#if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#include
#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))
diff --git a/src/OpenMesh/Tools/VDPM/ViewingParameters.cc b/src/OpenMesh/Tools/VDPM/ViewingParameters.cc
index 2036e2fb..065c9319 100644
--- a/src/OpenMesh/Tools/VDPM/ViewingParameters.cc
+++ b/src/OpenMesh/Tools/VDPM/ViewingParameters.cc
@@ -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
diff --git a/src/Python/Vector.hh b/src/Python/Vector.hh
index 933b730a..31e3ff34 100644
--- a/src/Python/Vector.hh
+++ b/src/Python/Vector.hh
@@ -190,4 +190,4 @@ void expose_vec(const char *_name) {
} // namespace OpenMesh
} // namespace Python
-#endif
+#endif
\ No newline at end of file
diff --git a/src/Unittests/unittests_cpp_11_features.cc b/src/Unittests/unittests_cpp_11_features.cc
index f50e0a9c..a001cf9c 100644
--- a/src/Unittests/unittests_cpp_11_features.cc
+++ b/src/Unittests/unittests_cpp_11_features.cc
@@ -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__)
/*
*/
diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc
index 5ee75c62..7a1f1d21 100644
--- a/src/Unittests/unittests_propertymanager.cc
+++ b/src/Unittests/unittests_propertymanager.cc
@@ -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, 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::VPropHandleT, 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, 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::EPropHandleT, 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, 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::FPropHandleT, 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, 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, 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, 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
bool has_property(const Mesh& _mesh, const std::string& _name) {
diff --git a/src/Unittests/unittests_vector_type.cc b/src/Unittests/unittests_vector_type.cc
index 7c1dd5a1..ef86ccad 100644
--- a/src/Unittests/unittests_vector_type.cc
+++ b/src/Unittests/unittests_vector_type.cc
@@ -3,6 +3,10 @@
#include
#include
+#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+#include
+#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;
+
+ EXPECT_EQ(1, x1);
+ EXPECT_EQ(42, obj.padding);
+ EXPECT_EQ(6.0f, vec3[0]);
+ EXPECT_EQ(8.0f, vec3[1]);
+ EXPECT_EQ(10.0f, vec3[2]);
+ EXPECT_EQ(12.0f, vec3[3]);
+}
+
+TEST_F(OpenMeshVectorGCCBugTest, alignment_bug) {
+ /*
+ * 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)(*this);
+}
+
+
}
|