Merge branch 'master' into 'BuildPythonWindows'
# Conflicts: # src/Python/Vector.hh
This commit is contained in:
@@ -7,6 +7,14 @@ if("${PROJECT_NAME}" STREQUAL "")
|
|||||||
project (OpenMesh)
|
project (OpenMesh)
|
||||||
endif()
|
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 )
|
if ( WIN32 )
|
||||||
# This is the base directory for windows library search used in the finders we ship.
|
# 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." )
|
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>
|
<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>
|
||||||
|
|
||||||
<tr valign=top><td><b>6.2</b> (2016/07/11)</td><td>
|
<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;
|
typedef Decimater::ModNormalFlippingT< mesh_t >::Handle mod_nf_t;
|
||||||
|
|
||||||
// object types
|
// 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;
|
typedef std::unique_ptr< decimater_t > decimater_o;
|
||||||
#else
|
#else
|
||||||
typedef std::auto_ptr< decimater_t > decimater_o;
|
typedef std::auto_ptr< decimater_t > decimater_o;
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ public:
|
|||||||
|
|
||||||
bool bind( osg::GeometryPtr geo )
|
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);
|
std::unique_ptr<mesh_t> obj(new mesh_t);
|
||||||
#else
|
#else
|
||||||
std::auto_ptr<mesh_t> obj(new mesh_t);
|
std::auto_ptr<mesh_t> obj(new mesh_t);
|
||||||
|
|||||||
@@ -851,7 +851,7 @@ compute_screen_space_error(VHierarchyNodeHandle node_handle, VHierarchyNodeHandl
|
|||||||
Vec3f residual;
|
Vec3f residual;
|
||||||
Vec3f res;
|
Vec3f res;
|
||||||
Vec3f lp;
|
Vec3f lp;
|
||||||
#if (_MSC_VER >= 1900 )
|
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) )
|
||||||
// Workaround for internal compiler error
|
// Workaround for internal compiler error
|
||||||
Vec3f tri[3]{ {},{},{} };
|
Vec3f tri[3]{ {},{},{} };
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ include (ACGCommon)
|
|||||||
include_directories (
|
include_directories (
|
||||||
../..
|
../..
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# source code directories
|
# source code directories
|
||||||
|
|||||||
@@ -366,8 +366,8 @@ class VectorT {
|
|||||||
template<typename OtherScalar>
|
template<typename OtherScalar>
|
||||||
auto operator% (const VectorT<OtherScalar, DIM> &_rhs) const ->
|
auto operator% (const VectorT<OtherScalar, DIM> &_rhs) const ->
|
||||||
typename std::enable_if<DIM == 3,
|
typename std::enable_if<DIM == 3,
|
||||||
VectorT<decltype(this->values_[0] * _rhs[0] -
|
VectorT<decltype((*this)[0] * _rhs[0] -
|
||||||
this->values_[0] * _rhs[0]),
|
(*this)[0] * _rhs[0]),
|
||||||
DIM>>::type {
|
DIM>>::type {
|
||||||
return {
|
return {
|
||||||
values_[1] * _rhs[2] - values_[2] * _rhs[1],
|
values_[1] * _rhs[2] - values_[2] * _rhs[1],
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
// macro expansion and preprocessor defines
|
// macro expansion and preprocessor defines
|
||||||
// don't work properly.
|
// 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"
|
#include "Vector11T.hh"
|
||||||
#else
|
#else
|
||||||
#ifndef DOXYGEN
|
#ifndef DOXYGEN
|
||||||
|
|||||||
@@ -55,12 +55,20 @@
|
|||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
// OpenMesh
|
// OpenMesh
|
||||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||||
#include <OpenMesh/Core/IO/reader/STLReader.hh>
|
#include <OpenMesh/Core/IO/reader/STLReader.hh>
|
||||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||||
|
|
||||||
|
//comppare strings crossplatform ignorign case
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define strnicmp _strnicmp
|
||||||
|
#else
|
||||||
|
#define strnicmp strncasecmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//=== NAMESPACES ==============================================================
|
//=== NAMESPACES ==============================================================
|
||||||
|
|
||||||
@@ -447,41 +455,62 @@ _STLReader_::STL_Type
|
|||||||
_STLReader_::
|
_STLReader_::
|
||||||
check_stl_type(const std::string& _filename) const
|
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
|
// read number of triangles
|
||||||
FILE* in = fopen(_filename.c_str(), "rb");
|
char dummy[100];
|
||||||
if (!in) return NONE;
|
fread(dummy, 1, 80, in);
|
||||||
|
size_t nT = read_int(in, swapFlag);
|
||||||
|
|
||||||
|
|
||||||
// determine endian mode
|
// compute file size from nT
|
||||||
union { unsigned int i; unsigned char c[4]; } endian_test;
|
size_t binary_size = 84 + nT*50;
|
||||||
endian_test.i = 1;
|
|
||||||
bool swapFlag = (endian_test.c[3] == 1);
|
|
||||||
|
|
||||||
|
// 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
|
// if sizes match -> it's STLB
|
||||||
char dummy[100];
|
return (binary_size == file_size ? STLB : NONE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ class GenericIteratorT {
|
|||||||
return cpy;
|
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>
|
template<class T = value_handle>
|
||||||
auto operator+=(int amount) ->
|
auto operator+=(int amount) ->
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
|
|
||||||
typedef unsigned int uint;
|
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
|
#define OM_HAS_HASH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#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>
|
#include <mutex>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ protected:
|
|||||||
virtual int sync()
|
virtual int sync()
|
||||||
{
|
{
|
||||||
// If working on multiple threads, we need to serialize the output correctly (requires c++11 headers)
|
// 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_);
|
std::lock_guard<std::mutex> lck (serializer_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ protected:
|
|||||||
char c = traits_type::to_char_type(_c);
|
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 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_);
|
std::lock_guard<std::mutex> lck (serializer_);
|
||||||
buffer_.push_back(c);
|
buffer_.push_back(c);
|
||||||
@@ -264,7 +264,7 @@ private:
|
|||||||
bool enabled_;
|
bool enabled_;
|
||||||
|
|
||||||
// If working on multiple threads, we need to serialize the output correctly (requires c++11 headers)
|
// 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_;
|
std::mutex serializer_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ public:
|
|||||||
* In C++11 an beyond we can introduce more efficient and more legible
|
* In C++11 an beyond we can introduce more efficient and more legible
|
||||||
* implementations of the following methods.
|
* 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.
|
* Reserves space for \p _n elements in all property vectors.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace OpenMesh {
|
|||||||
*/
|
*/
|
||||||
template<typename PROPTYPE, typename MeshT>
|
template<typename PROPTYPE, typename MeshT>
|
||||||
class PropertyManager {
|
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:
|
public:
|
||||||
PropertyManager(const PropertyManager&) = delete;
|
PropertyManager(const PropertyManager&) = delete;
|
||||||
PropertyManager& operator=(const PropertyManager&) = delete;
|
PropertyManager& operator=(const PropertyManager&) = delete;
|
||||||
@@ -167,7 +167,7 @@ class PropertyManager {
|
|||||||
|
|
||||||
MeshT &getMesh() const { return *mesh_; }
|
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.
|
/// Only for pre C++11 compatibility.
|
||||||
|
|
||||||
typedef PropertyManager<PROPTYPE, MeshT> Proxy;
|
typedef PropertyManager<PROPTYPE, MeshT> Proxy;
|
||||||
@@ -208,6 +208,42 @@ class PropertyManager {
|
|||||||
return std::move(pm);
|
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 duplicate(const char *clone_name) {
|
||||||
PropertyManager pm(*mesh_, clone_name, false);
|
PropertyManager pm(*mesh_, clone_name, false);
|
||||||
@@ -267,6 +303,27 @@ class PropertyManager {
|
|||||||
return (Proxy)pm;
|
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) {
|
Proxy duplicate(const char *clone_name) {
|
||||||
PropertyManager pm(*mesh_, clone_name, false);
|
PropertyManager pm(*mesh_, clone_name, false);
|
||||||
pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
|
pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
|
||||||
@@ -353,6 +410,14 @@ class PropertyManager {
|
|||||||
(*this)[*begin] = value;
|
(*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
|
* Conveniently transfer the values managed by one property manager
|
||||||
* onto the values managed by a different 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);
|
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 */
|
} /* namespace OpenMesh */
|
||||||
#endif /* PROPERTYMANAGER_HH_ */
|
#endif /* PROPERTYMANAGER_HH_ */
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ template<class Mesh>
|
|||||||
DecimaterT<Mesh>::DecimaterT(Mesh& _mesh) :
|
DecimaterT<Mesh>::DecimaterT(Mesh& _mesh) :
|
||||||
BaseDecimaterT<Mesh>(_mesh),
|
BaseDecimaterT<Mesh>(_mesh),
|
||||||
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)
|
heap_(nullptr)
|
||||||
#else
|
#else
|
||||||
heap_(NULL)
|
heap_(NULL)
|
||||||
@@ -178,7 +178,7 @@ size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
|||||||
// initialize heap
|
// initialize heap
|
||||||
HeapInterface HI(mesh_, priority_, heap_position_);
|
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));
|
heap_ = std::unique_ptr<DeciHeap>(new DeciHeap(HI));
|
||||||
#else
|
#else
|
||||||
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
|
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
|
// initialize heap
|
||||||
HeapInterface HI(mesh_, priority_, heap_position_);
|
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));
|
heap_ = std::unique_ptr<DeciHeap>(new DeciHeap(HI));
|
||||||
#else
|
#else
|
||||||
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
|
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ private: //------------------------------------------------------- private data
|
|||||||
Mesh& mesh_;
|
Mesh& mesh_;
|
||||||
|
|
||||||
// heap
|
// 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_;
|
std::unique_ptr<DeciHeap> heap_;
|
||||||
#else
|
#else
|
||||||
std::auto_ptr<DeciHeap> heap_;
|
std::auto_ptr<DeciHeap> heap_;
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
#include "Config.hh"
|
#include "Config.hh"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <OpenMesh/Core/System/omstream.hh>
|
#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>
|
#include <utility>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ public:
|
|||||||
/// Constructor
|
/// Constructor
|
||||||
HeapT() : HeapVector() {}
|
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.
|
/// Construct with a given \c HeapIterface.
|
||||||
HeapT(HeapInterface _interface)
|
HeapT(HeapInterface _interface)
|
||||||
: HeapVector(), interface_(std::move(_interface))
|
: HeapVector(), interface_(std::move(_interface))
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ update_viewing_configurations()
|
|||||||
Vec3f trans;
|
Vec3f trans;
|
||||||
|
|
||||||
// Workaround for internal compiler error on Visual Studio 2015 Update 1
|
// 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 inv_rot[3]{ {},{},{} };
|
||||||
Vec3f normal[4]{ {},{},{},{} };
|
Vec3f normal[4]{ {},{},{},{} };
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -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]);
|
face_vhandles.push_back(vhandle[3]);
|
||||||
mesh_.add_face(face_vhandles);
|
mesh_.add_face(face_vhandles);
|
||||||
|
|
||||||
OpenMesh::PropertyManager<
|
{
|
||||||
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
|
OpenMesh::PropertyManager<
|
||||||
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
|
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
|
||||||
for (int i = 0; i < 4; ++i)
|
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
|
||||||
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
|
for (int i = 0; i < 4; ++i)
|
||||||
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
|
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
|
||||||
for (int i = 0; i < 4; ++i)
|
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
|
||||||
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
|
for (int i = 0; i < 4; ++i)
|
||||||
|
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
|
||||||
|
|
||||||
OpenMesh::PropertyManager<
|
OpenMesh::PropertyManager<
|
||||||
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
|
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
|
||||||
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false);
|
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();
|
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
|
||||||
e_it != f_end; ++e_it)
|
e_it != f_end; ++e_it)
|
||||||
ASSERT_FALSE(pm_e_bool[*e_it]);
|
ASSERT_FALSE(pm_e_bool[*e_it]);
|
||||||
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), true);
|
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();
|
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
|
||||||
e_it != f_end; ++e_it)
|
e_it != f_end; ++e_it)
|
||||||
ASSERT_TRUE(pm_e_bool[*e_it]);
|
ASSERT_TRUE(pm_e_bool[*e_it]);
|
||||||
|
|
||||||
OpenMesh::PropertyManager<
|
OpenMesh::PropertyManager<
|
||||||
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
|
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
|
||||||
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false);
|
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();
|
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
|
||||||
f_it != f_end; ++f_it)
|
f_it != f_end; ++f_it)
|
||||||
ASSERT_FALSE(pm_f_bool[*f_it]);
|
ASSERT_FALSE(pm_f_bool[*f_it]);
|
||||||
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), true);
|
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();
|
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
|
||||||
f_it != f_end; ++f_it)
|
f_it != f_end; ++f_it)
|
||||||
ASSERT_TRUE(pm_f_bool[*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
|
* 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>
|
template<typename PropHandle, typename Mesh>
|
||||||
bool has_property(const Mesh& _mesh, const std::string& _name) {
|
bool has_property(const Mesh& _mesh, const std::string& _name) {
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
#include <cstdint>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class OpenMeshVectorTest : public testing::Test {
|
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) {
|
TEST_F(OpenMeshVectorTest, cpp11_constructors) {
|
||||||
OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 };
|
OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 };
|
||||||
|
|
||||||
@@ -323,4 +327,76 @@ TEST_F(OpenMeshVectorTest, size_dim) {
|
|||||||
EXPECT_EQ(2, v2i.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user