commit e4d3eb1ad37f6e58524453587978d5c62b7656f9 Author: ccolin Date: Mon Sep 20 20:36:29 2021 +0200 archivage initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/data/cube.obj b/data/cube.obj new file mode 100644 index 0000000..de4003f --- /dev/null +++ b/data/cube.obj @@ -0,0 +1,30 @@ +# Blender v2.90.1 OBJ File: '' +# www.blender.org +o Cube +v -1.000000 -1.000000 1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 -1.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 2//1 3//1 1//1 +f 4//2 7//2 3//2 +f 8//3 5//3 7//3 +f 6//4 1//4 5//4 +f 7//5 1//5 3//5 +f 4//6 6//6 8//6 +f 2//1 4//1 3//1 +f 4//2 8//2 7//2 +f 8//3 6//3 5//3 +f 6//4 2//4 1//4 +f 7//5 5//5 1//5 +f 4//6 2//6 6//6 diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/Config.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/Config.hh new file mode 100644 index 0000000..b1f1b08 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/Config.hh @@ -0,0 +1,75 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Defines +// +//============================================================================= + +#ifndef OPENMESH_GEOMETRY_CONFIG_HH +#define OPENMESH_GEOMETRY_CONFIG_HH + + +//== INCLUDES ================================================================= + +// OpenMesh Namespace Defines +#include + + +//== NAMESPACES =============================================================== + +#define BEGIN_NS_GEOMETRY namespace geometry { +#define END_NS_GEOMETRY } + + +//============================================================================= +#endif // OPENMESH_GEOMETRY_CONFIG_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh new file mode 100644 index 0000000..feca771 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/LoopSchemeMaskT.hh @@ -0,0 +1,196 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef LOOPSCHEMEMASKT_HH +#define LOOPSCHEMEMASKT_HH + +#include +#include + +#include +#include + +namespace OpenMesh +{ + +/** implements cache for the weights of the original Loop scheme + supported: + - vertex projection rule on the next level + - vertex projection rule on the limit surface + - vertex projection rule on the k-th (level) step (Barthe, Kobbelt'2003) + - vertex tangents on the limit surface +*/ + +template +class LoopSchemeMaskT +{ +public: + enum { cache_size = cache_size_ }; + typedef T_ Scalar; + +protected: + + Scalar proj_weights_[cache_size]; + Scalar limit_weights_[cache_size]; + Scalar step_weights_[cache_size]; + std::vector tang0_weights_[cache_size]; + std::vector tang1_weights_[cache_size]; + +protected: + + inline static Scalar compute_proj_weight(uint _valence) + { + //return pow(3.0 / 2.0 + cos(2.0 * M_PI / _valence), 2) / 2.0 - 1.0; + double denom = (3.0 + 2.0*cos(2.0*M_PI/(double)_valence)); + double weight = (64.0*_valence)/(40.0 - denom*denom) - _valence; + return (Scalar) weight; + } + + inline static Scalar compute_limit_weight(uint _valence) + { + double proj_weight = compute_proj_weight(_valence); + proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight + double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0)); + return (Scalar)weight; + } + + inline static Scalar compute_step_weight(uint _valence) + { + double proj_weight = compute_proj_weight(_valence); + proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight + double weight = proj_weight - (3.0/8.0); + return (Scalar)weight; + } + + inline static Scalar compute_tang0_weight(uint _valence, uint _ver_id) + { + return (Scalar)cos(2.0*M_PI*(double)_ver_id/(double)_valence); + } + + inline static Scalar compute_tang1_weight(uint _valence, uint _ver_id) + { + return (Scalar)sin(2.0*M_PI*(double)_ver_id/(double)_valence); + } + + void cache_weights() + { + proj_weights_[0] = 1; + for (uint k = 1; k < cache_size; ++k) + { + proj_weights_[k] = compute_proj_weight(k); + limit_weights_[k] = compute_limit_weight(k); + step_weights_[k] = compute_step_weight(k); + tang0_weights_[k].resize(k); + tang1_weights_[k].resize(k); + for (uint i = 0; i < k; ++i) + { + tang0_weights_[k][i] = compute_tang0_weight(k,i); + tang1_weights_[k][i] = compute_tang1_weight(k,i); + } + } + } + +public: + + LoopSchemeMaskT() + { + cache_weights(); + } + + inline Scalar proj_weight(uint _valence) const + { + assert(_valence < cache_size ); + return proj_weights_[_valence]; + } + + inline Scalar limit_weight(uint _valence) const + { + assert(_valence < cache_size ); + return limit_weights_[_valence]; + } + + inline Scalar step_weight(uint _valence, uint _step) const + { + assert(_valence < cache_size); + return pow(step_weights_[_valence], (int)_step);//can be precomputed + } + + inline Scalar tang0_weight(uint _valence, uint _ver_id) const + { + assert(_valence < cache_size ); + assert(_ver_id < _valence); + return tang0_weights_[_valence][_ver_id]; + } + + inline Scalar tang1_weight(uint _valence, uint _ver_id) const + { + assert(_valence < cache_size ); + assert(_ver_id < _valence); + return tang1_weights_[_valence][_ver_id]; + } + + void dump(uint _max_valency = cache_size - 1) const + { + assert(_max_valency <= cache_size - 1); + //CConsole::printf("(k : pw_k, lw_k): "); + for (uint i = 0; i <= _max_valency; ++i) + { + //CConsole::stream() << "(" << i << " : " << proj_weight(i) << ", " << limit_weight(i) << ", " << step_weight(i,1) << "), "; + } + //CConsole::printf("\n"); + } +}; + +typedef LoopSchemeMaskT LoopSchemeMaskDouble; +typedef SingletonT LoopSchemeMaskDoubleSingleton; + +}//namespace OpenMesh + +#endif//LOOPSCHEMEMASKT_HH + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/MathDefs.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/MathDefs.hh new file mode 100644 index 0000000..c61bb7d --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/MathDefs.hh @@ -0,0 +1,172 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef MATHDEFS_HH +#define MATHDEFS_HH + +#include +#include + +#ifndef M_PI + #define M_PI 3.14159265359 +#endif + +namespace OpenMesh +{ + +/** comparison operators with user-selected precision control +*/ +template +inline bool is_zero(const T& _a, Real _eps) +{ return fabs(_a) < _eps; } + +template +inline bool is_eq(const T1& a, const T2& b, Real _eps) +{ return is_zero(a-b, _eps); } + +template +inline bool is_gt(const T1& a, const T2& b, Real _eps) +{ return (a > b) && !is_eq(a,b,_eps); } + +template +inline bool is_ge(const T1& a, const T2& b, Real _eps) +{ return (a > b) || is_eq(a,b,_eps); } + +template +inline bool is_lt(const T1& a, const T2& b, Real _eps) +{ return (a < b) && !is_eq(a,b,_eps); } + +template +inline bool is_le(const T1& a, const T2& b, Real _eps) +{ return (a < b) || is_eq(a,b,_eps); } + +/*const float flt_eps__ = 10*FLT_EPSILON; +const double dbl_eps__ = 10*DBL_EPSILON;*/ +const float flt_eps__ = (float)1e-05; +const double dbl_eps__ = 1e-09; + +inline float eps__(float) +{ return flt_eps__; } + +inline double eps__(double) +{ return dbl_eps__; } + +template +inline bool is_zero(const T& a) +{ return is_zero(a, eps__(a)); } + +template +inline bool is_eq(const T1& a, const T2& b) +{ return is_zero(a-b); } + +template +inline bool is_gt(const T1& a, const T2& b) +{ return (a > b) && !is_eq(a,b); } + +template +inline bool is_ge(const T1& a, const T2& b) +{ return (a > b) || is_eq(a,b); } + +template +inline bool is_lt(const T1& a, const T2& b) +{ return (a < b) && !is_eq(a,b); } + +template +inline bool is_le(const T1& a, const T2& b) +{ return (a < b) || is_eq(a,b); } + +/// Trigonometry/angles - related + +template +inline T sane_aarg(T _aarg) +{ + if (_aarg < -1) + { + _aarg = -1; + } + else if (_aarg > 1) + { + _aarg = 1; + } + return _aarg; +} + +/** returns the angle determined by its cos and the sign of its sin + result is positive if the angle is in [0:pi] + and negative if it is in [pi:2pi] +*/ +template +T angle(T _cos_angle, T _sin_angle) +{//sanity checks - otherwise acos will return nan + _cos_angle = sane_aarg(_cos_angle); + return (T) _sin_angle >= 0 ? acos(_cos_angle) : -acos(_cos_angle); +} + +template +inline T positive_angle(T _angle) +{ return _angle < 0 ? (2*M_PI + _angle) : _angle; } + +template +inline T positive_angle(T _cos_angle, T _sin_angle) +{ return positive_angle(angle(_cos_angle, _sin_angle)); } + +template +inline T deg_to_rad(const T& _angle) +{ return M_PI*(_angle/180); } + +template +inline T rad_to_deg(const T& _angle) +{ return 180*(_angle/M_PI); } + +inline double log_(double _value) +{ return log(_value); } + +}//namespace OpenMesh + +#endif//MATHDEFS_HH diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.hh new file mode 100644 index 0000000..796bbdd --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.hh @@ -0,0 +1,132 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + + + +//============================================================================= +// +// CLASS NormalCone +// +//============================================================================= + + +#ifndef OPENMESH_NORMALCONE_HH +#define OPENMESH_NORMALCONE_HH + + +//== INCLUDES ================================================================= + + +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/** /class NormalCone NormalCone.hh + + NormalCone that can be merged with other normal cones. Provides + the center normal and the opening angle. +**/ + +template +class NormalConeT +{ +public: + + // typedefs + typedef VectorT Vec3; + + + //! default constructor (not initialized) + NormalConeT() {} + + //! Initialize cone with center (unit vector) and angle (radius in radians) + NormalConeT(const Vec3& _center_normal, Scalar _angle=0.0); + + //! return max. distance (radians) unit vector to cone (distant side) + Scalar max_angle(const Vec3&) const; + + //! return max. distance (radians) cone to cone (distant sides) + Scalar max_angle(const NormalConeT&) const; + + //! merge _cone; this instance will then enclose both former cones + void merge(const NormalConeT&); + + //! returns center normal + const Vec3& center_normal() const { return center_normal_; } + + //! returns size of cone (radius in radians) + inline Scalar angle() const { return angle_; } + +private: + + Vec3 center_normal_; + Scalar angle_; +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_NORMALCONE_C) +#define OPENMESH_NORMALCONE_TEMPLATES +#include "NormalConeT.cc" +#endif +//============================================================================= +#endif // OPENMESH_NORMALCONE_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/Plane3d.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/Plane3d.hh new file mode 100644 index 0000000..50e9ced --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/Plane3d.hh @@ -0,0 +1,124 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +//============================================================================= +// +// CLASS Plane3D +// +//============================================================================= + + +#ifndef OPENMESH_PLANE3D_HH +#define OPENMESH_PLANE3D_HH + + +//== INCLUDES ================================================================= + +#include + + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace VDPM { + +//== CLASS DEFINITION ========================================================= + + +/** \class Plane3d Plane3d.hh + + ax + by + cz + d = 0 +*/ + + +class OPENMESHDLLEXPORT Plane3d +{ +public: + + typedef OpenMesh::Vec3f vector_type; + typedef vector_type::value_type value_type; + +public: + + Plane3d() + : d_(0) + { } + + Plane3d(const vector_type &_dir, const vector_type &_pnt) + : n_(_dir), d_(0) + { + n_.normalize(); + d_ = -dot(n_,_pnt); + } + + value_type signed_distance(const OpenMesh::Vec3f &_p) + { + return dot(n_ , _p) + d_; + } + + // back compatibility + value_type singed_distance(const OpenMesh::Vec3f &point) + { return signed_distance( point ); } + +public: + + vector_type n_; + value_type d_; + +}; + +//============================================================================= +} // namespace VDPM +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_PLANE3D_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/QuadricT.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/QuadricT.hh new file mode 100644 index 0000000..8d2943a --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/QuadricT.hh @@ -0,0 +1,291 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +/** \file Core/Geometry/QuadricT.hh + + */ + +//============================================================================= +// +// CLASS QuadricT +// +//============================================================================= + +#ifndef OPENMESH_GEOMETRY_QUADRIC_HH +#define OPENMESH_GEOMETRY_QUADRIC_HH + + +//== INCLUDES ================================================================= + +#include "Config.hh" +#include +#include + +//== NAMESPACE ================================================================ + +namespace OpenMesh { //BEGIN_NS_OPENMESH +namespace Geometry { //BEGIN_NS_GEOMETRY + + +//== CLASS DEFINITION ========================================================= + + +/** /class QuadricT Geometry/QuadricT.hh + + Stores a quadric as a 4x4 symmetrix matrix. Used by the + error quadric based mesh decimation algorithms. +**/ + +template +class QuadricT +{ +public: + typedef Scalar value_type; + typedef QuadricT type; + typedef QuadricT Self; + // typedef VectorInterface > Vec3; + // typedef VectorInterface > Vec4; + //typedef Vector3Elem Vec3; + //typedef Vector4Elem Vec4; + + /// construct with upper triangle of symmetrix 4x4 matrix + QuadricT(Scalar _a, Scalar _b, Scalar _c, Scalar _d, + Scalar _e, Scalar _f, Scalar _g, + Scalar _h, Scalar _i, + Scalar _j) + : a_(_a), b_(_b), c_(_c), d_(_d), + e_(_e), f_(_f), g_(_g), + h_(_h), i_(_i), + j_(_j) + { + } + + + /// constructor from given plane equation: ax+by+cz+d_=0 + QuadricT( Scalar _a=0.0, Scalar _b=0.0, Scalar _c=0.0, Scalar _d=0.0 ) + : a_(_a*_a), b_(_a*_b), c_(_a*_c), d_(_a*_d), + e_(_b*_b), f_(_b*_c), g_(_b*_d), + h_(_c*_c), i_(_c*_d), + j_(_d*_d) + {} + + template + QuadricT(const _Point& _pt) + { + set_distance_to_point(_pt); + } + + template + QuadricT(const _Normal& _n, const _Point& _p) + { + set_distance_to_plane(_n,_p); + } + + //set operator + void set(Scalar _a, Scalar _b, Scalar _c, Scalar _d, + Scalar _e, Scalar _f, Scalar _g, + Scalar _h, Scalar _i, + Scalar _j) + { + a_ = _a; b_ = _b; c_ = _c; d_ = _d; + e_ = _e; f_ = _f; g_ = _g; + h_ = _h; i_ = _i; + j_ = _j; + } + + //sets the quadric representing the squared distance to _pt + template + void set_distance_to_point(const _Point& _pt) + { + set(1, 0, 0, -_pt[0], + 1, 0, -_pt[1], + 1, -_pt[2], + dot(_pt,_pt)); + } + + //sets the quadric representing the squared distance to the plane [_a,_b,_c,_d] + void set_distance_to_plane(Scalar _a, Scalar _b, Scalar _c, Scalar _d) + { + a_ = _a*_a; b_ = _a*_b; c_ = _a*_c; d_ = _a*_d; + e_ = _b*_b; f_ = _b*_c; g_ = _b*_d; + h_ = _c*_c; i_ = _c*_d; + j_ = _d*_d; + } + + //sets the quadric representing the squared distance to the plane + //determined by the normal _n and the point _p + template + void set_distance_to_plane(const _Normal& _n, const _Point& _p) + { + set_distance_to_plane(_n[0], _n[1], _n[2], -dot(_n,_p)); + } + + /// set all entries to zero + void clear() { a_ = b_ = c_ = d_ = e_ = f_ = g_ = h_ = i_ = j_ = 0.0; } + + /// add quadrics + QuadricT& operator+=( const QuadricT& _q ) + { + a_ += _q.a_; b_ += _q.b_; c_ += _q.c_; d_ += _q.d_; + e_ += _q.e_; f_ += _q.f_; g_ += _q.g_; + h_ += _q.h_; i_ += _q.i_; + j_ += _q.j_; + return *this; + } + + QuadricT operator+(const QuadricT& _other ) const + { + QuadricT result = *this; + return result += _other; + } + + + /// multiply by scalar + QuadricT& operator*=( Scalar _s) + { + a_ *= _s; b_ *= _s; c_ *= _s; d_ *= _s; + e_ *= _s; f_ *= _s; g_ *= _s; + h_ *= _s; i_ *= _s; + j_ *= _s; + return *this; + } + + QuadricT operator*(Scalar _s) const + { + QuadricT result = *this; + return result *= _s; + } + + /// multiply 4D vector from right: Q*v + template + _Vec4 operator*(const _Vec4& _v) const + { + Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]); + return _Vec4(x*a_ + y*b_ + z*c_ + w*d_, + x*b_ + y*e_ + z*f_ + w*g_, + x*c_ + y*f_ + z*h_ + w*i_, + x*d_ + y*g_ + z*i_ + w*j_); + } + + /// evaluate quadric Q at (3D or 4D) vector v: v*Q*v + template + Scalar operator()(const _Vec& _v) const + { + return evaluate(_v, GenProg::Int2Type::size_>()); + } + + Scalar a() const { return a_; } + Scalar b() const { return b_; } + Scalar c() const { return c_; } + Scalar d() const { return d_; } + Scalar e() const { return e_; } + Scalar f() const { return f_; } + Scalar g() const { return g_; } + Scalar h() const { return h_; } + Scalar i() const { return i_; } + Scalar j() const { return j_; } + + Scalar xx() const { return a_; } + Scalar xy() const { return b_; } + Scalar xz() const { return c_; } + Scalar xw() const { return d_; } + Scalar yy() const { return e_; } + Scalar yz() const { return f_; } + Scalar yw() const { return g_; } + Scalar zz() const { return h_; } + Scalar zw() const { return i_; } + Scalar ww() const { return j_; } + +protected: + + /// evaluate quadric Q at 3D vector v: v*Q*v + template + Scalar evaluate(const _Vec3& _v, GenProg::Int2Type<3>/*_dimension*/) const + { + Scalar x(_v[0]), y(_v[1]), z(_v[2]); + return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x + + e_*y*y + 2.0*f_*y*z + 2.0*g_*y + + h_*z*z + 2.0*i_*z + + j_; + } + + /// evaluate quadric Q at 4D vector v: v*Q*v + template + Scalar evaluate(const _Vec4& _v, GenProg::Int2Type<4>/*_dimension*/) const + { + Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]); + return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x*w + + e_*y*y + 2.0*f_*y*z + 2.0*g_*y*w + + h_*z*z + 2.0*i_*z*w + + j_*w*w; + } + +private: + + Scalar a_, b_, c_, d_, + e_, f_, g_, + h_, i_, + j_; +}; + + +/// Quadric using floats +typedef QuadricT Quadricf; + +/// Quadric using double +typedef QuadricT Quadricd; + + +//============================================================================= +} // END_NS_GEOMETRY +} // END_NS_OPENMESH +//============================================================================ +#endif // OPENMESH_GEOMETRY_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/Vector11T.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/Vector11T.hh new file mode 100644 index 0000000..b9113a6 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/Vector11T.hh @@ -0,0 +1,886 @@ +/* ========================================================================= * + * * + * 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. * + * * + * ========================================================================= */ + +#ifndef OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_ +#define OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// This header is not needed by this file but expected by others including +// this file. +#include + + +/* + * Helpers for VectorT + */ +namespace { + +template +struct are_convertible_to; + +template +struct are_convertible_to { + static constexpr bool value = std::is_convertible::value + && are_convertible_to::value; +}; + +template +struct are_convertible_to : public std::is_convertible { +}; +} + +namespace OpenMesh { + +template +class VectorT { + + static_assert(DIM >= 1, "VectorT requires positive dimensionality."); + + private: + using container = std::array; + container values_; + + public: + + //---------------------------------------------------------------- class info + + /// the type of the scalar used in this template + typedef Scalar value_type; + + /// type of this vector + typedef VectorT vector_type; + + /// returns dimension of the vector (deprecated) + static constexpr int dim() { + return DIM; + } + + /// returns dimension of the vector + static constexpr size_t size() { + return DIM; + } + + static constexpr const size_t size_ = DIM; + + //-------------------------------------------------------------- constructors + + // Converting constructor: Constructs the vector from DIM values (of + // potentially heterogenous types) which are all convertible to Scalar. + template::type, + typename = typename std::enable_if< + are_convertible_to::value>::type> + constexpr VectorT(T v, Ts... vs) : values_ { {static_cast(v), static_cast(vs)...} } { + static_assert(sizeof...(Ts)+1 == DIM, + "Invalid number of components specified in constructor."); + static_assert(are_convertible_to::value, + "Not all components are convertible to Scalar."); + } + + /// default constructor creates uninitialized values. + constexpr VectorT() {} + + /** + * Creates a vector with all components set to v. + */ + explicit VectorT(const Scalar &v) { + vectorize(v); + } + + VectorT(const VectorT &rhs) = default; + VectorT(VectorT &&rhs) = default; + VectorT &operator=(const VectorT &rhs) = default; + VectorT &operator=(VectorT &&rhs) = default; + + /** + * Only for 4-component vectors with division operator on their + * Scalar: Dehomogenization. + */ + template + auto homogenized() const -> + typename std::enable_if()/std::declval()), DIM>>::type { + static_assert(D == DIM, "D and DIM need to be identical. (Never " + "override the default template arguments.)"); + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + return VectorT( + values_[0]/values_[3], + values_[1]/values_[3], + values_[2]/values_[3], + 1); + } + + /// construct from a value array or any other iterator + template(), void(), + ++std::declval(), void())> + explicit VectorT(Iterator it) { + std::copy_n(it, DIM, values_.begin()); + } + + /// copy & cast constructor (explicit) + template::value>> + explicit VectorT(const VectorT& _rhs) { + operator=(_rhs); + } + + //--------------------------------------------------------------------- casts + + /// cast from vector with a different scalar type + template::value>> + vector_type& operator=(const VectorT& _rhs) { + std::transform(_rhs.cbegin(), _rhs.cend(), + this->begin(), [](OtherScalar rhs) { + return static_cast(std::move(rhs)); + }); + return *this; + } + + /// access to Scalar array + Scalar* data() { return values_.data(); } + + /// access to const Scalar array + const Scalar* data() const { return values_.data(); } + + //----------------------------------------------------------- element access + + /// get i'th element read-write + Scalar& operator[](size_t _i) { + assert(_i < DIM); + return values_[_i]; + } + + /// get i'th element read-only + const Scalar& operator[](size_t _i) const { + assert(_i < DIM); + return values_[_i]; + } + + //---------------------------------------------------------------- comparsion + + /// component-wise comparison + bool operator==(const vector_type& _rhs) const { + return std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin()); + } + + /// component-wise comparison + bool operator!=(const vector_type& _rhs) const { + return !std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin()); + } + + //---------------------------------------------------------- scalar operators + + /// component-wise self-multiplication with scalar + template + auto operator*=(const OtherScalar& _s) -> + typename std::enable_ifvalues_[0] * _s), Scalar>::value, + VectorT&>::type { + for (auto& e : *this) { + e *= _s; + } + return *this; + } + + /// component-wise self-division by scalar + template + auto operator/=(const OtherScalar& _s) -> + typename std::enable_ifvalues_[0] / _s), Scalar>::value, + VectorT&>::type { + for (auto& e : *this) { + e /= _s; + } + return *this; + } + + /// component-wise multiplication with scalar + template + typename std::enable_if() * std::declval()), + Scalar>::value, + VectorT>::type + operator*(const OtherScalar& _s) const { + return vector_type(*this) *= _s; + } + + /// component-wise division by with scalar + template + typename std::enable_if() / std::declval()), + Scalar>::value, + VectorT>::type + operator/(const OtherScalar& _s) const { + return vector_type(*this) /= _s; + } + + //---------------------------------------------------------- vector operators + + /// component-wise self-multiplication + template + auto operator*=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0, + vector_type&>::type { + for (int i = 0; i < DIM; ++i) { + data()[i] *= _rhs.data()[i]; + } + return *this; + } + + /// component-wise self-division + template + auto operator/=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0, + vector_type&>::type { + for (int i = 0; i < DIM; ++i) { + data()[i] /= _rhs.data()[i]; + } + return *this; + } + + /// vector difference from this + template + auto operator-=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0, + vector_type&>::type { + for (int i = 0; i < DIM; ++i) { + data()[i] -= _rhs.data()[i]; + } + return *this; + } + + /// vector self-addition + template + auto operator+=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0, + vector_type&>::type { + for (int i = 0; i < DIM; ++i) { + data()[i] += _rhs.data()[i]; + } + return *this; + } + + /// component-wise vector multiplication + template + auto operator*(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0, + vector_type>::type { + return vector_type(*this) *= _rhs; + } + + /// component-wise vector division + template + auto operator/(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0, + vector_type>::type { + return vector_type(*this) /= _rhs; + } + + /// component-wise vector addition + template + auto operator+(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0, + vector_type>::type { + return vector_type(*this) += _rhs; + } + + /// component-wise vector difference + template + auto operator-(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0, + vector_type>::type { + return vector_type(*this) -= _rhs; + } + + /// unary minus + vector_type operator-(void) const { + vector_type v; + std::transform(values_.begin(), values_.end(), v.values_.begin(), + [](const Scalar &s) { return -s; }); + return v; + } + + /// cross product: only defined for Vec3* as specialization + /// \see OpenMesh::cross + template + auto operator% (const VectorT &_rhs) const -> + typename std::enable_if>::type { + return { + values_[1] * _rhs[2] - values_[2] * _rhs[1], + values_[2] * _rhs[0] - values_[0] * _rhs[2], + values_[0] * _rhs[1] - values_[1] * _rhs[0] + }; + } + + /// compute scalar product + /// \see OpenMesh::dot + template + auto operator|(const VectorT& _rhs) const -> + decltype(*this->data() * *_rhs.data()) { + + return std::inner_product(begin() + 1, begin() + DIM, _rhs.begin() + 1, + *begin() * *_rhs.begin()); + } + + //------------------------------------------------------------ euclidean norm + + /// \name Euclidean norm calculations + //@{ + + /// compute squared euclidean norm + template + decltype(std::declval() * std::declval()) sqrnorm() const { + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + typedef decltype(values_[0] * values_[0]) RESULT; + return std::accumulate(values_.cbegin() + 1, values_.cend(), + values_[0] * values_[0], + [](const RESULT &l, const Scalar &r) { return l + r * r; }); + } + + /// compute euclidean norm + template + auto norm() const -> + decltype(std::sqrt(std::declval>().sqrnorm())) { + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + return std::sqrt(sqrnorm()); + } + + template + auto length() const -> + decltype(std::declval>().norm()) { + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + return norm(); + } + + /** normalize vector, return normalized vector + */ + template + auto normalize() -> + decltype(*this /= std::declval>().norm()) { + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + return *this /= norm(); + } + + /** return normalized vector + */ + template + auto normalized() const -> + decltype(*this / std::declval>().norm()) { + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + return *this / norm(); + } + + /** normalize vector, return normalized vector and avoids div by zero + */ + template + typename std::enable_if< + sizeof(decltype( + static_cast(0), + std::declval>().norm())) >= 0, + vector_type&>::type + normalize_cond() { + static_assert(std::is_same::value, "S and Scalar need " + "to be the same type. (Never override the default template " + "arguments.)"); + auto n = norm(); + if (n != static_cast(0)) { + *this /= n; + } + return *this; + } + + //@} + + //------------------------------------------------------------ euclidean norm + + /// \name Non-Euclidean norm calculations + //@{ + + /// compute L1 (Manhattan) norm + Scalar l1_norm() const { + return std::accumulate( + values_.cbegin() + 1, values_.cend(), values_[0]); + } + + /// compute l8_norm + Scalar l8_norm() const { + return max_abs(); + } + + //@} + + //------------------------------------------------------------ max, min, mean + + /// \name Minimum maximum and mean + //@{ + + /// return the maximal component + Scalar max() const { + return *std::max_element(values_.cbegin(), values_.cend()); + } + + /// return the maximal absolute component + Scalar max_abs() const { + return std::abs( + *std::max_element(values_.cbegin(), values_.cend(), + [](const Scalar &a, const Scalar &b) { + return std::abs(a) < std::abs(b); + })); + } + + /// return the minimal component + Scalar min() const { + return *std::min_element(values_.cbegin(), values_.cend()); + } + + /// return the minimal absolute component + Scalar min_abs() const { + return std::abs( + *std::min_element(values_.cbegin(), values_.cend(), + [](const Scalar &a, const Scalar &b) { + return std::abs(a) < std::abs(b); + })); + } + + /// return arithmetic mean + Scalar mean() const { + return l1_norm()/DIM; + } + + /// return absolute arithmetic mean + Scalar mean_abs() const { + return std::accumulate(values_.cbegin() + 1, values_.cend(), + std::abs(values_[0]), + [](const Scalar &l, const Scalar &r) { + return l + std::abs(r); + }) / DIM; + } + + /// minimize values: same as *this = min(*this, _rhs), but faster + vector_type& minimize(const vector_type& _rhs) { + std::transform(values_.cbegin(), values_.cend(), + _rhs.values_.cbegin(), + values_.begin(), + [](const Scalar &l, const Scalar &r) { + return std::min(l, r); + }); + return *this; + } + + /// minimize values and signalize coordinate minimization + bool minimized(const vector_type& _rhs) { + bool result = false; + std::transform(values_.cbegin(), values_.cend(), + _rhs.values_.cbegin(), + values_.begin(), + [&result](const Scalar &l, const Scalar &r) { + if (l < r) { + return l; + } else { + result = true; + return r; + } + }); + return result; + } + + /// maximize values: same as *this = max(*this, _rhs), but faster + vector_type& maximize(const vector_type& _rhs) { + std::transform(values_.cbegin(), values_.cend(), + _rhs.values_.cbegin(), + values_.begin(), + [](const Scalar &l, const Scalar &r) { + return std::max(l, r); + }); + return *this; + } + + /// maximize values and signalize coordinate maximization + bool maximized(const vector_type& _rhs) { + bool result = false; + std::transform(values_.cbegin(), values_.cend(), + _rhs.values_.cbegin(), + values_.begin(), + [&result](const Scalar &l, const Scalar &r) { + if (l > r) { + return l; + } else { + result = true; + return r; + } + }); + return result; + } + + /// component-wise min + inline vector_type min(const vector_type& _rhs) const { + return vector_type(*this).minimize(_rhs); + } + + /// component-wise max + inline vector_type max(const vector_type& _rhs) const { + return vector_type(*this).maximize(_rhs); + } + + //@} + + //------------------------------------------------------------ misc functions + + /// component-wise apply function object with Scalar operator()(Scalar). + template + inline vector_type apply(const Functor& _func) const { + vector_type result; + std::transform(result.values_.cbegin(), result.values_.cend(), + result.values_.begin(), _func); + return result; + } + + /// store the same value in each component (e.g. to clear all entries) + vector_type& vectorize(const Scalar& _s) { + std::fill(values_.begin(), values_.end(), _s); + return *this; + } + + /// store the same value in each component + static vector_type vectorized(const Scalar& _s) { + return vector_type().vectorize(_s); + } + + /// lexicographical comparison + bool operator<(const vector_type& _rhs) const { + return std::lexicographical_compare( + values_.begin(), values_.end(), + _rhs.values_.begin(), _rhs.values_.end()); + } + + /// swap with another vector + void swap(VectorT& _other) + noexcept(noexcept(std::swap(values_, _other.values_))) { + std::swap(values_, _other.values_); + } + + //------------------------------------------------------------ component iterators + + /// \name Component iterators + //@{ + + using iterator = typename container::iterator; + using const_iterator = typename container::const_iterator; + using reverse_iterator = typename container::reverse_iterator; + using const_reverse_iterator = typename container::const_reverse_iterator; + + iterator begin() noexcept { return values_.begin(); } + const_iterator begin() const noexcept { return values_.cbegin(); } + const_iterator cbegin() const noexcept { return values_.cbegin(); } + + iterator end() noexcept { return values_.end(); } + const_iterator end() const noexcept { return values_.cend(); } + const_iterator cend() const noexcept { return values_.cend(); } + + reverse_iterator rbegin() noexcept { return values_.rbegin(); } + const_reverse_iterator rbegin() const noexcept { return values_.crbegin(); } + const_reverse_iterator crbegin() const noexcept { return values_.crbegin(); } + + reverse_iterator rend() noexcept { return values_.rend(); } + const_reverse_iterator rend() const noexcept { return values_.crend(); } + const_reverse_iterator crend() const noexcept { return values_.crend(); } + + //@} +}; + +/// Component wise multiplication from the left +template +auto operator*(const OtherScalar& _s, const VectorT &rhs) -> + decltype(rhs.operator*(_s)) { + + return rhs * _s; +} + +/// output a vector by printing its space-separated compontens +template +auto operator<<(std::ostream& os, const VectorT &_vec) -> + typename std::enable_if< + sizeof(decltype(os << _vec[0])) >= 0, std::ostream&>::type { + + os << _vec[0]; + for (int i = 1; i < DIM; ++i) { + os << " " << _vec[i]; + } + return os; +} + +/// read the space-separated components of a vector from a stream +template +auto operator>> (std::istream& is, VectorT &_vec) -> + typename std::enable_if< + sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type { + for (int i = 0; i < DIM; ++i) + is >> _vec[i]; + return is; +} + +/// \relates OpenMesh::VectorT +/// symmetric version of the dot product +template +Scalar dot(const VectorT& _v1, const VectorT& _v2) { + return (_v1 | _v2); +} + +/// \relates OpenMesh::VectorT +/// symmetric version of the cross product +template +auto +cross(const VectorT& _v1, const VectorT& _v2) -> + decltype(_v1 % _v2) { + return (_v1 % _v2); +} + +/// \relates OpenMesh::VectorT +/// non-member swap +template +void swap(VectorT& _v1, VectorT& _v2) +noexcept(noexcept(_v1.swap(_v2))) { + _v1.swap(_v2); +} + +/// \relates OpenMesh::VectorT +/// non-member norm +template +Scalar norm(const VectorT& _v) { + return _v.norm(); +} + +/// \relates OpenMesh::VectorT +/// non-member sqrnorm +template +Scalar sqrnorm(const VectorT& _v) { + return _v.sqrnorm(); +} +/// \relates OpenMesh::VectorT +/// non-member vectorize +template +VectorT& vectorize(VectorT& _v, OtherScalar const& _val) { + return _v.vectorize(_val); +} + +/// \relates OpenMesh::VectorT +/// non-member normalize +template +VectorT& normalize(VectorT& _v) { + return _v.normalize(); +} + +/// \relates OpenMesh::VectorT +/// non-member maximize +template +VectorT& maximize(VectorT& _v1, VectorT& _v2) { + return _v1.maximize(_v2); +} + +/// \relates OpenMesh::VectorT +/// non-member minimize +template +VectorT& minimize(VectorT& _v1, VectorT& _v2) { + return _v1.minimize(_v2); +} + +//== TYPEDEFS ================================================================= + +/** 1-byte signed vector */ +typedef VectorT Vec1c; +/** 1-byte unsigned vector */ +typedef VectorT Vec1uc; +/** 1-short signed vector */ +typedef VectorT Vec1s; +/** 1-short unsigned vector */ +typedef VectorT Vec1us; +/** 1-int signed vector */ +typedef VectorT Vec1i; +/** 1-int unsigned vector */ +typedef VectorT Vec1ui; +/** 1-float vector */ +typedef VectorT Vec1f; +/** 1-double vector */ +typedef VectorT Vec1d; + +/** 2-byte signed vector */ +typedef VectorT Vec2c; +/** 2-byte unsigned vector */ +typedef VectorT Vec2uc; +/** 2-short signed vector */ +typedef VectorT Vec2s; +/** 2-short unsigned vector */ +typedef VectorT Vec2us; +/** 2-int signed vector */ +typedef VectorT Vec2i; +/** 2-int unsigned vector */ +typedef VectorT Vec2ui; +/** 2-float vector */ +typedef VectorT Vec2f; +/** 2-double vector */ +typedef VectorT Vec2d; + +/** 3-byte signed vector */ +typedef VectorT Vec3c; +/** 3-byte unsigned vector */ +typedef VectorT Vec3uc; +/** 3-short signed vector */ +typedef VectorT Vec3s; +/** 3-short unsigned vector */ +typedef VectorT Vec3us; +/** 3-int signed vector */ +typedef VectorT Vec3i; +/** 3-int unsigned vector */ +typedef VectorT Vec3ui; +/** 3-float vector */ +typedef VectorT Vec3f; +/** 3-double vector */ +typedef VectorT Vec3d; +/** 3-bool vector */ +typedef VectorT Vec3b; + +/** 4-byte signed vector */ +typedef VectorT Vec4c; +/** 4-byte unsigned vector */ +typedef VectorT Vec4uc; +/** 4-short signed vector */ +typedef VectorT Vec4s; +/** 4-short unsigned vector */ +typedef VectorT Vec4us; +/** 4-int signed vector */ +typedef VectorT Vec4i; +/** 4-int unsigned vector */ +typedef VectorT Vec4ui; +/** 4-float vector */ +typedef VectorT Vec4f; +/** 4-double vector */ +typedef VectorT Vec4d; + +/** 5-byte signed vector */ +typedef VectorT Vec5c; +/** 5-byte unsigned vector */ +typedef VectorT Vec5uc; +/** 5-short signed vector */ +typedef VectorT Vec5s; +/** 5-short unsigned vector */ +typedef VectorT Vec5us; +/** 5-int signed vector */ +typedef VectorT Vec5i; +/** 5-int unsigned vector */ +typedef VectorT Vec5ui; +/** 5-float vector */ +typedef VectorT Vec5f; +/** 5-double vector */ +typedef VectorT Vec5d; + +/** 6-byte signed vector */ +typedef VectorT Vec6c; +/** 6-byte unsigned vector */ +typedef VectorT Vec6uc; +/** 6-short signed vector */ +typedef VectorT Vec6s; +/** 6-short unsigned vector */ +typedef VectorT Vec6us; +/** 6-int signed vector */ +typedef VectorT Vec6i; +/** 6-int unsigned vector */ +typedef VectorT Vec6ui; +/** 6-float vector */ +typedef VectorT Vec6f; +/** 6-double vector */ +typedef VectorT Vec6d; + +} // namespace OpenMesh + +/** + * Literal operator for inline specification of colors in HTML syntax. + * + * Example: + * \code{.cpp} + * OpenMesh::Vec4f light_blue = 0x1FCFFFFF_htmlColor; + * \endcode + */ +constexpr OpenMesh::Vec4f operator"" _htmlColor(unsigned long long raw_color) { + return OpenMesh::Vec4f( + ((raw_color >> 24) & 0xFF) / 255.0f, + ((raw_color >> 16) & 0xFF) / 255.0f, + ((raw_color >> 8) & 0xFF) / 255.0f, + ((raw_color >> 0) & 0xFF) / 255.0f); +} + +#endif /* OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_ */ diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/VectorT.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/VectorT.hh new file mode 100644 index 0000000..3384332 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/VectorT.hh @@ -0,0 +1,440 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS VectorT +// +//============================================================================= + +// Don't parse this header file with doxygen since +// for some reason (obviously due to a bug in doxygen, +// bugreport: https://bugzilla.gnome.org/show_bug.cgi?id=629182) +// macro expansion and preprocessor defines +// don't work properly. + +#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY) +#include "Vector11T.hh" +#else +#ifndef DOXYGEN + +#ifndef OPENMESH_VECTOR_HH +#define OPENMESH_VECTOR_HH + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(__SSE__) +#include +#endif + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/** The N values of the template Scalar type are the only data members + of the class VectorT. This guarantees 100% compatibility + with arrays of type Scalar and size N, allowing us to define the + cast operators to and from arrays and array pointers. + + In addition, this class will be specialized for Vec4f to be 16 bit + aligned, so that aligned SSE instructions can be used on these + vectors. +*/ +template class VectorDataT { + public: + Scalar values_[N]; +}; + + +#if defined(__GNUC__) && defined(__SSE__) + +/// This specialization enables us to use aligned SSE instructions. +template<> class VectorDataT { + public: + union { + __m128 m128; + float values_[4]; + }; +}; + +#endif + + + + +//== CLASS DEFINITION ========================================================= + + +#define DIM N +#define TEMPLATE_HEADER template +#define CLASSNAME VectorT +#define DERIVED VectorDataT +#define unroll(expr) for (int i=0; i + A vector is an array of \ values of type \. + The actual data is stored in an VectorDataT, this class just adds + the necessary operators. +*/ +#include "VectorT_inc.hh" + +#undef DIM +#undef TEMPLATE_HEADER +#undef CLASSNAME +#undef DERIVED +#undef unroll + + + + +//== PARTIAL TEMPLATE SPECIALIZATIONS ========================================= +#if OM_PARTIAL_SPECIALIZATION + + +#define TEMPLATE_HEADER template +#define CLASSNAME VectorT +#define DERIVED VectorDataT + + +#define DIM 2 +#define unroll(expr) expr(0) expr(1) +#define unroll_comb(expr, op) expr(0) op expr(1) +#define unroll_csv(expr) expr(0), expr(1) +#include "VectorT_inc.hh" +#undef DIM +#undef unroll +#undef unroll_comb +#undef unroll_csv + + +#define DIM 3 +#define unroll(expr) expr(0) expr(1) expr(2) +#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) +#define unroll_csv(expr) expr(0), expr(1), expr(2) +#include "VectorT_inc.hh" +#undef DIM +#undef unroll +#undef unroll_comb +#undef unroll_csv + + +#define DIM 4 +#define unroll(expr) expr(0) expr(1) expr(2) expr(3) +#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3) +#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3) +#include "VectorT_inc.hh" +#undef DIM +#undef unroll +#undef unroll_comb +#undef unroll_csv + +#define DIM 5 +#define unroll(expr) expr(0) expr(1) expr(2) expr(3) expr(4) +#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3) op expr(4) +#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3), expr(4) +#include "VectorT_inc.hh" +#undef DIM +#undef unroll +#undef unroll_comb +#undef unroll_csv + +#define DIM 6 +#define unroll(expr) expr(0) expr(1) expr(2) expr(3) expr(4) expr(5) +#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3) op expr(4) op expr(5) +#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3), expr(4), expr(5) +#include "VectorT_inc.hh" +#undef DIM +#undef unroll +#undef unroll_comb +#undef unroll_csv + + +#undef TEMPLATE_HEADER +#undef CLASSNAME +#undef DERIVED + + + + +//== FULL TEMPLATE SPECIALIZATIONS ============================================ +#else + +/// cross product for Vec3f +template<> +inline VectorT +VectorT::operator%(const VectorT& _rhs) const +{ + return + VectorT(values_[1]*_rhs.values_[2]-values_[2]*_rhs.values_[1], + values_[2]*_rhs.values_[0]-values_[0]*_rhs.values_[2], + values_[0]*_rhs.values_[1]-values_[1]*_rhs.values_[0]); +} + + +/// cross product for Vec3d +template<> +inline VectorT +VectorT::operator%(const VectorT& _rhs) const +{ + return + VectorT(values_[1]*_rhs.values_[2]-values_[2]*_rhs.values_[1], + values_[2]*_rhs.values_[0]-values_[0]*_rhs.values_[2], + values_[0]*_rhs.values_[1]-values_[1]*_rhs.values_[0]); +} + +#endif + + + +//== GLOBAL FUNCTIONS ========================================================= + + +/// \relates OpenMesh::VectorT +/// scalar * vector +template +inline VectorT operator*(Scalar2 _s, const VectorT& _v) { + return _v*_s; +} + + +/// \relates OpenMesh::VectorT +/// symmetric version of the dot product +template +inline Scalar +dot(const VectorT& _v1, const VectorT& _v2) { + return (_v1 | _v2); +} + + +/// \relates OpenMesh::VectorT +/// symmetric version of the cross product +template +inline VectorT +cross(const VectorT& _v1, const VectorT& _v2) { + return (_v1 % _v2); +} + + +/// \relates OpenMesh::VectorT +/// non-member norm +template +Scalar norm(const VectorT& _v) { + return _v.norm(); +} + + +/// \relates OpenMesh::VectorT +/// non-member sqrnorm +template +Scalar sqrnorm(const VectorT& _v) { + return _v.sqrnorm(); +} + + +/// \relates OpenMesh::VectorT +/// non-member vectorize +template +VectorT& vectorize(VectorT& _v, OtherScalar const& _val) { + return _v.vectorize(_val); +} + + +/// \relates OpenMesh::VectorT +/// non-member normalize +template +VectorT& normalize(VectorT& _v) { + return _v.normalize(); +} + + +/// \relates OpenMesh::VectorT +/// non-member maximize +template +VectorT& maximize(VectorT& _v1, VectorT& _v2) { + return _v1.maximize(_v2); +} + + +/// \relates OpenMesh::VectorT +/// non-member minimize +template +VectorT& minimize(VectorT& _v1, VectorT& _v2) { + return _v1.minimize(_v2); +} + + +//== TYPEDEFS ================================================================= + +/** 1-byte signed vector */ +typedef VectorT Vec1c; +/** 1-byte unsigned vector */ +typedef VectorT Vec1uc; +/** 1-short signed vector */ +typedef VectorT Vec1s; +/** 1-short unsigned vector */ +typedef VectorT Vec1us; +/** 1-int signed vector */ +typedef VectorT Vec1i; +/** 1-int unsigned vector */ +typedef VectorT Vec1ui; +/** 1-float vector */ +typedef VectorT Vec1f; +/** 1-double vector */ +typedef VectorT Vec1d; + +/** 2-byte signed vector */ +typedef VectorT Vec2c; +/** 2-byte unsigned vector */ +typedef VectorT Vec2uc; +/** 2-short signed vector */ +typedef VectorT Vec2s; +/** 2-short unsigned vector */ +typedef VectorT Vec2us; +/** 2-int signed vector */ +typedef VectorT Vec2i; +/** 2-int unsigned vector */ +typedef VectorT Vec2ui; +/** 2-float vector */ +typedef VectorT Vec2f; +/** 2-double vector */ +typedef VectorT Vec2d; + +/** 3-byte signed vector */ +typedef VectorT Vec3c; +/** 3-byte unsigned vector */ +typedef VectorT Vec3uc; +/** 3-short signed vector */ +typedef VectorT Vec3s; +/** 3-short unsigned vector */ +typedef VectorT Vec3us; +/** 3-int signed vector */ +typedef VectorT Vec3i; +/** 3-int unsigned vector */ +typedef VectorT Vec3ui; +/** 3-float vector */ +typedef VectorT Vec3f; +/** 3-double vector */ +typedef VectorT Vec3d; +/** 3-bool vector */ +typedef VectorT Vec3b; + +/** 4-byte signed vector */ +typedef VectorT Vec4c; +/** 4-byte unsigned vector */ +typedef VectorT Vec4uc; +/** 4-short signed vector */ +typedef VectorT Vec4s; +/** 4-short unsigned vector */ +typedef VectorT Vec4us; +/** 4-int signed vector */ +typedef VectorT Vec4i; +/** 4-int unsigned vector */ +typedef VectorT Vec4ui; +/** 4-float vector */ +typedef VectorT Vec4f; +/** 4-double vector */ +typedef VectorT Vec4d; + +/** 5-byte signed vector */ +typedef VectorT Vec5c; +/** 5-byte unsigned vector */ +typedef VectorT Vec5uc; +/** 5-short signed vector */ +typedef VectorT Vec5s; +/** 5-short unsigned vector */ +typedef VectorT Vec5us; +/** 5-int signed vector */ +typedef VectorT Vec5i; +/** 5-int unsigned vector */ +typedef VectorT Vec5ui; +/** 5-float vector */ +typedef VectorT Vec5f; +/** 5-double vector */ +typedef VectorT Vec5d; + +/** 6-byte signed vector */ +typedef VectorT Vec6c; +/** 6-byte unsigned vector */ +typedef VectorT Vec6uc; +/** 6-short signed vector */ +typedef VectorT Vec6s; +/** 6-short unsigned vector */ +typedef VectorT Vec6us; +/** 6-int signed vector */ +typedef VectorT Vec6i; +/** 6-int unsigned vector */ +typedef VectorT Vec6ui; +/** 6-float vector */ +typedef VectorT Vec6f; +/** 6-double vector */ +typedef VectorT Vec6d; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + + +#endif // OPENMESH_VECTOR_HH defined +//============================================================================= +#endif // DOXYGEN +#endif // C++11 diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/VectorT_inc.hh b/libs/OpenMesh/include/OpenMesh/Core/Geometry/VectorT_inc.hh new file mode 100644 index 0000000..96b6c10 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/VectorT_inc.hh @@ -0,0 +1,668 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +// Set template keywords and class names properly when +// parsing with doxygen. This only seems to work this way since +// the scope of preprocessor defines is limited to one file in doxy. +#ifdef DOXYGEN + +// Only used for correct doxygen parsing +#define OPENMESH_VECTOR_HH + +#define DIM N +#define TEMPLATE_HEADER template +#define CLASSNAME VectorT +#define DERIVED VectorDataT +#define unroll(expr) for (int i=0; i vector_type; + + /// returns dimension of the vector (deprecated) + static inline int dim() { return DIM; } + + /// returns dimension of the vector + static inline size_t size() { return DIM; } + + static const size_t size_ = DIM; + + + //-------------------------------------------------------------- constructors + + /// default constructor creates uninitialized values. + inline VectorT() {} + + /// special constructor for 1D vectors + explicit inline VectorT(const Scalar& v) { +// assert(DIM==1); +// values_[0] = v0; + vectorize(v); + } + +#if DIM == 2 + /// special constructor for 2D vectors + inline VectorT(const Scalar v0, const Scalar v1) { + Base::values_[0] = v0; Base::values_[1] = v1; + } +#endif + +#if DIM == 3 + /// special constructor for 3D vectors + inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2) { + Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; + } +#endif + +#if DIM == 4 + /// special constructor for 4D vectors + inline VectorT(const Scalar v0, const Scalar v1, + const Scalar v2, const Scalar v3) { + Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3; + } + + VectorT homogenized() const { return VectorT(Base::values_[0]/Base::values_[3], Base::values_[1]/Base::values_[3], Base::values_[2]/Base::values_[3], 1); } +#endif + +#if DIM == 5 + /// special constructor for 5D vectors + inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2, + const Scalar v3, const Scalar v4) { + Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4; + } +#endif + +#if DIM == 6 + /// special constructor for 6D vectors + inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2, + const Scalar v3, const Scalar v4, const Scalar v5) { + Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; + Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5; + } +#endif + + /// construct from a value array (explicit) + explicit inline VectorT(const Scalar _values[DIM]) { + memcpy(data(), _values, DIM*sizeof(Scalar)); + } + + +#ifdef OM_CC_MIPS + /// assignment from a vector of the same kind + // mipspro need this method + inline vector_type& operator=(const vector_type& _rhs) { + memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar)); + return *this; + } +#endif + + + /// copy & cast constructor (explicit) + template + explicit inline VectorT(const VectorT& _rhs) { + operator=(_rhs); + } + + + + + //--------------------------------------------------------------------- casts + + /// cast from vector with a different scalar type + template + inline vector_type& operator=(const VectorT& _rhs) { +#define expr(i) Base::values_[i] = (Scalar)_rhs[i]; + unroll(expr); +#undef expr + return *this; + } + +// /// cast to Scalar array +// inline operator Scalar*() { return Base::values_; } + +// /// cast to const Scalar array +// inline operator const Scalar*() const { return Base::values_; } + + /// access to Scalar array + inline Scalar* data() { return Base::values_; } + + /// access to const Scalar array + inline const Scalar*data() const { return Base::values_; } + + + //----------------------------------------------------------- element access + +// /// get i'th element read-write +// inline Scalar& operator[](int _i) { +// assert(_i>=0 && _i=0 && _i operator%(const VectorT& _rhs) const +#if DIM==3 + { + return + VectorT(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1], + Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2], + Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]); + } +#else + ; +#endif + + + /// compute scalar product + /// \see OpenMesh::dot + inline Scalar operator|(const vector_type& _rhs) const { + Scalar p(0); +#define expr(i) p += Base::values_[i] * _rhs.Base::values_[i]; + unroll(expr); +#undef expr + return p; + } + + + + + + //------------------------------------------------------------ euclidean norm + + /// \name Euclidean norm calculations + //@{ + /// compute euclidean norm + inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); } + inline Scalar length() const { return norm(); } // OpenSG interface + + /// compute squared euclidean norm + inline Scalar sqrnorm() const + { +#if DIM==N + Scalar s(0); +#define expr(i) s += Base::values_[i] * Base::values_[i]; + unroll(expr); +#undef expr + return s; +#else +#define expr(i) Base::values_[i]*Base::values_[i] + return (unroll_comb(expr, +)); +#undef expr +#endif + } + + /** normalize vector, return normalized vector + */ + + inline vector_type& normalize() + { + *this /= norm(); + return *this; + } + + /** return normalized vector + */ + + inline const vector_type normalized() const + { + return *this / norm(); + } + + /** normalize vector, return normalized vector and avoids div by zero + */ + inline vector_type& normalize_cond() + { + Scalar n = norm(); + if (n != (Scalar)0.0) + { + *this /= n; + } + return *this; + } + + //@} + + //------------------------------------------------------------ euclidean norm + + /// \name Non-Euclidean norm calculations + //@{ + + /// compute L1 (Manhattan) norm + inline Scalar l1_norm() const + { +#if DIM==N + Scalar s(0); +#define expr(i) s += std::abs(Base::values_[i]); + unroll(expr); +#undef expr + return s; +#else +#define expr(i) std::abs(Base::values_[i]) + return (unroll_comb(expr, +)); +#undef expr +#endif + } + + /// compute l8_norm + inline Scalar l8_norm() const + { + return max_abs(); + } + + //@} + + //------------------------------------------------------------ max, min, mean + + /// \name Minimum maximum and mean + //@{ + + /// return the maximal component + inline Scalar max() const + { + Scalar m(Base::values_[0]); + for(int i=1; im) m=Base::values_[i]; + return m; + } + + /// return the maximal absolute component + inline Scalar max_abs() const + { + Scalar m(std::abs(Base::values_[0])); + for(int i=1; im) + m=std::abs(Base::values_[i]); + return m; + } + + + /// return the minimal component + inline Scalar min() const + { + Scalar m(Base::values_[0]); + for(int i=1; i Base::values_[i]) Base::values_[i] = _rhs[i]; + unroll(expr); +#undef expr + return *this; + } + + /// maximize values and signalize coordinate maximization + inline bool maximized(const vector_type& _rhs) { + bool result(false); +#define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; } + unroll(expr); +#undef expr + return result; + } + + /// component-wise min + inline vector_type min(const vector_type& _rhs) const { + return vector_type(*this).minimize(_rhs); + } + + /// component-wise max + inline vector_type max(const vector_type& _rhs) const { + return vector_type(*this).maximize(_rhs); + } + + //@} + + //------------------------------------------------------------ misc functions + + /// component-wise apply function object with Scalar operator()(Scalar). + template + inline vector_type apply(const Functor& _func) const { + vector_type result; +#define expr(i) result[i] = _func(Base::values_[i]); + unroll(expr); +#undef expr + return result; + } + + /// store the same value in each component (e.g. to clear all entries) + vector_type& vectorize(const Scalar& _s) { +#define expr(i) Base::values_[i] = _s; + unroll(expr); +#undef expr + return *this; + } + + + /// store the same value in each component + static vector_type vectorized(const Scalar& _s) { + return vector_type().vectorize(_s); + } + + + /// lexicographical comparison + bool operator<(const vector_type& _rhs) const { +#define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \ + return (Base::values_[i] < _rhs.Base::values_[i]); + unroll(expr); +#undef expr + return false; + } +}; + + + +/// read the space-separated components of a vector from a stream +TEMPLATE_HEADER +inline std::istream& +operator>>(std::istream& is, VectorT& vec) +{ +#define expr(i) is >> vec[i]; + unroll(expr); +#undef expr + return is; +} + + +/// output a vector by printing its space-separated compontens +TEMPLATE_HEADER +inline std::ostream& +operator<<(std::ostream& os, const VectorT& vec) +{ +#if DIM==N + for(int i=0; i +// -------------------- STL +#if defined( OM_CC_MIPS ) +# include +#else +# include +#endif +#include +// -------------------- OpenMesh + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + +//============================================================================= + + +/** \name Handling binary input/output. + These functions take care of swapping bytes to get the right Endian. +*/ +//@{ + +//----------------------------------------------------------------------------- + + +/** Binary read a \c short from \c _is and perform byte swapping if + \c _swap is true */ +short int read_short(FILE* _in, bool _swap=false); + +/** Binary read an \c int from \c _is and perform byte swapping if + \c _swap is true */ +int read_int(FILE* _in, bool _swap=false); + +/** Binary read a \c float from \c _is and perform byte swapping if + \c _swap is true */ +float read_float(FILE* _in, bool _swap=false); + +/** Binary read a \c double from \c _is and perform byte swapping if + \c _swap is true */ +double read_double(FILE* _in, bool _swap=false); + +/** Binary read a \c short from \c _is and perform byte swapping if + \c _swap is true */ +short int read_short(std::istream& _in, bool _swap=false); + +/** Binary read an \c int from \c _is and perform byte swapping if + \c _swap is true */ +int read_int(std::istream& _in, bool _swap=false); + +/** Binary read a \c float from \c _is and perform byte swapping if + \c _swap is true */ +float read_float(std::istream& _in, bool _swap=false); + +/** Binary read a \c double from \c _is and perform byte swapping if + \c _swap is true */ +double read_double(std::istream& _in, bool _swap=false); + + +/** Binary write a \c short to \c _os and perform byte swapping if + \c _swap is true */ +void write_short(short int _i, FILE* _out, bool _swap=false); + +/** Binary write an \c int to \c _os and perform byte swapping if + \c _swap is true */ +void write_int(int _i, FILE* _out, bool _swap=false); + +/** Binary write a \c float to \c _os and perform byte swapping if + \c _swap is true */ +void write_float(float _f, FILE* _out, bool _swap=false); + +/** Binary write a \c double to \c _os and perform byte swapping if + \c _swap is true */ +void write_double(double _d, FILE* _out, bool _swap=false); + +/** Binary write a \c short to \c _os and perform byte swapping if + \c _swap is true */ +void write_short(short int _i, std::ostream& _out, bool _swap=false); + +/** Binary write an \c int to \c _os and perform byte swapping if + \c _swap is true */ +void write_int(int _i, std::ostream& _out, bool _swap=false); + +/** Binary write a \c float to \c _os and perform byte swapping if + \c _swap is true */ +void write_float(float _f, std::ostream& _out, bool _swap=false); + +/** Binary write a \c double to \c _os and perform byte swapping if + \c _swap is true */ +void write_double(double _d, std::ostream& _out, bool _swap=false); + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESHREADER_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/IOInstances.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/IOInstances.hh new file mode 100644 index 0000000..744b9a8 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/IOInstances.hh @@ -0,0 +1,115 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper file for static builds +// +// In opposite to dynamic builds where the instance of every reader module +// is generated within the OpenMesh library, static builds only instanciate +// objects that are at least referenced once. As all reader modules are +// never used directly, they will not be part of a static build, hence +// this file. +// +//============================================================================= + + +#ifndef __IOINSTANCES_HH__ +#define __IOINSTANCES_HH__ + +#if defined(OM_STATIC_BUILD) || defined(ARCH_DARWIN) + +//============================================================================= + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//=== NAMESPACES ============================================================== + +namespace OpenMesh { +namespace IO { + +//============================================================================= + + +// Instanciate every Reader module +static BaseReader* OFFReaderInstance = &OFFReader(); +static BaseReader* OBJReaderInstance = &OBJReader(); +static BaseReader* PLYReaderInstance = &PLYReader(); +static BaseReader* STLReaderInstance = &STLReader(); +static BaseReader* OMReaderInstance = &OMReader(); + +// Instanciate every writer module +static BaseWriter* OBJWriterInstance = &OBJWriter(); +static BaseWriter* OFFWriterInstance = &OFFWriter(); +static BaseWriter* STLWriterInstance = &STLWriter(); +static BaseWriter* OMWriterInstance = &OMWriter(); +static BaseWriter* PLYWriterInstance = &PLYWriter(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // static ? +#endif //__IOINSTANCES_HH__ +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/IOManager.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/IOManager.hh new file mode 100644 index 0000000..58c157f --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/IOManager.hh @@ -0,0 +1,272 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +//============================================================================= +// +// Implements the OpenMesh IOManager singleton +// +//============================================================================= + +#ifndef __IOMANAGER_HH__ +#define __IOMANAGER_HH__ + + +//=== INCLUDES ================================================================ + + +// STL +#include +#include +#include +#include + +// OpenMesh +#include +#include +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** This is the real IOManager class that is later encapsulated by + SingletonT to enforce its uniqueness. _IOManager_ is not meant to be used + directly by the programmer - the IOManager alias exists for this task. + + All reader/writer modules register themselves at this class. For + reading or writing data all modules are asked to do the job. If no + suitable module is found, an error is returned. + + For the sake of reading, the target data structure is hidden + behind the BaseImporter interface that takes care of adding + vertices or faces. + + Writing from a source structure is encapsulate similarly behind a + BaseExporter interface, providing iterators over vertices/faces to + the writer modules. + + \see \ref mesh_io +*/ + +class OPENMESHDLLEXPORT _IOManager_ +{ +private: + + /// Constructor has nothing todo for the Manager + _IOManager_() {} + + /// Destructor has nothing todo for the Manager + ~_IOManager_() {}; + + /** Declare the singleton getter function as friend to access the private constructor + and destructor + */ + friend OPENMESHDLLEXPORT _IOManager_& IOManager(); + +public: + + /** + Read a mesh from file _filename. The target data structure is specified + by the given BaseImporter. The \c read method consecutively queries all + of its reader modules. True is returned upon success, false if all + reader modules failed to interprete _filename. + */ + bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt); + +/** + Read a mesh from open std::istream _is. The target data structure is specified + by the given BaseImporter. The \c sread method consecutively queries all + of its reader modules. True is returned upon success, false if all + reader modules failed to use _is. + */ + bool read(std::istream& _filename, + const std::string& _ext, + BaseImporter& _bi, + Options& _opt); + + + /** Write a mesh to file _filename. The source data structure is specified + by the given BaseExporter. The \c save method consecutively queries all + of its writer modules. True is returned upon success, false if all + writer modules failed to write the requested format. + Options is determined by _filename's extension. + */ + bool write(const std::string& _filename, + BaseExporter& _be, + Options _opt=Options::Default, + std::streamsize _precision = 6); + +/** Write a mesh to open std::ostream _os. The source data structure is specified + by the given BaseExporter. The \c save method consecutively queries all + of its writer modules. True is returned upon success, false if all + writer modules failed to write the requested format. + Options is determined by _filename's extension. + */ + bool write(std::ostream& _filename, + const std::string& _ext, + BaseExporter& _be, + Options _opt=Options::Default, + std::streamsize _precision = 6); + + + /// Returns true if the format is supported by one of the reader modules. + bool can_read( const std::string& _format ) const; + + /// Returns true if the format is supported by one of the writer modules. + bool can_write( const std::string& _format ) const; + + + size_t binary_size(const std::string& _format, + BaseExporter& _be, + Options _opt = Options::Default) + { + const BaseWriter *bw = find_writer(_format); + return bw ? bw->binary_size(_be,_opt) : 0; + } + + + +public: //-- QT convenience function ------------------------------------------ + + + /** Returns all readable file extension + descriptions in one string. + File formats are separated by ;;. + Convenience function for Qt file dialogs. + */ + const std::string& qt_read_filters() const { return read_filters_; } + + + /** Returns all writeable file extension + descriptions in one string. + File formats are separated by ;;. + Convenience function for Qt file dialogs. + */ + const std::string& qt_write_filters() const { return write_filters_; } + + + +private: + + // collect all readable file extensions + void update_read_filters(); + + + // collect all writeable file extensions + void update_write_filters(); + + + +public: //-- SYSTEM PART------------------------------------------------------ + + + /** Registers a new reader module. A call to this function should be + implemented in the constructor of all classes derived from BaseReader. + */ + bool register_module(BaseReader* _bl) + { + reader_modules_.insert(_bl); + update_read_filters(); + return true; + } + + + + /** Registers a new writer module. A call to this function should be + implemented in the constructor of all classed derived from BaseWriter. + */ + bool register_module(BaseWriter* _bw) + { + writer_modules_.insert(_bw); + update_write_filters(); + return true; + } + + +private: + + const BaseWriter *find_writer(const std::string& _format); + + // stores registered reader modules + std::set reader_modules_; + + // stores registered writer modules + std::set writer_modules_; + + // input filters (e.g. for Qt file dialog) + std::string read_filters_; + + // output filters (e.g. for Qt file dialog) + std::string write_filters_; +}; + + +//============================================================================= + + +//_IOManager_* __IOManager_instance; Causes memory leak, as destructor is never called + +OPENMESHDLLEXPORT _IOManager_& IOManager(); + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/MeshIO.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/MeshIO.hh new file mode 100644 index 0000000..49b6f64 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/MeshIO.hh @@ -0,0 +1,296 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +#ifndef OM_MESHIO_HH +#define OM_MESHIO_HH + + +//=== INCLUDES ================================================================ + +// -------------------- system settings +#include + +// -------------------- check include order +#if defined (OPENMESH_TRIMESH_ARRAY_KERNEL_HH) || \ + defined (OPENMESH_POLYMESH_ARRAY_KERNEL_HH) + + // Issue warning if MeshIO was not included before Mesh Type + // Nobody knows why this order was enforced. + // If somebody encounters an error resulting from a wrong order, please report it to the OpenMesh developers. + // If we don't here about any errors, this check will be removed + // @TODO: Remove after reasonable time + #ifdef WIN32 + #pragma message("MeshIO.hh was included after Mesh Type. You may ignore this warning. Please report errors resulting ifrom this order to the developers!") + #else + #warning "MeshIO.hh was included after Mesh Type. You may ignore this warning. Please report errors resulting from this order to the developers!" + #endif + +#endif + +// -------------------- OpenMesh +#include +#include +#include +#include + + +//== NAMESPACES ============================================================== + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** \name Mesh Reading / Writing + Convenience functions the map to IOManager functions. + \see OpenMesh::IO::_IOManager_ +*/ +//@{ + + +//----------------------------------------------------------------------------- + + +/** \brief Read a mesh from file _filename. + + The file format is determined by the file extension. + + \note If you link statically against OpenMesh, you have to add + the define OM_STATIC_BUILD to your application. This will + ensure that readers and writers get initialized correctly. + + @param _mesh The target mesh that will be filled with the read data + @param _filename fill to load + + @return Successful? + */ +template +bool +read_mesh(Mesh& _mesh, + const std::string& _filename) +{ + Options opt; + return read_mesh(_mesh, _filename, opt, true); +} + + +/** \brief Read a mesh from file _filename. + + The file format is determined by the file extension. + + \note If you link statically against OpenMesh, you have to add + the define OM_STATIC_BUILD to your application. This will + ensure that readers and writers get initialized correctly. + + @param _mesh The target mesh that will be filled with the read data + @param _filename fill to load + @param _opt Reader options (e.g. skip loading of normals ... depends + on the reader capabilities). Note that simply passing an + Options::Flag enum is not sufficient. + @param _clear Clear the target data before filling it (allows to + load multiple files into one Mesh). If you only want to read a mesh + without clearing set _clear to false. Providing a default Options + object is sufficient in this case. + + @return Successful? +*/ +template +bool +read_mesh(Mesh& _mesh, + const std::string& _filename, + Options& _opt, + bool _clear = true) +{ + if (_clear) _mesh.clear(); + ImporterT importer(_mesh); + return IOManager().read(_filename, importer, _opt); +} + + +/** \brief Read a mesh from file open std::istream. + + The file format is determined by parameter _ext. _ext has to include + ".[format]" in order to work properly (e.g. ".OFF") + + \note If you link statically against OpenMesh, you have to add + the define OM_STATIC_BUILD to your application. This will + ensure that readers and writers get initialized correctly. + + @param _mesh The target mesh that will be filled with the read data + @param _is stream to load the data from + @param _ext The file format that is written to the stream + @param _opt Reader options (e.g. skip loading of normals ... depends + on the reader capabilities) + @param _clear Clear the target data before filling it (allows to + load multiple files into one Mesh) + + @return Successful? +*/ +template +bool +read_mesh(Mesh& _mesh, + std::istream& _is, + const std::string& _ext, + Options& _opt, + bool _clear = true) +{ + if (_clear) _mesh.clear(); + ImporterT importer(_mesh); + return IOManager().read(_is,_ext, importer, _opt); +} + + + +//----------------------------------------------------------------------------- + + +/** \brief Write a mesh to the file _filename. + + The file format is determined by _filename's extension. + + \note If you link statically against OpenMesh, you have to add + the define OM_STATIC_BUILD to your application. This will + ensure that readers and writers get initialized correctly. + + @param _mesh The mesh that will be written to file + @param _filename output filename + @param _opt Writer options (e.g. writing of normals ... depends + on the writer capabilities) + @param _precision specifies stream precision for ascii files + + @return Successful? +*/ +template +bool write_mesh(const Mesh& _mesh, + const std::string& _filename, + Options _opt = Options::Default, + std::streamsize _precision = 6) +{ + ExporterT exporter(_mesh); + return IOManager().write(_filename, exporter, _opt, _precision); +} + + +//----------------------------------------------------------------------------- + + +/** Write a mesh to an open std::ostream. + + The file format is determined by parameter _ext. _ext has to include + ".[format]" in order to work properly (e.g. ".OFF") + + \note If you link statically against OpenMesh, you have to add + the define OM_STATIC_BUILD to your application. This will + ensure that readers and writers get initialized correctly. + + @param _mesh The mesh that will be written to file + @param _os output stream to write into + @param _ext extension defining the type of output + @param _opt Writer options (e.g. writing of normals ... depends + on the writer capabilities) + @param _precision specifies stream precision for ascii files + + @return Successful? +*/ +template +bool write_mesh(const Mesh& _mesh, + std::ostream& _os, + const std::string& _ext, + Options _opt = Options::Default, + std::streamsize _precision = 6) +{ + ExporterT exporter(_mesh); + return IOManager().write(_os,_ext, exporter, _opt, _precision); +} + + +//----------------------------------------------------------------------------- + +/** \brief Get binary size of data + + This function calls the corresponding writer which calculates the size + of the data that would be written to a binary file + + The file format is determined by parameter _ext. _ext has to include + ".[format]" in order to work properly (e.g. ".OFF") + + @param _mesh Mesh to write + @param _ext extension of the file (used to determine the writing module) + @param _opt Writer options (e.g. writing of normals ... depends + on the writer capabilities) + + @return Binary size in bytes used when writing the data +*/ +template +size_t binary_size(const Mesh& _mesh, + const std::string& _ext, + Options _opt = Options::Default) +{ + ExporterT exporter(_mesh); + return IOManager().binary_size(_ext, exporter, _opt); +} + + +//----------------------------------------------------------------------------- + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#if defined(OM_STATIC_BUILD) || defined(ARCH_DARWIN) +# include +#endif +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/OFFFormat.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/OFFFormat.hh new file mode 100644 index 0000000..bd87f56 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/OFFFormat.hh @@ -0,0 +1,99 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +#ifndef OPENMESH_IO_OFFFORMAT_HH +#define OPENMESH_IO_OFFFORMAT_HH + + +//=== INCLUDES ================================================================ + + +// OpenMesh +#include + + +//== NAMESPACES ============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** \name Mesh Reading / Writing + Option for writer modules. +*/ +//@{ + + +//----------------------------------------------------------------------------- + +#ifndef DOXY_IGNORE_THIS + +struct OPENMESHDLLEXPORT OFFFormat +{ + typedef int integer_type; + typedef float float_type; +}; + +#endif + + + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/OMFormat.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/OMFormat.hh new file mode 100644 index 0000000..9bbcd86 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/OMFormat.hh @@ -0,0 +1,751 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +#ifndef OPENMESH_IO_OMFORMAT_HH +#define OPENMESH_IO_OMFORMAT_HH + + +//=== INCLUDES ================================================================ + +#include +#include +#include +#include +#include +#include +// -------------------- +#include +#if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000) +# include +# define OM_MISSING_HEADER_LIMITS 1 +#else +# include +#endif + + +//== NAMESPACES ============================================================== + +#ifndef DOXY_IGNORE_THIS +namespace OpenMesh { +namespace IO { +namespace OMFormat { + + +//=== IMPLEMENTATION ========================================================== + + +/** \name Mesh Reading / Writing +*/ +//@{ + +//----------------------------------------------------------------------------- + + // <:Header> + // <:Comment> + // Chunk 0 + // <:ChunkHeader> + // <:Comment> + // data + // Chunk 1 + // <:ChunkHeader> + // <:Comment> + // data + // . + // . + // . + // Chunk N + + // + // NOTICE! + // + // The usage of data types who differ in size + // on different pc architectures (32/64 bit) and/or + // operating systems, e.g. (unsigned) long, size_t, + // is not recommended because of inconsistencies + // in case of cross writing and reading. + // + // Basic types that are supported are: + + + typedef unsigned char uchar; + typedef uint8_t uint8; + typedef uint16_t uint16; + typedef uint32_t uint32; + typedef uint64_t uint64; + typedef int8_t int8; + typedef int16_t int16; + typedef int32_t int32; + typedef int64_t int64; + typedef float32_t float32; + typedef float64_t float64; + + struct Header + { + uchar magic_[2]; // OM + uchar mesh_; // [T]riangles, [Q]uads, [P]olygonals + uint8 version_; + uint32 n_vertices_; + uint32 n_faces_; + uint32 n_edges_; + + size_t store( std::ostream& _os, bool _swap ) const + { + _os.write( (char*)this, 4); // magic_, mesh_, version_ + size_t bytes = 4; + bytes += binary::store( _os, n_vertices_, _swap ); + bytes += binary::store( _os, n_faces_, _swap ); + bytes += binary::store( _os, n_edges_, _swap ); + return bytes; + } + + size_t restore( std::istream& _is, bool _swap ) + { + if (_is.read( (char*)this, 4 ).eof()) + return 0; + + size_t bytes = 4; + bytes += binary::restore( _is, n_vertices_, _swap ); + bytes += binary::restore( _is, n_faces_, _swap ); + bytes += binary::restore( _is, n_edges_, _swap ); + return bytes; + } + + }; + + struct Chunk + { + // Hardcoded this size to an uint32 to make the system 32/64 bit compatible. + // Needs further investigation! + typedef uint32 esize_t; // element size, used for custom properties + + enum Type { + Type_Pos = 0x00, + Type_Normal = 0x01, + Type_Texcoord = 0x02, + Type_Status = 0x03, + Type_Color = 0x04, + Type_Custom = 0x06, + Type_Topology = 0x07 + }; + + enum Entity { + Entity_Vertex = 0x00, + Entity_Mesh = 0x01, + Entity_Face = 0x02, + Entity_Edge = 0x04, + Entity_Halfedge = 0x06, + Entity_Sentinel = 0x07 + }; + + enum Dim { + Dim_1D = 0x00, + Dim_2D = 0x01, + Dim_3D = 0x02, + Dim_4D = 0x03, + Dim_5D = 0x04, + Dim_6D = 0x05, + Dim_7D = 0x06, + Dim_8D = 0x07 + }; + + enum Integer_Size { + Integer_8 = 0x00, // 1 byte for (unsigned) char + Integer_16 = 0x01, // 2 bytes for short + Integer_32 = 0x02, // 4 bytes for long + Integer_64 = 0x03 // 8 bytes for long long + }; + + enum Float_Size { + Float_32 = 0x00, // 4 bytes for float + Float_64 = 0x01, // 8 bytes for double + Float_128 = 0x02 // 16 bytes for long double (an assumption!) + }; + + static const int SIZE_RESERVED = 1; // 1 + static const int SIZE_NAME = 1; // 2 + static const int SIZE_ENTITY = 3; // 5 + static const int SIZE_TYPE = 4; // 9 + + static const int SIZE_SIGNED = 1; // 10 + static const int SIZE_FLOAT = 1; // 11 + static const int SIZE_DIM = 3; // 14 + static const int SIZE_BITS = 2; // 16 + + static const int OFF_RESERVED = 0; // 0 + static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED; // 2 + static const int OFF_ENTITY = SIZE_NAME + OFF_NAME; // 3 + static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY; // 5 + static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE; // 9 + static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED; // 10 + static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT; // 11 + static const int OFF_BITS = SIZE_DIM + OFF_DIM; // 14 + + // !Attention! When changing the bit size, the operators + // << (uint16, Header) and << (Header, uint16) must be changed as well + // + // Entries signed_, float_, dim_, bits_ are not used when type_ + // equals Type_Custom + // + struct Header // 16 bits long + { + unsigned reserved_: SIZE_RESERVED; + unsigned name_ : SIZE_NAME; // 1 named property, 0 anonymous + unsigned entity_ : SIZE_ENTITY; // 0 vertex, 1 mesh, 2 edge, + // 4 halfedge, 6 face + unsigned type_ : SIZE_TYPE; // 0 pos, 1 normal, 2 texcoord, + // 3 status, 4 color 6 custom 7 topology + unsigned signed_ : SIZE_SIGNED; // bool + unsigned float_ : SIZE_FLOAT; // bool + unsigned dim_ : SIZE_DIM; // 0 1D, 1 2D, 2 3D, .., 7 8D + unsigned bits_ : SIZE_BITS; // {8, 16, 32, 64} | {32, 64, 128} + // (integer) (float) + unsigned unused_ : 16; // fill up to 32 bits + }; // struct Header + + + class PropertyName : public std::string + { + public: + + static const size_t size_max = 256; + + PropertyName( ) { } + + PropertyName( const std::string& _name ) { *this = _name; } + + bool is_valid() const { return is_valid( size() ); } + + static bool is_valid( size_t _s ) { return _s <= size_max; } + + PropertyName& operator = ( const std::string& _rhs ) + { + assert( is_valid( _rhs.size() ) ); + + if ( is_valid( _rhs.size() ) ) + std::string::operator = ( _rhs ); + else + { + omerr() << "Warning! Property name too long. Will be shortened!\n"; + this->std::string::operator = ( _rhs.substr(0, size_max) ); + } + + return *this; + } + + }; + + }; // Chunk + + // ------------------------------------------------------------ Helper + + // -------------------- get size information + + /// Return size of header in bytes. + inline size_t header_size(void) { return sizeof(Header); } + + + /// Return size of chunk header in bytes. + inline size_t chunk_header_size( void ) { return sizeof(uint16); } + + + /// Return the size of a scale in bytes. + inline size_t scalar_size( const Chunk::Header& _hdr ) + { + return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_); + } + + + /// Return the dimension of the vector in a chunk + inline size_t dimensions(const Chunk::Header& _chdr) { return _chdr.dim_+1; } + + + /// Return the size of a vector in bytes. + inline size_t vector_size( const Chunk::Header& _chdr ) + { + return dimensions(_chdr)*scalar_size(_chdr); + } + + + /// Return the size of chunk data in bytes + inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr ) + { + size_t C; + switch( _chunk_hdr.entity_ ) + { + case Chunk::Entity_Vertex: C = _hdr.n_vertices_; break; + case Chunk::Entity_Face: C = _hdr.n_faces_; break; + case Chunk::Entity_Halfedge: C = _hdr.n_edges_*2; break; + case Chunk::Entity_Edge: C = _hdr.n_edges_; break; + case Chunk::Entity_Mesh: C = 1; break; + default: + C = 0; + std::cerr << "Invalid value in _chunk_hdr.entity_\n"; + assert( false ); + break; + } + + return C * vector_size( _chunk_hdr ); + } + + inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr ) + { + return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr ); + } + + // -------------------- convert from Chunk::Header to storage type + + uint16& operator << (uint16& val, const Chunk::Header& hdr); + Chunk::Header& operator << (Chunk::Header& hdr, const uint16 val); + + + // -------------------- type information + + template bool is_float(const T&) + { +#if defined(OM_MISSING_HEADER_LIMITS) + return !Utils::NumLimitsT::is_integer(); +#else + return !std::numeric_limits::is_integer; +#endif + } + + template bool is_integer(const T) + { +#if defined(OM_MISSING_HEADER_LIMITS) + return Utils::NumLimitsT::is_integer(); +#else + return std::numeric_limits::is_integer; +#endif + } + + template bool is_signed(const T&) + { +#if defined(OM_MISSING_HEADER_LIMITS) + return Utils::NumLimitsT::is_signed(); +#else + return std::numeric_limits::is_signed; +#endif + } + + // -------------------- conversions (format type <- type/value) + + template + inline + Chunk::Dim dim( VecType ) + { + assert( vector_traits< VecType >::size() < 9 ); + return static_cast(vector_traits< VecType >::size() - 1); + } + + template + inline + Chunk::Dim dim( const Chunk::Header& _hdr ) + { + return static_cast( _hdr.dim_ ); + } + + // calc minimum (power-of-2) number of bits needed + Chunk::Integer_Size needed_bits( size_t s ); + + // Convert size of type to Integer_Size +#ifdef NDEBUG + template Chunk::Integer_Size integer_size(const T&) +#else + template Chunk::Integer_Size integer_size(const T& d) +#endif + { +#ifndef NDEBUG + assert( is_integer(d) ); +#endif + + switch( sizeof(T) ) + { + case 1: return OMFormat::Chunk::Integer_8; + case 2: return OMFormat::Chunk::Integer_16; + case 4: return OMFormat::Chunk::Integer_32; + case 8: return OMFormat::Chunk::Integer_64; + default: + std::cerr << "Invalid value in integer_size\n"; + assert( false ); + break; + } + return Chunk::Integer_Size(0); + } + + + // Convert size of type to FLoat_Size +#ifdef NDEBUG + template Chunk::Float_Size float_size(const T&) +#else + template Chunk::Float_Size float_size(const T& d) +#endif + { +#ifndef NDEBUG + assert( is_float(d) ); +#endif + + switch( sizeof(T) ) + { + case 4: return OMFormat::Chunk::Float_32; + case 8: return OMFormat::Chunk::Float_64; + case 16: return OMFormat::Chunk::Float_128; + default: + std::cerr << "Invalid value in float_size\n"; + assert( false ); + break; + } + return Chunk::Float_Size(0); + } + + // Return the storage type (Chunk::Header::bits_) + template + inline + unsigned int bits(const T& val) + { + return is_integer(val) + ? (static_cast(integer_size(val))) + : (static_cast(float_size(val))); + } + + // -------------------- create/read version + + inline uint8 mk_version(const uint16 major, const uint16 minor) + { return (major & 0x07) << 5 | (minor & 0x1f); } + + + inline uint16 major_version(const uint8 version) + { return (version >> 5) & 0x07; } + + + inline uint16 minor_version(const uint8 version) + { return (version & 0x001f); } + + + // ---------------------------------------- convenience functions + + const char *as_string(Chunk::Type t); + const char *as_string(Chunk::Entity e); + const char *as_string(Chunk::Dim d); + const char *as_string(Chunk::Integer_Size d); + const char *as_string(Chunk::Float_Size d); + + std::ostream& operator << ( std::ostream& _os, const Header& _h ); + std::ostream& operator << ( std::ostream& _os, const Chunk::Header& _c ); + +//@} +} // namespace OMFormat + + // -------------------- (re-)store header + + template <> inline + size_t store( std::ostream& _os, const OMFormat::Header& _hdr, bool _swap) + { return _hdr.store( _os, _swap ); } + + template <> inline + size_t restore( std::istream& _is, OMFormat::Header& _hdr, bool _swap ) + { return _hdr.restore( _is, _swap ); } + + + // -------------------- (re-)store chunk header + + template <> inline + size_t + store( std::ostream& _os, const OMFormat::Chunk::Header& _hdr, bool _swap) + { + OMFormat::uint16 val; val << _hdr; + return binary::store( _os, val, _swap ); + } + + template <> inline + size_t + restore( std::istream& _is, OMFormat::Chunk::Header& _hdr, bool _swap ) + { + OMFormat::uint16 val; + size_t bytes = binary::restore( _is, val, _swap ); + + _hdr << val; + + return bytes; + } + + // -------------------- (re-)store integer with wanted number of bits (bytes) + + typedef GenProg::TrueType t_signed; + typedef GenProg::FalseType t_unsigned; + + // helper to store a an integer + template< typename T > + size_t + store( std::ostream& _os, + const T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap, + t_signed); + + // helper to store a an unsigned integer + template< typename T > + size_t + store( std::ostream& _os, + const T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap, + t_unsigned); + + /// Store an integer with a wanted number of bits + template< typename T > + inline + size_t + store( std::ostream& _os, + const T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap) + { + assert( OMFormat::is_integer( _val ) ); + + if ( OMFormat::is_signed( _val ) ) + return store( _os, _val, _b, _swap, t_signed() ); + return store( _os, _val, _b, _swap, t_unsigned() ); + } + + // helper to store a an integer + template< typename T > inline + size_t restore( std::istream& _is, + T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap, + t_signed); + + // helper to store a an unsigned integer + template< typename T > inline + size_t restore( std::istream& _is, + T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap, + t_unsigned); + + /// Restore an integer with a wanted number of bits + template< typename T > + inline + size_t + restore( std::istream& _is, + T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap) + { + assert( OMFormat::is_integer( _val ) ); + + if ( OMFormat::is_signed( _val ) ) + return restore( _is, _val, _b, _swap, t_signed() ); + return restore( _is, _val, _b, _swap, t_unsigned() ); + } + + + // + // ---------------------------------------- storing vectors + template inline + size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<2>, + bool _swap ) + { + size_t bytes = store( _os, _vec[0], _swap ); + bytes += store( _os, _vec[1], _swap ); + return bytes; + } + + template inline + size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<3>, + bool _swap ) + { + size_t bytes = store( _os, _vec[0], _swap ); + bytes += store( _os, _vec[1], _swap ); + bytes += store( _os, _vec[2], _swap ); + return bytes; + } + + template inline + size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<4>, + bool _swap ) + { + size_t bytes = store( _os, _vec[0], _swap ); + bytes += store( _os, _vec[1], _swap ); + bytes += store( _os, _vec[2], _swap ); + bytes += store( _os, _vec[3], _swap ); + return bytes; + } + + template inline + size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<1>, + bool _swap ) + { + return store( _os, _vec[0], _swap ); + } + + /// storing a vector type + template inline + size_t vector_store( std::ostream& _os, const VecT& _vec, bool _swap ) + { + return store( _os, _vec, + GenProg::Int2Type< vector_traits::size_ >(), + _swap ); + } + + // ---------------------------------------- restoring vectors + template + inline + size_t + restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<2>, + bool _swap ) + { + size_t bytes = restore( _is, _vec[0], _swap ); + bytes += restore( _is, _vec[1], _swap ); + return bytes; + } + + template + inline + size_t + restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<3>, + bool _swap ) + { + typedef typename vector_traits::value_type scalar_type; + size_t bytes; + + bytes = binary::restore( _is, _vec[0], _swap ); + bytes += binary::restore( _is, _vec[1], _swap ); + bytes += binary::restore( _is, _vec[2], _swap ); + return bytes; + } + + template + inline + size_t + restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<4>, + bool _swap ) + { + typedef typename vector_traits::value_type scalar_type; + size_t bytes; + + bytes = binary::restore( _is, _vec[0], _swap ); + bytes += binary::restore( _is, _vec[1], _swap ); + bytes += binary::restore( _is, _vec[2], _swap ); + bytes += binary::restore( _is, _vec[3], _swap ); + return bytes; + } + + template + inline + size_t + restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<1>, + bool _swap ) + { + return restore( _is, _vec[0], _swap ); + } + + /// Restoring a vector type + template + inline + size_t + vector_restore( std::istream& _is, VecT& _vec, bool _swap ) + { + return restore( _is, _vec, + GenProg::Int2Type< vector_traits::size_ >(), + _swap ); + } + + + // ---------------------------------------- storing property names + + template <> + inline + size_t store( std::ostream& _os, const OMFormat::Chunk::PropertyName& _pn, + bool _swap ) + { + store( _os, _pn.size(), OMFormat::Chunk::Integer_8, _swap ); // 1 byte + if ( _pn.size() ) + _os.write( _pn.c_str(), _pn.size() ); // size bytes + return _pn.size() + 1; + } + + template <> + inline + size_t restore( std::istream& _is, OMFormat::Chunk::PropertyName& _pn, + bool _swap ) + { + size_t size; + + restore( _is, size, OMFormat::Chunk::Integer_8, _swap); // 1 byte + + assert( OMFormat::Chunk::PropertyName::is_valid( size ) ); + + if ( size > 0 ) + { + char buf[256]; + _is.read( buf, size ); // size bytes + buf[size] = '\0'; + _pn.resize(size); + _pn = buf; + } + return size+1; + } + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +#endif +//============================================================================= +#if defined(OM_MISSING_HEADER_LIMITS) +# undef OM_MISSING_HEADER_LIMITS +#endif +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC) +# define OPENMESH_IO_OMFORMAT_TEMPLATES +# include "OMFormatT.cc" +#endif +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/Options.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/Options.hh new file mode 100644 index 0000000..f266725 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/Options.hh @@ -0,0 +1,250 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +#ifndef OPENMESH_IO_OPTIONS_HH +#define OPENMESH_IO_OPTIONS_HH + + +//=== INCLUDES ================================================================ + + +// OpenMesh +#include + + +//== NAMESPACES ============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** \name Mesh Reading / Writing + Option for reader and writer modules. +*/ +//@{ + + +//----------------------------------------------------------------------------- + +/** \brief Set options for reader/writer modules. + * + * The class is used in a twofold way. + * -# In combination with reader modules the class is used + * - to pass hints to the reading module, whether the input is + * binary and what byte ordering the binary data has + * - to retrieve information about the file contents after + * succesful reading. + * -# In combination with write modules the class gives directions to + * the writer module, whether to + * - use binary mode or not and what byte order to use + * - store one of the standard properties. + * + * The option are defined in \c Options::Flag as bit values and stored in + * an \c int value as a bitset. + */ +class Options +{ +public: + typedef int enum_type; + typedef enum_type value_type; + + /// Definitions of %Options for reading and writing. The options can be + /// or'ed. + enum Flag { + Default = 0x0000, ///< No options + Binary = 0x0001, ///< Set binary mode for r/w + MSB = 0x0002, ///< Assume big endian byte ordering + LSB = 0x0004, ///< Assume little endian byte ordering + Swap = 0x0008, ///< Swap byte order in binary mode + VertexNormal = 0x0010, ///< Has (r) / store (w) vertex normals + VertexColor = 0x0020, ///< Has (r) / store (w) vertex colors + VertexTexCoord = 0x0040, ///< Has (r) / store (w) texture coordinates + EdgeColor = 0x0080, ///< Has (r) / store (w) edge colors + FaceNormal = 0x0100, ///< Has (r) / store (w) face normals + FaceColor = 0x0200, ///< Has (r) / store (w) face colors + FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates + ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors + ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) + Custom = 0x2000 ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version) + }; + +public: + + /// Default constructor + Options() : flags_( Default ) + { } + + + /// Copy constructor + Options(const Options& _opt) : flags_(_opt.flags_) + { } + + + /// Initializing constructor setting a single option + Options(Flag _flg) : flags_( _flg) + { } + + + /// Initializing constructor setting multiple options + Options(const value_type _flgs) : flags_( _flgs) + { } + + + ~Options() + { } + + /// Restore state after default constructor. + void cleanup(void) + { flags_ = Default; } + + /// Clear all bits. + void clear(void) + { flags_ = 0; } + + /// Returns true if all bits are zero. + bool is_empty(void) const { return !flags_; } + +public: + + + //@{ + /// Copy options defined in _rhs. + + Options& operator = ( const Options& _rhs ) + { flags_ = _rhs.flags_; return *this; } + + Options& operator = ( const value_type _rhs ) + { flags_ = _rhs; return *this; } + + //@} + + + //@{ + /// Unset options defined in _rhs. + + Options& operator -= ( const value_type _rhs ) + { flags_ &= ~_rhs; return *this; } + + Options& unset( const value_type _rhs) + { return (*this -= _rhs); } + + //@} + + + + //@{ + /// Set options defined in _rhs + + Options& operator += ( const value_type _rhs ) + { flags_ |= _rhs; return *this; } + + Options& set( const value_type _rhs) + { return (*this += _rhs); } + + //@} + +public: + + + // Check if an option or several options are set. + bool check(const value_type _rhs) const + { + return (flags_ & _rhs)==_rhs; + } + + bool is_binary() const { return check(Binary); } + bool vertex_has_normal() const { return check(VertexNormal); } + bool vertex_has_color() const { return check(VertexColor); } + bool vertex_has_texcoord() const { return check(VertexTexCoord); } + bool edge_has_color() const { return check(EdgeColor); } + bool face_has_normal() const { return check(FaceNormal); } + bool face_has_color() const { return check(FaceColor); } + bool face_has_texcoord() const { return check(FaceTexCoord); } + bool color_has_alpha() const { return check(ColorAlpha); } + bool color_is_float() const { return check(ColorFloat); } + + + /// Returns true if _rhs has the same options enabled. + bool operator == (const value_type _rhs) const + { return flags_ == _rhs; } + + + /// Returns true if _rhs does not have the same options enabled. + bool operator != (const value_type _rhs) const + { return flags_ != _rhs; } + + + /// Returns the option set. + operator value_type () const { return flags_; } + +private: + + bool operator && (const value_type _rhs) const; + + value_type flags_; +}; + +//----------------------------------------------------------------------------- + + + + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary.hh new file mode 100644 index 0000000..05c9de8 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary.hh @@ -0,0 +1,136 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + +#ifndef OPENMESH_SR_BINARY_HH +#define OPENMESH_SR_BINARY_HH + + +//== INCLUDES ================================================================= + +#include +// -------------------- STL +#include +#include +#include +#include // accumulate +// -------------------- OpenMesh + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + +//============================================================================= + + +//----------------------------------------------------------------------------- + + const static size_t UnknownSize(size_t(-1)); + + +//----------------------------------------------------------------------------- +// struct binary, helper for storing/restoring + +#define X \ + std::ostringstream msg; \ + msg << "Type not supported: " << typeid(value_type).name(); \ + throw std::logic_error(msg.str()) + +/// \struct binary SR_binary.hh +/// +/// The struct defines how to store and restore the type T. +/// It's used by the OM reader/writer modules. +/// +/// The following specialization are provided: +/// - Fundamental types except \c long \c double +/// - %OpenMesh vector types +/// - %OpenMesh::StatusInfo +/// - std::string (max. length 65535) +/// +/// \todo Complete documentation of members +template < typename T > struct binary +{ + typedef T value_type; + + static const bool is_streamable = false; + + static size_t size_of(void) { return UnknownSize; } + static size_t size_of(const value_type&) { return UnknownSize; } + + static + size_t store( std::ostream& /* _os */, + const value_type& /* _v */, + bool /* _swap=false */) + { X; return 0; } + + static + size_t restore( std::istream& /* _is */, + value_type& /* _v */, + bool /* _swap=false */) + { X; return 0; } +}; + +#undef X + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_SR_RBO_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_spec.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_spec.hh new file mode 100644 index 0000000..956b6e8 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_spec.hh @@ -0,0 +1,329 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + +#ifndef OPENMESH_SR_BINARY_SPEC_HH +#define OPENMESH_SR_BINARY_SPEC_HH + +//== INCLUDES ================================================================= + +#include +// -------------------- STL +#include +#include +#if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000) +# include +#else +# include +#endif +#include +#include // logic_error +#include // accumulate +// -------------------- OpenMesh +#include +#include +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + +//============================================================================= + +#ifndef DOXY_IGNORE_THIS + +//----------------------------------------------------------------------------- +// struct binary, helper for storing/restoring + +#define SIMPLE_BINARY( T ) \ + template <> struct binary< T > { \ + typedef T value_type; \ + static const bool is_streamable = true; \ + static size_t size_of(const value_type&) { return sizeof(value_type); } \ + static size_t size_of(void) { return sizeof(value_type); } \ + static size_t store( std::ostream& _os, const value_type& _val, \ + bool _swap=false) { \ + value_type tmp = _val; \ + if (_swap) reverse_byte_order(tmp); \ + _os.write( (const char*)&tmp, sizeof(value_type) ); \ + return _os.good() ? sizeof(value_type) : 0; \ + } \ + \ + static size_t restore( std::istream& _is, value_type& _val, \ + bool _swap=false) { \ + _is.read( (char*)&_val, sizeof(value_type) ); \ + if (_swap) reverse_byte_order(_val); \ + return _is.good() ? sizeof(value_type) : 0; \ + } \ + } + +SIMPLE_BINARY(bool); +//SIMPLE_BINARY(int); + +// Why is this needed? Should not be used as not 32 bit compatible +//SIMPLE_BINARY(unsigned long); +SIMPLE_BINARY(float); +SIMPLE_BINARY(double); +SIMPLE_BINARY(long double); +SIMPLE_BINARY(char); + +SIMPLE_BINARY(int8_t); +SIMPLE_BINARY(int16_t); +SIMPLE_BINARY(int32_t); +SIMPLE_BINARY(int64_t); +SIMPLE_BINARY(uint8_t); +SIMPLE_BINARY(uint16_t); +SIMPLE_BINARY(uint32_t); +SIMPLE_BINARY(uint64_t); + +#undef SIMPLE_BINARY + +// For unsigned long which is of size 64 bit on 64 bit +// architectures: convert into 32 bit unsigned integer value +// in order to stay compatible between 32/64 bit architectures. +// This allows cross reading BUT forbids storing unsigned longs +// as data type since higher order word (4 bytes) will be truncated. +// Does not work in case the data type that is to be stored +// exceeds the value range of unsigned int in size, which is improbable... + +#define SIMPLE_BINARY( T ) \ + template <> struct binary< T > { \ + typedef T value_type; \ + static const bool is_streamable = true; \ + static size_t size_of(const value_type&) { return sizeof(value_type); } \ + static size_t size_of(void) { return sizeof(value_type); } \ + static size_t store( std::ostream& _os, const value_type& _val, \ + bool _swap=false) { \ + value_type tmp = _val; \ + if (_swap) reverse_byte_order(tmp); \ + /* Convert unsigned long to unsigned int for compatibility reasons */ \ + unsigned int t1 = static_cast(tmp); \ + _os.write( (const char*)&t1, sizeof(unsigned int) ); \ + return _os.good() ? sizeof(unsigned int) : 0; \ + } \ + \ + static size_t restore( std::istream& _is, value_type& _val, \ + bool _swap=false) { \ + unsigned int t1; \ + _is.read( (char*)&t1, sizeof(unsigned int) ); \ + _val = t1; \ + if (_swap) reverse_byte_order(_val); \ + return _is.good() ? sizeof(unsigned int) : 0; \ + } \ + } + +SIMPLE_BINARY(unsigned long); + +#undef SIMPLE_BINARY + +#define VECTORT_BINARY( T ) \ + template <> struct binary< T > { \ + typedef T value_type; \ + static const bool is_streamable = true; \ + static size_t size_of(void) { return sizeof(value_type); } \ + static size_t size_of(const value_type&) { return size_of(); } \ + static size_t store( std::ostream& _os, const value_type& _val, \ + bool _swap=false) { \ + value_type tmp = _val; \ + size_t i, b = size_of(_val), N = value_type::size_; \ + if (_swap) for (i=0; i struct binary< std::string > { + typedef std::string value_type; + typedef uint16_t length_t; + + static const bool is_streamable = true; + + static size_t size_of() { return UnknownSize; } + static size_t size_of(const value_type &_v) + { return sizeof(length_t) + _v.size(); } + + static + size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) + { +#if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000) + if (_v.size() < Utils::NumLimitsT::max() ) +#else + if (_v.size() < std::numeric_limits::max() ) +#endif + { + length_t len = length_t(_v.size()); + + size_t bytes = binary::store( _os, len, _swap ); + _os.write( _v.data(), len ); + return _os.good() ? len+bytes : 0; + } + throw std::runtime_error("Cannot store string longer than 64Kb"); + } + + static + size_t restore(std::istream& _is, value_type& _val, bool _swap=false) + { + length_t len; + size_t bytes = binary::restore( _is, len, _swap ); + _val.resize(len); + _is.read( const_cast(_val.data()), len ); + + return _is.good() ? (len+bytes) : 0; + } +}; + + +template <> struct binary +{ + typedef OpenMesh::Attributes::StatusInfo value_type; + typedef value_type::value_type status_t; + + static const bool is_streamable = true; + + static size_t size_of() { return sizeof(status_t); } + static size_t size_of(const value_type&) { return size_of(); } + + static size_t n_bytes(size_t _n_elem) + { return _n_elem*sizeof(status_t); } + + static + size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) + { + status_t v=_v.bits(); + return binary::store(_os, v, _swap); + } + + static + size_t restore( std::istream& _os, value_type& _v, bool _swap=false) + { + status_t v; + size_t b = binary::restore(_os, v, _swap); + _v.set_bits(v); + return b; + } +}; + + +//----------------------------------------------------------------------------- +// std::vector specializations for struct binary<> + +template +struct FunctorStore { + FunctorStore( std::ostream& _os, bool _swap) : os_(_os), swap_(_swap) { } + size_t operator () ( size_t _v1, const T& _s2 ) + { return _v1+binary::store(os_, _s2, swap_ ); } + + std::ostream& os_; + bool swap_; +}; + + +template +struct FunctorRestore { + FunctorRestore( std::istream& _is, bool _swap) : is_(_is), swap_(_swap) { } + size_t operator () ( size_t _v1, T& _s2 ) + { return _v1+binary::restore(is_, _s2, swap_ ); } + std::istream& is_; + bool swap_; +}; + +#include +#include +#include + +// ---------------------------------------------------------------------------- + +#endif // DOXY_IGNORE_THIS + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_SR_BINARY_SPEC_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_bool.inl b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_bool.inl new file mode 100644 index 0000000..3ec619c --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_bool.inl @@ -0,0 +1,98 @@ + +template <> struct binary< std::vector > +{ + + typedef std::vector< bool > value_type; + typedef value_type::value_type elem_type; + + static const bool is_streamable = true; + + static size_t size_of(void) { return UnknownSize; } + static size_t size_of(const value_type& _v) + { + return _v.size() / 8 + ((_v.size() % 8)!=0); + } + + static + size_t store( std::ostream& _ostr, const value_type& _v, bool ) + { + size_t bytes = 0; + + size_t N = _v.size() / 8; + size_t R = _v.size() % 8; + + size_t idx; // element index + unsigned char bits; // bitset + + for (idx=0; idx < N; ++idx) + { + bits = static_cast(_v[idx]) + | (static_cast(_v[idx+1]) << 1) + | (static_cast(_v[idx+2]) << 2) + | (static_cast(_v[idx+3]) << 3) + | (static_cast(_v[idx+4]) << 4) + | (static_cast(_v[idx+5]) << 5) + | (static_cast(_v[idx+6]) << 6) + | (static_cast(_v[idx+7]) << 7); + _ostr << bits; + } + bytes = N; + + if (R) + { + bits = 0; + switch(R) + { + case 7: bits |= (static_cast(_v[idx+6]) << 6); + case 6: bits |= (static_cast(_v[idx+5]) << 5); + case 5: bits |= (static_cast(_v[idx+4]) << 4); + case 4: bits |= (static_cast(_v[idx+3]) << 3); + case 3: bits |= (static_cast(_v[idx+2]) << 2); + case 2: bits |= (static_cast(_v[idx+1]) << 1); + case 1: bits |= static_cast(_v[idx+0]); + } + _ostr << bits; + ++bytes; + } + + assert( bytes == size_of(_v) ); + + return bytes; + } + + static + size_t restore( std::istream& _istr, value_type& _v, bool ) + { + size_t bytes = 0; + + size_t N = _v.size() / 8; + size_t R = _v.size() % 8; + + size_t idx; // element index + unsigned char bits; // bitset + + for (idx=0; idx < N; ++idx) + { + _istr >> bits; + _v[idx+0] = ((bits & 0x01)!=0); + _v[idx+1] = ((bits & 0x02)!=0); + _v[idx+2] = ((bits & 0x04)!=0); + _v[idx+3] = ((bits & 0x08)!=0); + _v[idx+4] = ((bits & 0x10)!=0); + _v[idx+5] = ((bits & 0x20)!=0); + _v[idx+6] = ((bits & 0x40)!=0); + _v[idx+7] = ((bits & 0x80)!=0); + } + bytes = N; + + if (R) + { + _istr >> bits; + for(; idx < _v.size(); ++idx) + _v[idx] = (bits & (1 << (idx%8)))!=0; + ++bytes; + } + + return bytes; + } +}; diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_fundamentals.inl b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_fundamentals.inl new file mode 100644 index 0000000..15ebae2 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_fundamentals.inl @@ -0,0 +1,53 @@ + +#define BINARY_VECTOR( T ) \ +template <> struct binary< std::vector< T > > { \ + typedef std::vector< T > value_type; \ + typedef value_type::value_type elem_type; \ + \ + static const bool is_streamable = true; \ + \ + static size_t size_of(void) \ + { return IO::UnknownSize; } \ + \ + static size_t size_of(const value_type& _v) \ + { return sizeof(elem_type)*_v.size(); } \ + \ + static \ + size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) { \ + size_t bytes=0; \ + \ + if (_swap) \ + bytes = std::accumulate( _v.begin(), _v.end(), bytes, \ + FunctorStore(_os,_swap) ); \ + else { \ + bytes = size_of(_v); \ + _os.write( reinterpret_cast(&_v[0]), bytes ); \ + } \ + return _os.good() ? bytes : 0; \ + } \ + \ + static size_t restore(std::istream& _is, value_type& _v, bool _swap=false) { \ + size_t bytes=0; \ + \ + if ( _swap) \ + bytes = std::accumulate( _v.begin(), _v.end(), size_t(0), \ + FunctorRestore(_is, _swap) ); \ + else \ + { \ + bytes = size_of(_v); \ + _is.read( reinterpret_cast(&_v[0]), bytes ); \ + } \ + return _is.good() ? bytes : 0; \ + } \ +} + +BINARY_VECTOR( short ); +BINARY_VECTOR( unsigned short ); +BINARY_VECTOR( int ); +BINARY_VECTOR( unsigned int ); +BINARY_VECTOR( long ); +BINARY_VECTOR( unsigned long ); +BINARY_VECTOR( float ); +BINARY_VECTOR( double ); + +#undef BINARY_VECTOR diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_string.inl b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_string.inl new file mode 100644 index 0000000..c6201de --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_binary_vector_of_string.inl @@ -0,0 +1,39 @@ + +template <> struct binary< std::vector< std::string > > +{ + // struct binary interface + + typedef std::vector< std::string > value_type; + typedef value_type::value_type elem_type; + + static const bool is_streamable = true; + + // Helper + + struct Sum + { + size_t operator() ( size_t _v1, const elem_type& _s2 ) + { return _v1 + binary::size_of(_s2); } + }; + + // struct binary interface + + static size_t size_of(void) { return UnknownSize; } + + static size_t size_of(const value_type& _v) + { return std::accumulate( _v.begin(), _v.end(), size_t(0), Sum() ); } + + static + size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) + { + return std::accumulate( _v.begin(), _v.end(), size_t(0), + FunctorStore(_os, _swap) ); + } + + static + size_t restore(std::istream& _is, value_type& _v, bool _swap=false) + { + return std::accumulate( _v.begin(), _v.end(), size_t(0), + FunctorRestore(_is, _swap) ); + } +}; diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_rbo.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_rbo.hh new file mode 100644 index 0000000..64275c4 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_rbo.hh @@ -0,0 +1,256 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + +#ifndef OPENMESH_SR_RBO_HH +#define OPENMESH_SR_RBO_HH + + +//== INCLUDES ================================================================= + +#include +// -------------------- STL +#if defined(OM_CC_MIPS) +# include // size_t +#else +# include // size_t +#endif +#include +#include +// -------------------- OpenMesh +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + +//============================================================================= + + +/** \name Handling binary input/output. + These functions take care of swapping bytes to get the right Endian. +*/ +//@{ + + +//----------------------------------------------------------------------------- + +/** this does not compile for g++3.4 and higher, hence we comment the +function body which will result in a linker error */ + +template < size_t N > inline +void _reverse_byte_order_N(uint8_t* _val); + +template <> inline +void _reverse_byte_order_N<1>(uint8_t* /*_val*/) { } + + +template <> inline +void _reverse_byte_order_N<2>(uint8_t* _val) +{ + _val[0] ^= _val[1]; _val[1] ^= _val[0]; _val[0] ^= _val[1]; +} + + +template <> inline +void _reverse_byte_order_N<4>(uint8_t* _val) +{ + _val[0] ^= _val[3]; _val[3] ^= _val[0]; _val[0] ^= _val[3]; // 0 <-> 3 + _val[1] ^= _val[2]; _val[2] ^= _val[1]; _val[1] ^= _val[2]; // 1 <-> 2 +} + + +template <> inline +void _reverse_byte_order_N<8>(uint8_t* _val) +{ + _val[0] ^= _val[7]; _val[7] ^= _val[0]; _val[0] ^= _val[7]; // 0 <-> 7 + _val[1] ^= _val[6]; _val[6] ^= _val[1]; _val[1] ^= _val[6]; // 1 <-> 6 + _val[2] ^= _val[5]; _val[5] ^= _val[2]; _val[2] ^= _val[5]; // 2 <-> 5 + _val[3] ^= _val[4]; _val[4] ^= _val[3]; _val[3] ^= _val[4]; // 3 <-> 4 +} + + +template <> inline +void _reverse_byte_order_N<12>(uint8_t* _val) +{ + _val[0] ^= _val[11]; _val[11] ^= _val[0]; _val[0] ^= _val[11]; // 0 <-> 11 + _val[1] ^= _val[10]; _val[10] ^= _val[1]; _val[1] ^= _val[10]; // 1 <-> 10 + _val[2] ^= _val[ 9]; _val[ 9] ^= _val[2]; _val[2] ^= _val[ 9]; // 2 <-> 9 + _val[3] ^= _val[ 8]; _val[ 8] ^= _val[3]; _val[3] ^= _val[ 8]; // 3 <-> 8 + _val[4] ^= _val[ 7]; _val[ 7] ^= _val[4]; _val[4] ^= _val[ 7]; // 4 <-> 7 + _val[5] ^= _val[ 6]; _val[ 6] ^= _val[5]; _val[5] ^= _val[ 6]; // 5 <-> 6 +} + + +template <> inline +void _reverse_byte_order_N<16>(uint8_t* _val) +{ + _reverse_byte_order_N<8>(_val); + _reverse_byte_order_N<8>(_val+8); + std::swap(*(uint64_t*)_val, *(((uint64_t*)_val)+1)); +} + + +//----------------------------------------------------------------------------- +// wrapper for byte reordering + +// reverting pointers makes no sense, hence forbid it. +/** this does not compile for g++3.4 and higher, hence we comment the +function body which will result in a linker error */ +template inline T* reverse_byte_order(T* t); +// Should never reach this point. If so, then some operator were not +// overloaded. Especially check for IO::binary<> specialization on +// custom data types. + + +inline void compile_time_error__no_fundamental_type() +{ + // we should never reach this point + assert(false); +} + +// default action for byte reversal: cause an error to avoid +// surprising behaviour! +template T& reverse_byte_order( T& _t ) +{ + omerr() << "Not defined for type " << typeid(T).name() << std::endl; + compile_time_error__no_fundamental_type(); + return _t; +} + +template <> inline bool& reverse_byte_order(bool & _t) { return _t; } +template <> inline char& reverse_byte_order(char & _t) { return _t; } +#if defined(OM_CC_GCC) +template <> inline signed char& reverse_byte_order(signed char & _t) { return _t; } +#endif +template <> inline uchar& reverse_byte_order(uchar& _t) { return _t; } + +// Instead do specializations for the necessary types +#define REVERSE_FUNDAMENTAL_TYPE( T ) \ + template <> inline T& reverse_byte_order( T& _t ) {\ + _reverse_byte_order_N( reinterpret_cast(&_t) ); \ + return _t; \ + } + +// REVERSE_FUNDAMENTAL_TYPE(bool) +// REVERSE_FUNDAMENTAL_TYPE(char) +// REVERSE_FUNDAMENTAL_TYPE(uchar) +REVERSE_FUNDAMENTAL_TYPE(int16_t) +REVERSE_FUNDAMENTAL_TYPE(uint16_t) +// REVERSE_FUNDAMENTAL_TYPE(int) +// REVERSE_FUNDAMENTAL_TYPE(uint) + +REVERSE_FUNDAMENTAL_TYPE(unsigned long) +REVERSE_FUNDAMENTAL_TYPE(int32_t) +REVERSE_FUNDAMENTAL_TYPE(uint32_t) +REVERSE_FUNDAMENTAL_TYPE(int64_t) +REVERSE_FUNDAMENTAL_TYPE(uint64_t) +REVERSE_FUNDAMENTAL_TYPE(float) +REVERSE_FUNDAMENTAL_TYPE(double) +REVERSE_FUNDAMENTAL_TYPE(long double) + +#undef REVERSE_FUNDAMENTAL_TYPE + +#if 0 + +#define REVERSE_VECTORT_TYPE( T ) \ + template <> inline T& reverse_byte_order(T& _v) {\ + for (size_t i; i< T::size_; ++i) \ + _reverse_byte_order_N< sizeof(T::value_type) >( reinterpret_cast(&_v[i])); \ + return _v; \ + } + +#define REVERSE_VECTORT_TYPES( N ) \ + REVERSE_VECTORT_TYPE( Vec##N##c ) \ + REVERSE_VECTORT_TYPE( Vec##N##uc ) \ + REVERSE_VECTORT_TYPE( Vec##N##s ) \ + REVERSE_VECTORT_TYPE( Vec##N##us ) \ + REVERSE_VECTORT_TYPE( Vec##N##i ) \ + REVERSE_VECTORT_TYPE( Vec##N##ui ) \ + REVERSE_VECTORT_TYPE( Vec##N##f ) \ + REVERSE_VECTORT_TYPE( Vec##N##d ) \ + +REVERSE_VECTORT_TYPES(1) +REVERSE_VECTORT_TYPES(2) +REVERSE_VECTORT_TYPES(3) +REVERSE_VECTORT_TYPES(4) +REVERSE_VECTORT_TYPES(6) + +#undef REVERSE_VECTORT_TYPES +#undef REVERSE_VECTORT_TYPE + +#endif + +template inline +T reverse_byte_order(const T& a) +{ + compile_timer_error__const_means_const(a); + return a; +} + + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_SR_RBO_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_store.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_store.hh new file mode 100644 index 0000000..e1b99a0 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_store.hh @@ -0,0 +1,72 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + +#ifndef OPENMESH_SR_STORE_HH +#define OPENMESH_SR_STORE_HH + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include +#include +#include + +//============================================================================= +#endif // OPENMESH_STORE_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/SR_types.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_types.hh new file mode 100644 index 0000000..9628f59 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/SR_types.hh @@ -0,0 +1,112 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + +#ifndef OPENMESH_SR_TYPES_HH +#define OPENMESH_SR_TYPES_HH + + +//== INCLUDES ================================================================= + +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + +//============================================================================= + + +/** \name Handling binary input/output. + These functions take care of swapping bytes to get the right Endian. +*/ +//@{ + +//----------------------------------------------------------------------------- + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned long ulong; + +typedef signed char int8_t; typedef unsigned char uint8_t; +typedef short int16_t; typedef unsigned short uint16_t; + +// Int should be 32 bit on all archs. +// long is 32 under windows but 64 under unix 64 bit +typedef int int32_t; typedef unsigned int uint32_t; +#if defined(OM_CC_MSVC) +typedef __int64 int64_t; typedef unsigned __int64 uint64_t; +#else +typedef long long int64_t; typedef unsigned long long uint64_t; +#endif + +typedef float float32_t; +typedef double float64_t; + +typedef uint8_t rgb_t[3]; +typedef uint8_t rgba_t[4]; + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESHREADER_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/StoreRestore.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/StoreRestore.hh new file mode 100644 index 0000000..fff6708 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/StoreRestore.hh @@ -0,0 +1,117 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + +#ifndef OPENMESH_STORERESTORE_HH +#define OPENMESH_STORERESTORE_HH + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + +//============================================================================= + + +/** \name Handling binary input/output. + These functions take care of swapping bytes to get the right Endian. +*/ +//@{ + + +//----------------------------------------------------------------------------- +// StoreRestore definitions + +template inline +bool is_streamable(void) +{ return binary< T >::is_streamable; } + +template inline +bool is_streamable( const T& ) +{ return binary< T >::is_streamable; } + +template inline +size_t size_of( const T& _v ) +{ return binary< T >::size_of(_v); } + +template inline +size_t size_of(void) +{ return binary< T >::size_of(); } + +template inline +size_t store( std::ostream& _os, const T& _v, bool _swap=false) +{ return binary< T >::store( _os, _v, _swap ); } + +template inline +size_t restore( std::istream& _is, T& _v, bool _swap=false) +{ return binary< T >::restore( _is, _v, _swap ); } + +//@} + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESHREADER_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/exporter/BaseExporter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/exporter/BaseExporter.hh new file mode 100644 index 0000000..477d95a --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/exporter/BaseExporter.hh @@ -0,0 +1,165 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements the baseclass for MeshWriter exporter modules +// +//============================================================================= + + +#ifndef __BASEEXPORTER_HH__ +#define __BASEEXPORTER_HH__ + + +//=== INCLUDES ================================================================ + + +// STL +#include + +// OpenMesh +#include +#include +#include + + +//=== NAMESPACES ============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== EXPORTER ================================================================ + + +/** + Base class for exporter modules. + The exporter modules provide an interface between the writer modules and + the target data structure. +*/ + +class OPENMESHDLLEXPORT BaseExporter +{ +public: + + virtual ~BaseExporter() { } + + + // get vertex data + virtual Vec3f point(VertexHandle _vh) const = 0; + virtual Vec3f normal(VertexHandle _vh) const = 0; + virtual Vec3uc color(VertexHandle _vh) const = 0; + virtual Vec4uc colorA(VertexHandle _vh) const = 0; + virtual Vec3ui colori(VertexHandle _vh) const = 0; + virtual Vec4ui colorAi(VertexHandle _vh) const = 0; + virtual Vec3f colorf(VertexHandle _vh) const = 0; + virtual Vec4f colorAf(VertexHandle _vh) const = 0; + virtual Vec2f texcoord(VertexHandle _vh) const = 0; + virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0; + + + // get face data + virtual unsigned int + get_vhandles(FaceHandle _fh, + std::vector& _vhandles) const=0; + /// + /// \brief getHeh returns the HalfEdgeHandle that belongs to the face + /// specified by _fh and has a toVertexHandle that corresponds to _vh. + /// \param _fh FaceHandle that is used to search for the half edge handle + /// \param _vh to_vertex_handle of the searched heh + /// \return HalfEdgeHandle or invalid HalfEdgeHandle if none is found. + /// + virtual HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const = 0; + virtual unsigned int + get_face_texcoords(std::vector& _hehandles) const = 0; + virtual Vec3f normal(FaceHandle _fh) const = 0; + virtual Vec3uc color (FaceHandle _fh) const = 0; + virtual Vec4uc colorA(FaceHandle _fh) const = 0; + virtual Vec3ui colori(FaceHandle _fh) const = 0; + virtual Vec4ui colorAi(FaceHandle _fh) const = 0; + virtual Vec3f colorf(FaceHandle _fh) const = 0; + virtual Vec4f colorAf(FaceHandle _fh) const = 0; + + // get edge data + virtual Vec3uc color(EdgeHandle _eh) const = 0; + virtual Vec4uc colorA(EdgeHandle _eh) const = 0; + virtual Vec3ui colori(EdgeHandle _eh) const = 0; + virtual Vec4ui colorAi(EdgeHandle _eh) const = 0; + virtual Vec3f colorf(EdgeHandle _eh) const = 0; + virtual Vec4f colorAf(EdgeHandle _eh) const = 0; + + // get reference to base kernel + virtual const BaseKernel* kernel() { return 0; } + + + // query number of faces, vertices, normals, texcoords + virtual size_t n_vertices() const = 0; + virtual size_t n_faces() const = 0; + virtual size_t n_edges() const = 0; + + + // property information + virtual bool is_triangle_mesh() const { return false; } + virtual bool has_vertex_normals() const { return false; } + virtual bool has_vertex_colors() const { return false; } + virtual bool has_vertex_texcoords() const { return false; } + virtual bool has_edge_colors() const { return false; } + virtual bool has_face_normals() const { return false; } + virtual bool has_face_colors() const { return false; } +}; + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/exporter/ExporterT.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/exporter/ExporterT.hh new file mode 100644 index 0000000..9a9d9b3 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/exporter/ExporterT.hh @@ -0,0 +1,338 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements an exporter module for arbitrary OpenMesh meshes +// +//============================================================================= + + +#ifndef __EXPORTERT_HH__ +#define __EXPORTERT_HH__ + + +//=== INCLUDES ================================================================ + +// C++ +#include + +// OpenMesh +#include +#include +#include +#include +#include +#include + + +//=== NAMESPACES ============================================================== + +namespace OpenMesh { +namespace IO { + + +//=== EXPORTER CLASS ========================================================== + +/** + * This class template provides an exporter module for OpenMesh meshes. + */ +template +class ExporterT : public BaseExporter +{ +public: + + // Constructor + ExporterT(const Mesh& _mesh) : mesh_(_mesh) {} + + + // get vertex data + + Vec3f point(VertexHandle _vh) const + { + return vector_cast(mesh_.point(_vh)); + } + + Vec3f normal(VertexHandle _vh) const + { + return (mesh_.has_vertex_normals() + ? vector_cast(mesh_.normal(_vh)) + : Vec3f(0.0f, 0.0f, 0.0f)); + } + + Vec3uc color(VertexHandle _vh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_vh)) + : Vec3uc(0, 0, 0)); + } + + Vec4uc colorA(VertexHandle _vh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_vh)) + : Vec4uc(0, 0, 0, 0)); + } + + Vec3ui colori(VertexHandle _vh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_vh)) + : Vec3ui(0, 0, 0)); + } + + Vec4ui colorAi(VertexHandle _vh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_vh)) + : Vec4ui(0, 0, 0, 0)); + } + + Vec3f colorf(VertexHandle _vh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_vh)) + : Vec3f(0, 0, 0)); + } + + Vec4f colorAf(VertexHandle _vh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_vh)) + : Vec4f(0, 0, 0, 0)); + } + + Vec2f texcoord(VertexHandle _vh) const + { +#if defined(OM_CC_GCC) && (OM_CC_VERSION<30000) + // Workaround! + // gcc 2.95.3 exits with internal compiler error at the + // code below!??? **) + if (mesh_.has_vertex_texcoords2D()) + return vector_cast(mesh_.texcoord2D(_vh)); + return Vec2f(0.0f, 0.0f); +#else // **) + return (mesh_.has_vertex_texcoords2D() + ? vector_cast(mesh_.texcoord2D(_vh)) + : Vec2f(0.0f, 0.0f)); +#endif + } + + Vec2f texcoord(HalfedgeHandle _heh) const + { + return (mesh_.has_halfedge_texcoords2D() + ? vector_cast(mesh_.texcoord2D(_heh)) + : Vec2f(0.0f, 0.0f)); + } + + // get edge data + + Vec3uc color(EdgeHandle _eh) const + { + return (mesh_.has_edge_colors() + ? color_cast(mesh_.color(_eh)) + : Vec3uc(0, 0, 0)); + } + + Vec4uc colorA(EdgeHandle _eh) const + { + return (mesh_.has_edge_colors() + ? color_cast(mesh_.color(_eh)) + : Vec4uc(0, 0, 0, 0)); + } + + Vec3ui colori(EdgeHandle _eh) const + { + return (mesh_.has_edge_colors() + ? color_cast(mesh_.color(_eh)) + : Vec3ui(0, 0, 0)); + } + + Vec4ui colorAi(EdgeHandle _eh) const + { + return (mesh_.has_edge_colors() + ? color_cast(mesh_.color(_eh)) + : Vec4ui(0, 0, 0, 0)); + } + + Vec3f colorf(EdgeHandle _eh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_eh)) + : Vec3f(0, 0, 0)); + } + + Vec4f colorAf(EdgeHandle _eh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_eh)) + : Vec4f(0, 0, 0, 0)); + } + + // get face data + + unsigned int get_vhandles(FaceHandle _fh, + std::vector& _vhandles) const + { + unsigned int count(0); + _vhandles.clear(); + for (typename Mesh::CFVIter fv_it=mesh_.cfv_iter(_fh); fv_it.is_valid(); ++fv_it) + { + _vhandles.push_back(*fv_it); + ++count; + } + return count; + } + + unsigned int get_face_texcoords(std::vector& _hehandles) const + { + unsigned int count(0); + _hehandles.clear(); + for(typename Mesh::CHIter he_it=mesh_.halfedges_begin(); + he_it != mesh_.halfedges_end(); ++he_it) + { + _hehandles.push_back(vector_cast(mesh_.texcoord2D( *he_it))); + ++count; + } + + return count; + } + + HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const + { + typename Mesh::ConstFaceHalfedgeIter fh_it; + for(fh_it = mesh_.cfh_iter(_fh); fh_it.is_valid();++fh_it) + { + if(mesh_.to_vertex_handle(*fh_it) == _vh) + return *fh_it; + } + return *fh_it; + } + + Vec3f normal(FaceHandle _fh) const + { + return (mesh_.has_face_normals() + ? vector_cast(mesh_.normal(_fh)) + : Vec3f(0.0f, 0.0f, 0.0f)); + } + + Vec3uc color(FaceHandle _fh) const + { + return (mesh_.has_face_colors() + ? color_cast(mesh_.color(_fh)) + : Vec3uc(0, 0, 0)); + } + + Vec4uc colorA(FaceHandle _fh) const + { + return (mesh_.has_face_colors() + ? color_cast(mesh_.color(_fh)) + : Vec4uc(0, 0, 0, 0)); + } + + Vec3ui colori(FaceHandle _fh) const + { + return (mesh_.has_face_colors() + ? color_cast(mesh_.color(_fh)) + : Vec3ui(0, 0, 0)); + } + + Vec4ui colorAi(FaceHandle _fh) const + { + return (mesh_.has_face_colors() + ? color_cast(mesh_.color(_fh)) + : Vec4ui(0, 0, 0, 0)); + } + + Vec3f colorf(FaceHandle _fh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_fh)) + : Vec3f(0, 0, 0)); + } + + Vec4f colorAf(FaceHandle _fh) const + { + return (mesh_.has_vertex_colors() + ? color_cast(mesh_.color(_fh)) + : Vec4f(0, 0, 0, 0)); + } + + virtual const BaseKernel* kernel() { return &mesh_; } + + + // query number of faces, vertices, normals, texcoords + size_t n_vertices() const { return mesh_.n_vertices(); } + size_t n_faces() const { return mesh_.n_faces(); } + size_t n_edges() const { return mesh_.n_edges(); } + + + // property information + bool is_triangle_mesh() const + { return Mesh::is_triangles(); } + + bool has_vertex_normals() const { return mesh_.has_vertex_normals(); } + bool has_vertex_colors() const { return mesh_.has_vertex_colors(); } + bool has_vertex_texcoords() const { return mesh_.has_vertex_texcoords2D(); } + bool has_edge_colors() const { return mesh_.has_edge_colors(); } + bool has_face_normals() const { return mesh_.has_face_normals(); } + bool has_face_colors() const { return mesh_.has_face_colors(); } + +private: + + const Mesh& mesh_; +}; + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/importer/BaseImporter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/importer/BaseImporter.hh new file mode 100644 index 0000000..afcfd6c --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/importer/BaseImporter.hh @@ -0,0 +1,205 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements the baseclass for IOManager importer modules +// +//============================================================================= + + +#ifndef __BASEIMPORTER_HH__ +#define __BASEIMPORTER_HH__ + + +//=== INCLUDES ================================================================ + + +// STL +#include + +// OpenMesh +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** Base class for importer modules. Importer modules provide an + * interface between the loader modules and the target data + * structure. This is basically a wrapper providing virtual versions + * for the required mesh functions. + */ +class OPENMESHDLLEXPORT BaseImporter +{ +public: + + // base class needs virtual destructor + virtual ~BaseImporter() {} + + + // add a vertex with coordinate \c _point + virtual VertexHandle add_vertex(const Vec3f& _point) = 0; + + // add a vertex without coordinate. Use set_point to set the position deferred + virtual VertexHandle add_vertex() = 0; + + // add a face with indices _indices refering to vertices + typedef std::vector VHandles; + virtual FaceHandle add_face(const VHandles& _indices) = 0; + + // add texture coordinates per face, _vh references the first texcoord + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) = 0; + + // add texture 3d coordinates per face, _vh references the first texcoord + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) = 0; + + // Set the texture index for a face + virtual void set_face_texindex( FaceHandle _fh, int _texId ) = 0; + + // Set coordinate of the given vertex. Use this function, if you created a vertex without coordinate + virtual void set_point(VertexHandle _vh, const Vec3f& _point) = 0; + + // set vertex normal + virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0; + + // set vertex color + virtual void set_color(VertexHandle _vh, const Vec3uc& _color) = 0; + + // set vertex color + virtual void set_color(VertexHandle _vh, const Vec4uc& _color) = 0; + + // set vertex color + virtual void set_color(VertexHandle _vh, const Vec3f& _color) = 0; + + // set vertex color + virtual void set_color(VertexHandle _vh, const Vec4f& _color) = 0; + + // set vertex texture coordinate + virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0; + + // set vertex texture coordinate + virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) = 0; + + // set 3d vertex texture coordinate + virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) = 0; + + // set 3d vertex texture coordinate + virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) = 0; + + // set edge color + virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0; + + // set edge color + virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) = 0; + + // set edge color + virtual void set_color(EdgeHandle _eh, const Vec3f& _color) = 0; + + // set edge color + virtual void set_color(EdgeHandle _eh, const Vec4f& _color) = 0; + + // set face normal + virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0; + + // set face color + virtual void set_color(FaceHandle _fh, const Vec3uc& _color) = 0; + + // set face color + virtual void set_color(FaceHandle _fh, const Vec4uc& _color) = 0; + + // set face color + virtual void set_color(FaceHandle _fh, const Vec3f& _color) = 0; + + // set face color + virtual void set_color(FaceHandle _fh, const Vec4f& _color) = 0; + + // Store a property in the mesh mapping from an int to a texture file + // Use set_face_texindex to set the index for each face + virtual void add_texture_information( int _id , std::string _name ) = 0; + + // get reference to base kernel + virtual BaseKernel* kernel() { return 0; } + + virtual bool is_triangle_mesh() const { return false; } + + // reserve mem for elements + virtual void reserve( unsigned int /* nV */, + unsigned int /* nE */, + unsigned int /* nF */) {} + + // query number of faces, vertices, normals, texcoords + virtual size_t n_vertices() const = 0; + virtual size_t n_faces() const = 0; + virtual size_t n_edges() const = 0; + + + // pre-processing + virtual void prepare() {} + + // post-processing + virtual void finish() {} +}; + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/importer/ImporterT.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/importer/ImporterT.hh new file mode 100644 index 0000000..fb6b669 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/importer/ImporterT.hh @@ -0,0 +1,408 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements an importer module for arbitrary OpenMesh meshes +// +//============================================================================= + + +#ifndef __IMPORTERT_HH__ +#define __IMPORTERT_HH__ + + +//=== INCLUDES ================================================================ + + +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + * This class template provides an importer module for OpenMesh meshes. + */ +template +class ImporterT : public BaseImporter +{ +public: + + typedef typename Mesh::Point Point; + typedef typename Mesh::Normal Normal; + typedef typename Mesh::Color Color; + typedef typename Mesh::TexCoord2D TexCoord2D; + typedef typename Mesh::TexCoord3D TexCoord3D; + typedef std::vector VHandles; + + + ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {} + + + virtual VertexHandle add_vertex(const Vec3f& _point) + { + return mesh_.add_vertex(vector_cast(_point)); + } + + virtual VertexHandle add_vertex() + { + return mesh_.new_vertex(); + } + + virtual FaceHandle add_face(const VHandles& _indices) + { + FaceHandle fh; + + if (_indices.size() > 2) + { + VHandles::const_iterator it, it2, end(_indices.end()); + + + // test for valid vertex indices + for (it=_indices.begin(); it!=end; ++it) + if (! mesh_.is_valid_handle(*it)) + { + omerr() << "ImporterT: Face contains invalid vertex index\n"; + return fh; + } + + + // don't allow double vertices + for (it=_indices.begin(); it!=end; ++it) + for (it2=it+1; it2!=end; ++it2) + if (*it == *it2) + { + omerr() << "ImporterT: Face has equal vertices\n"; + return fh; + } + + + // try to add face + fh = mesh_.add_face(_indices); + // separate non-manifold faces and mark them + if (!fh.is_valid()) + { + VHandles vhandles(_indices.size()); + + // double vertices + for (unsigned int j=0; j<_indices.size(); ++j) + { + // DO STORE p, reference may not work since vertex array + // may be relocated after adding a new vertex ! + Point p = mesh_.point(_indices[j]); + vhandles[j] = mesh_.add_vertex(p); + + // Mark vertices of failed face as non-manifold + if (mesh_.has_vertex_status()) { + mesh_.status(vhandles[j]).set_fixed_nonmanifold(true); + } + } + + // add face + fh = mesh_.add_face(vhandles); + + // Mark failed face as non-manifold + if (mesh_.has_face_status()) + mesh_.status(fh).set_fixed_nonmanifold(true); + + // Mark edges of failed face as non-two-manifold + if (mesh_.has_edge_status()) { + typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh); + for(; fe_it.is_valid(); ++fe_it) { + mesh_.status(*fe_it).set_fixed_nonmanifold(true); + } + } + } + + //write the half edge normals + if (mesh_.has_halfedge_normals()) + { + //iterate over all incoming haldedges of the added face + for (typename Mesh::FaceHalfedgeIter fh_iter = mesh_.fh_begin(fh); + fh_iter != mesh_.fh_end(fh); ++fh_iter) + { + //and write the normals to it + typename Mesh::HalfedgeHandle heh = *fh_iter; + typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(heh); + typename std::map::iterator it_heNs = halfedgeNormals_.find(vh); + if (it_heNs != halfedgeNormals_.end()) + mesh_.set_normal(heh,it_heNs->second); + } + halfedgeNormals_.clear(); + } + } + return fh; + } + + // vertex attributes + + virtual void set_point(VertexHandle _vh, const Vec3f& _point) + { + mesh_.set_point(_vh,vector_cast(_point)); + } + + virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) + { + if (mesh_.has_vertex_normals()) + mesh_.set_normal(_vh, vector_cast(_normal)); + + //saves normals for half edges. + //they will be written, when the face is added + if (mesh_.has_halfedge_normals()) + halfedgeNormals_[_vh] = vector_cast(_normal); + } + + virtual void set_color(VertexHandle _vh, const Vec4uc& _color) + { + if (mesh_.has_vertex_colors()) + mesh_.set_color(_vh, color_cast(_color)); + } + + virtual void set_color(VertexHandle _vh, const Vec3uc& _color) + { + if (mesh_.has_vertex_colors()) + mesh_.set_color(_vh, color_cast(_color)); + } + + virtual void set_color(VertexHandle _vh, const Vec4f& _color) + { + if (mesh_.has_vertex_colors()) + mesh_.set_color(_vh, color_cast(_color)); + } + + virtual void set_color(VertexHandle _vh, const Vec3f& _color) + { + if (mesh_.has_vertex_colors()) + mesh_.set_color(_vh, color_cast(_color)); + } + + virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) + { + if (mesh_.has_vertex_texcoords2D()) + mesh_.set_texcoord2D(_vh, vector_cast(_texcoord)); + } + + virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) + { + if (mesh_.has_halfedge_texcoords2D()) + mesh_.set_texcoord2D(_heh, vector_cast(_texcoord)); + } + + virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) + { + if (mesh_.has_vertex_texcoords3D()) + mesh_.set_texcoord3D(_vh, vector_cast(_texcoord)); + } + + virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) + { + if (mesh_.has_halfedge_texcoords3D()) + mesh_.set_texcoord3D(_heh, vector_cast(_texcoord)); + } + + + // edge attributes + + virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) + { + if (mesh_.has_edge_colors()) + mesh_.set_color(_eh, color_cast(_color)); + } + + virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) + { + if (mesh_.has_edge_colors()) + mesh_.set_color(_eh, color_cast(_color)); + } + + virtual void set_color(EdgeHandle _eh, const Vec4f& _color) + { + if (mesh_.has_edge_colors()) + mesh_.set_color(_eh, color_cast(_color)); + } + + virtual void set_color(EdgeHandle _eh, const Vec3f& _color) + { + if (mesh_.has_edge_colors()) + mesh_.set_color(_eh, color_cast(_color)); + } + + // face attributes + + virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) + { + if (mesh_.has_face_normals()) + mesh_.set_normal(_fh, vector_cast(_normal)); + } + + virtual void set_color(FaceHandle _fh, const Vec3uc& _color) + { + if (mesh_.has_face_colors()) + mesh_.set_color(_fh, color_cast(_color)); + } + + virtual void set_color(FaceHandle _fh, const Vec4uc& _color) + { + if (mesh_.has_face_colors()) + mesh_.set_color(_fh, color_cast(_color)); + } + + virtual void set_color(FaceHandle _fh, const Vec3f& _color) + { + if (mesh_.has_face_colors()) + mesh_.set_color(_fh, color_cast(_color)); + } + + virtual void set_color(FaceHandle _fh, const Vec4f& _color) + { + if (mesh_.has_face_colors()) + mesh_.set_color(_fh, color_cast(_color)); + } + + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) + { + // get first halfedge handle + HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh); + HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh); + + // find start heh + while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh ) + cur_heh = mesh_.next_halfedge_handle( cur_heh); + + for(unsigned int i=0; i<_face_texcoords.size(); ++i) + { + set_texcoord( cur_heh, _face_texcoords[i]); + cur_heh = mesh_.next_halfedge_handle( cur_heh); + } + } + + virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector& _face_texcoords) + { + // get first halfedge handle + HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh); + HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh); + + // find start heh + while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh ) + cur_heh = mesh_.next_halfedge_handle( cur_heh); + + for(unsigned int i=0; i<_face_texcoords.size(); ++i) + { + set_texcoord( cur_heh, _face_texcoords[i]); + cur_heh = mesh_.next_halfedge_handle( cur_heh); + } + } + + virtual void set_face_texindex( FaceHandle _fh, int _texId ) { + if ( mesh_.has_face_texture_index() ) { + mesh_.set_texture_index(_fh , _texId); + } + } + + virtual void add_texture_information( int _id , std::string _name ) { + OpenMesh::MPropHandleT< std::map< int, std::string > > property; + + if ( !mesh_.get_property_handle(property,"TextureMapping") ) { + mesh_.add_property(property,"TextureMapping"); + } + + if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() ) + mesh_.property(property)[_id] = _name; + } + + // low-level access to mesh + + virtual BaseKernel* kernel() { return &mesh_; } + + bool is_triangle_mesh() const + { return Mesh::is_triangles(); } + + void reserve(unsigned int nV, unsigned int nE, unsigned int nF) + { + mesh_.reserve(nV, nE, nF); + } + + // query number of faces, vertices, normals, texcoords + size_t n_vertices() const { return mesh_.n_vertices(); } + size_t n_faces() const { return mesh_.n_faces(); } + size_t n_edges() const { return mesh_.n_edges(); } + + + void prepare() { } + + + void finish() { } + + +private: + + Mesh& mesh_; + // stores normals for halfedges of the next face + std::map halfedgeNormals_; +}; + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/reader/BaseReader.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/BaseReader.hh new file mode 100644 index 0000000..463b9c7 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/BaseReader.hh @@ -0,0 +1,213 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements the baseclass for IOManager file access modules +// +//============================================================================= + + +#ifndef __BASEREADER_HH__ +#define __BASEREADER_HH__ + + +//=== INCLUDES ================================================================ + + +// STD C++ +#include +#include +#include +#include +#include + +// OpenMesh +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + Base class for reader modules. + Reader modules access persistent data and pass them to the desired + data structure by the means of a BaseImporter derivative. + All reader modules must be derived from this class. +*/ +class OPENMESHDLLEXPORT BaseReader +{ +public: + + /// Destructor + virtual ~BaseReader() {}; + + /// Returns a brief description of the file type that can be parsed. + virtual std::string get_description() const = 0; + + /** Returns a string with the accepted file extensions separated by a + whitespace and in small caps. + */ + virtual std::string get_extensions() const = 0; + + /// Return magic bits used to determine file format + virtual std::string get_magic() const { return std::string(""); } + + + /** Reads a mesh given by a filename. Usually this method opens a stream + and passes it to stream read method. Acceptance checks by filename + extension can be placed here. + + Options can be passed via _opt. After execution _opt contains the Options + that were available + */ + virtual bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt) = 0; + + /** Reads a mesh given by a std::stream. This method usually uses the same stream reading method + that read uses. Options can be passed via _opt. After execution _opt contains the Options + that were available. + + Please make sure that if _is is std::ifstream, the correct std::ios_base::openmode flags are set. + */ + virtual bool read(std::istream& _is, + BaseImporter& _bi, + Options& _opt) = 0; + + + /** \brief Returns true if writer can parse _filename (checks extension). + * _filename can also provide an extension without a name for a file e.g. _filename == "om" checks, if the reader can read the "om" extension + * @param _filename complete name of a file or just the extension + * @result true, if reader can read data with the given extension + */ + virtual bool can_u_read(const std::string& _filename) const; + + +protected: + + // case insensitive search for _ext in _fname. + bool check_extension(const std::string& _fname, + const std::string& _ext) const; +}; + + +/** \brief Trim left whitespace + * + * Removes whitespace at the beginning of the string + * + * @param _string input string + * @return trimmed string + */ +static inline std::string &left_trim(std::string &_string) { + + // Find out if the compiler supports CXX11 + #if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L ) + // as with CXX11 we can use lambda expressions + _string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), [](int i)->int { return ! std::isspace(i); })); + #else + // we do what we did before + _string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), std::not1(std::ptr_fun(std::isspace)))); + #endif + + return _string; +} + +/** \brief Trim right whitespace + * + * Removes whitespace at the end of the string + * + * @param _string input string + * @return trimmed string + */ +static inline std::string &right_trim(std::string &_string) { + + // Find out if the compiler supports CXX11 + #if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L ) + // as with CXX11 we can use lambda expressions + _string.erase(std::find_if(_string.rbegin(), _string.rend(), [](int i)->int { return ! std::isspace(i); } ).base(), _string.end()); + #else + // we do what we did before + _string.erase(std::find_if(_string.rbegin(), _string.rend(), std::not1(std::ptr_fun(std::isspace))).base(), _string.end()); + #endif + + + + return _string; +} + +/** \brief Trim whitespace + * + * Removes whitespace at the beginning and end of the string + * + * @param _string input string + * @return trimmed string + */ +static inline std::string &trim(std::string &_string) { + return left_trim(right_trim(_string)); +} + + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OBJReader.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OBJReader.hh new file mode 100644 index 0000000..70c3a2f --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OBJReader.hh @@ -0,0 +1,201 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements an reader module for OBJ files +// +//============================================================================= + + +#ifndef __OBJREADER_HH__ +#define __OBJREADER_HH__ + + +//=== INCLUDES ================================================================ + + +#include +#include +#include + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//== IMPLEMENTATION =========================================================== + + +/** + Implementation of the OBJ format reader. +*/ +class OPENMESHDLLEXPORT _OBJReader_ : public BaseReader +{ +public: + + _OBJReader_(); + + virtual ~_OBJReader_() { } + + std::string get_description() const { return "Alias/Wavefront"; } + std::string get_extensions() const { return "obj"; } + + bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt); + + bool read(std::istream& _in, + BaseImporter& _bi, + Options& _opt); + +private: + +#ifndef DOXY_IGNORE_THIS + class Material + { + public: + + Material() { cleanup(); } + + void cleanup() + { + Kd_is_set_ = false; + Ka_is_set_ = false; + Ks_is_set_ = false; + Tr_is_set_ = false; + map_Kd_is_set_ = false; + } + + bool is_valid(void) const + { return Kd_is_set_ || Ka_is_set_ || Ks_is_set_ || Tr_is_set_ || map_Kd_is_set_; } + + bool has_Kd(void) { return Kd_is_set_; } + bool has_Ka(void) { return Ka_is_set_; } + bool has_Ks(void) { return Ks_is_set_; } + bool has_Tr(void) { return Tr_is_set_; } + bool has_map_Kd(void) { return map_Kd_is_set_; } + + void set_Kd( float r, float g, float b ) + { Kd_=Vec3f(r,g,b); Kd_is_set_=true; } + + void set_Ka( float r, float g, float b ) + { Ka_=Vec3f(r,g,b); Ka_is_set_=true; } + + void set_Ks( float r, float g, float b ) + { Ks_=Vec3f(r,g,b); Ks_is_set_=true; } + + void set_Tr( float t ) + { Tr_=t; Tr_is_set_=true; } + + void set_map_Kd( std::string _name, int _index_Kd ) + { map_Kd_ = _name, index_Kd_ = _index_Kd; map_Kd_is_set_ = true; }; + + const Vec3f& Kd( void ) const { return Kd_; } + const Vec3f& Ka( void ) const { return Ka_; } + const Vec3f& Ks( void ) const { return Ks_; } + float Tr( void ) const { return Tr_; } + const std::string& map_Kd( void ) { return map_Kd_ ; } + const int& map_Kd_index( void ) { return index_Kd_ ; } + + private: + + Vec3f Kd_; bool Kd_is_set_; // diffuse + Vec3f Ka_; bool Ka_is_set_; // ambient + Vec3f Ks_; bool Ks_is_set_; // specular + float Tr_; bool Tr_is_set_; // transperency + + std::string map_Kd_; int index_Kd_; bool map_Kd_is_set_; // Texture + + }; +#endif + + typedef std::map MaterialList; + + MaterialList materials_; + + bool read_material( std::fstream& _in ); + + +private: + + bool read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt, + std::vector & normals, + std::vector & colors, + std::vector & texcoords3d, + std::vector & texcoords, + std::vector & vertexHandles, + Options & fileOptions); + + std::string path_; + +}; + + +//== TYPE DEFINITION ========================================================== + + +extern _OBJReader_ __OBJReaderInstance; +OPENMESHDLLEXPORT _OBJReader_& OBJReader(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OFFReader.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OFFReader.hh new file mode 100644 index 0000000..755093a --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OFFReader.hh @@ -0,0 +1,171 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a reader module for OFF files +// +//============================================================================= + + +#ifndef __OFFREADER_HH__ +#define __OFFREADER_HH__ + + +//=== INCLUDES ================================================================ + + +#include +#include +#include + +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//== FORWARDS ================================================================= + + +class BaseImporter; + + +//== IMPLEMENTATION =========================================================== + + +/** + Implementation of the OFF format reader. This class is singleton'ed by + SingletonT to OFFReader. + + By passing Options to the read function you can manipulate the reading behavoir. + The following options can be set: + + VertexNormal + VertexColor + VertexTexCoord + FaceColor + ColorAlpha [only when reading binary] + + These options define if the corresponding data should be read (if available) + or if it should be omitted. + + After execution of the read function. The options object contains information about + what was actually read. + + e.g. if VertexNormal was true when the read function was called, but the file + did not contain vertex normals then it is false afterwards. + + When reading a binary off with Color Flag in the header it is assumed that all vertices + and faces have colors in the format "int int int". + If ColorAlpha is set the format "int int int int" is assumed. + +*/ + +class OPENMESHDLLEXPORT _OFFReader_ : public BaseReader +{ +public: + + _OFFReader_(); + + /// Destructor + virtual ~_OFFReader_() {}; + + std::string get_description() const { return "Object File Format"; } + std::string get_extensions() const { return "off"; } + std::string get_magic() const { return "OFF"; } + + bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt); + + bool can_u_read(const std::string& _filename) const; + + bool read(std::istream& _in, BaseImporter& _bi, Options& _opt ); + +private: + + bool can_u_read(std::istream& _is) const; + + bool read_ascii(std::istream& _in, BaseImporter& _bi, Options& _opt) const; + bool read_binary(std::istream& _in, BaseImporter& _bi, Options& _opt, bool swap) const; + + void readValue(std::istream& _in, float& _value) const; + void readValue(std::istream& _in, int& _value) const; + void readValue(std::istream& _in, unsigned int& _value) const; + + int getColorType(std::string & _line, bool _texCoordsAvailable) const; + + //available options for reading + mutable Options options_; + //options that the user wants to read + mutable Options userOptions_; +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the OFF reader +extern _OFFReader_ __OFFReaderInstance; +OPENMESHDLLEXPORT _OFFReader_& OFFReader(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OMReader.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OMReader.hh new file mode 100644 index 0000000..4b1f67d --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/OMReader.hh @@ -0,0 +1,178 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a reader module for OFF files +// +//============================================================================= + + +#ifndef __OMREADER_HH__ +#define __OMREADER_HH__ + + +//=== INCLUDES ================================================================ + +// OpenMesh +#include +#include +#include +#include +#include +#include + +// STD C++ +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//== IMPLEMENTATION =========================================================== + + +/** + Implementation of the OM format reader. This class is singleton'ed by + SingletonT to OMReader. +*/ +class OPENMESHDLLEXPORT _OMReader_ : public BaseReader +{ +public: + + _OMReader_(); + virtual ~_OMReader_() { } + + std::string get_description() const { return "OpenMesh File Format"; } + std::string get_extensions() const { return "om"; } + std::string get_magic() const { return "OM"; } + + bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt ); + +//! Stream Reader for std::istream input in binary format + bool read(std::istream& _is, + BaseImporter& _bi, + Options& _opt ); + + virtual bool can_u_read(const std::string& _filename) const; + virtual bool can_u_read(std::istream& _is) const; + + +private: + + bool supports( const OMFormat::uint8 version ) const; + + bool read_ascii(std::istream& _is, BaseImporter& _bi, Options& _opt) const; + bool read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt) const; + + typedef OMFormat::Header Header; + typedef OMFormat::Chunk::Header ChunkHeader; + typedef OMFormat::Chunk::PropertyName PropertyName; + + // initialized/updated by read_binary*/read_ascii* + mutable size_t bytes_; + mutable Options fileOptions_; + mutable Header header_; + mutable ChunkHeader chunk_header_; + mutable PropertyName property_name_; + + bool read_binary_vertex_chunk( std::istream &_is, + BaseImporter &_bi, + Options &_opt, + bool _swap) const; + + bool read_binary_face_chunk( std::istream &_is, + BaseImporter &_bi, + Options &_opt, + bool _swap) const; + + bool read_binary_edge_chunk( std::istream &_is, + BaseImporter &_bi, + Options &_opt, + bool _swap) const; + + bool read_binary_halfedge_chunk( std::istream &_is, + BaseImporter &_bi, + Options &_opt, + bool _swap) const; + + bool read_binary_mesh_chunk( std::istream &_is, + BaseImporter &_bi, + Options &_opt, + bool _swap) const; + + size_t restore_binary_custom_data( std::istream& _is, + BaseProperty* _bp, + size_t _n_elem, + bool _swap) const; + +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the OM reader. +extern _OMReader_ __OMReaderInstance; +OPENMESHDLLEXPORT _OMReader_& OMReader(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/reader/PLYReader.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/PLYReader.hh new file mode 100644 index 0000000..c887a5b --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/PLYReader.hh @@ -0,0 +1,244 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a reader module for OFF files +// +//============================================================================= + + +#ifndef __PLYREADER_HH__ +#define __PLYREADER_HH__ + + +//=== INCLUDES ================================================================ + + + +#include +#include +#include +#include + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//== FORWARDS ================================================================= + + +class BaseImporter; + + +//== IMPLEMENTATION =========================================================== + + +/** + Implementation of the PLY format reader. This class is singleton'ed by + SingletonT to OFFReader. It can read custom properties, accessible via the name + of the custom properties. List properties has the type std::vector. + +*/ + +class OPENMESHDLLEXPORT _PLYReader_ : public BaseReader +{ +public: + + _PLYReader_(); + + std::string get_description() const { return "PLY polygon file format"; } + std::string get_extensions() const { return "ply"; } + std::string get_magic() const { return "PLY"; } + + bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt); + + bool read(std::istream& _is, + BaseImporter& _bi, + Options& _opt); + + bool can_u_read(const std::string& _filename) const; + + enum ValueType { + Unsupported, + ValueTypeINT8, ValueTypeCHAR, + ValueTypeUINT8, ValueTypeUCHAR, + ValueTypeINT16, ValueTypeSHORT, + ValueTypeUINT16, ValueTypeUSHORT, + ValueTypeINT32, ValueTypeINT, + ValueTypeUINT32, ValueTypeUINT, + ValueTypeFLOAT32, ValueTypeFLOAT, + ValueTypeFLOAT64, ValueTypeDOUBLE + }; + +private: + + bool can_u_read(std::istream& _is) const; + + bool read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const; + bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const; + + float readToFloatValue(ValueType _type , std::fstream& _in) const; + + void readValue(ValueType _type , std::istream& _in, float& _value) const; + void readValue(ValueType _type , std::istream& _in, double& _value) const; + void readValue(ValueType _type , std::istream& _in, unsigned int& _value) const; + void readValue(ValueType _type , std::istream& _in, unsigned short& _value) const; + void readValue(ValueType _type , std::istream& _in, unsigned char& _value) const; + void readValue(ValueType _type , std::istream& _in, int& _value) const; + void readValue(ValueType _type , std::istream& _in, short& _value) const; + void readValue(ValueType _type , std::istream& _in, signed char& _value) const; + + void readInteger(ValueType _type, std::istream& _in, int& _value) const; + void readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const; + + /// Read unsupported properties in PLY file + void consume_input(std::istream& _in, int _count) const { + _in.read(reinterpret_cast(&buff[0]), _count); + } + + mutable unsigned char buff[8]; + + /// Available per file options for reading + mutable Options options_; + + /// Options that the user wants to read + mutable Options userOptions_; + + mutable unsigned int vertexCount_; + mutable unsigned int faceCount_; + + mutable uint vertexDimension_; + + enum Property { + XCOORD,YCOORD,ZCOORD, + TEXX,TEXY, + COLORRED,COLORGREEN,COLORBLUE,COLORALPHA, + XNORM,YNORM,ZNORM, CUSTOM_PROP, VERTEX_INDICES, + UNSUPPORTED + }; + + /// Stores sizes of property types + mutable std::map scalar_size_; + + // Number of vertex properties + struct PropertyInfo + { + Property property; + ValueType value; + std::string name;//for custom properties + ValueType listIndexType;//if type is unsupported, the poerty is not a list. otherwise, it the index type + PropertyInfo():property(UNSUPPORTED),value(Unsupported),name(""),listIndexType(Unsupported){} + PropertyInfo(Property _p, ValueType _v):property(_p),value(_v),name(""),listIndexType(Unsupported){} + PropertyInfo(Property _p, ValueType _v, const std::string& _n):property(_p),value(_v),name(_n),listIndexType(Unsupported){} + }; + + enum Element { + VERTEX, + FACE, + UNKNOWN + }; + + // Information on the elements + struct ElementInfo + { + Element element_; + std::string name_; + unsigned int count_; + std::vector< PropertyInfo > properties_; + }; + + mutable std::vector< ElementInfo > elements_; + + template + inline void read(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::TrueType /*_binary*/) const + { + readValue(_type, _in, _value); + } + + template + inline void read(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::FalseType /*_binary*/) const + { + _in >> _value; + } + + //read and assign custom properties with the given type. Also creates property, if not exist + template + void readCreateCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const ValueType _valueType, const ValueType _listType) const; + + template + void readCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const _PLYReader_::ValueType _valueType, const _PLYReader_::ValueType _listIndexType) const; +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the PLY reader +extern _PLYReader_ __PLYReaderInstance; +OPENMESHDLLEXPORT _PLYReader_& PLYReader(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/reader/STLReader.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/STLReader.hh new file mode 100644 index 0000000..b642623 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/reader/STLReader.hh @@ -0,0 +1,151 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements an reader module for STL files +// +//============================================================================= + + +#ifndef __STLREADER_HH__ +#define __STLREADER_HH__ + + +//=== INCLUDES ================================================================ + + +#include +#include + +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + +//== FORWARDS ================================================================= + +class BaseImporter; + +//== IMPLEMENTATION =========================================================== + + +/** + Implementation of the STL format reader. This class is singleton'ed by + SingletonT to STLReader. +*/ +class OPENMESHDLLEXPORT _STLReader_ : public BaseReader +{ +public: + + // constructor + _STLReader_(); + + /// Destructor + virtual ~_STLReader_() {}; + + + std::string get_description() const + { return "Stereolithography Interface Format"; } + std::string get_extensions() const { return "stl stla stlb"; } + + bool read(const std::string& _filename, + BaseImporter& _bi, + Options& _opt); + + bool read(std::istream& _in, + BaseImporter& _bi, + Options& _opt); + + /** Set the threshold to be used for considering two point to be equal. + Can be used to merge small gaps */ + void set_epsilon(float _eps) { eps_=_eps; } + + /// Returns the threshold to be used for considering two point to be equal. + float epsilon() const { return eps_; } + + + +private: + + enum STL_Type { STLA, STLB, NONE }; + STL_Type check_stl_type(const std::string& _filename) const; + + bool read_stla(const std::string& _filename, BaseImporter& _bi, Options& _opt) const; + bool read_stla(std::istream& _in, BaseImporter& _bi, Options& _opt) const; + bool read_stlb(const std::string& _filename, BaseImporter& _bi, Options& _opt) const; + bool read_stlb(std::istream& _in, BaseImporter& _bi, Options& _opt) const; + + +private: + + float eps_; +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the STL reader +extern _STLReader_ __STLReaderInstance; +OPENMESHDLLEXPORT _STLReader_& STLReader(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/BaseWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/BaseWriter.hh new file mode 100644 index 0000000..3e1688f --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/BaseWriter.hh @@ -0,0 +1,155 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements the baseclass for IOManager writer modules +// +//============================================================================= + + +#ifndef __BASEWRITER_HH__ +#define __BASEWRITER_HH__ + + +//=== INCLUDES ================================================================ + + +// STD C++ +#include +#include + +// OpenMesh +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + Base class for all writer modules. The module should register itself at + the IOManager by calling the register_module function. +*/ +class OPENMESHDLLEXPORT BaseWriter +{ +public: + + typedef unsigned int Option; + + /// Destructor + virtual ~BaseWriter() {}; + + /// Return short description of the supported file format. + virtual std::string get_description() const = 0; + + /// Return file format's extension. + virtual std::string get_extensions() const = 0; + + /** \brief Returns true if writer can write _filename (checks extension). + * _filename can also provide an extension without a name for a file e.g. _filename == "om" checks, if the writer can write the "om" extension + * @param _filename complete name of a file or just the extension + * @result true, if writer can write data with the given extension + */ + virtual bool can_u_write(const std::string& _filename) const; + + /** Write to a file + * @param _filename write to file with the given filename + * @param _be BaseExporter, which specifies the data source + * @param _opt writing options + * @param _precision can be used to specify the precision of the floating point notation. + */ + virtual bool write(const std::string& _filename, + BaseExporter& _be, + Options _opt, + std::streamsize _precision = 6) const = 0; + + /** Write to a std::ostream + * @param _os write to std::ostream + * @param _be BaseExporter, which specifies the data source + * @param _opt writing options + * @param _precision can be used to specify the precision of the floating point notation. + */ + virtual bool write(std::ostream& _os, + BaseExporter& _be, + Options _opt, + std::streamsize _precision = 6) const = 0; + + /// Returns expected size of file if binary format is supported else 0. + virtual size_t binary_size(BaseExporter&, Options) const { return 0; } + + + +protected: + + bool check(BaseExporter& _be, Options _opt) const + { + return (_opt.check(Options::VertexNormal ) <= _be.has_vertex_normals()) + && (_opt.check(Options::VertexTexCoord)<= _be.has_vertex_texcoords()) + && (_opt.check(Options::VertexColor) <= _be.has_vertex_colors()) + && (_opt.check(Options::FaceNormal) <= _be.has_face_normals()) + && (_opt.check(Options::FaceColor) <= _be.has_face_colors()); + } +}; + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OBJWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OBJWriter.hh new file mode 100644 index 0000000..6adc772 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OBJWriter.hh @@ -0,0 +1,136 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements an IOManager writer module for OBJ files +// +//============================================================================= + + +#ifndef __OBJWRITER_HH__ +#define __OBJWRITER_HH__ + + +//=== INCLUDES ================================================================ + + +#include +#include + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + This class defines the OBJ writer. This class is further singleton'ed + by SingletonT to OBJWriter. +*/ +class OPENMESHDLLEXPORT _OBJWriter_ : public BaseWriter +{ +public: + + _OBJWriter_(); + + /// Destructor + virtual ~_OBJWriter_() {}; + + std::string get_description() const { return "Alias/Wavefront"; } + std::string get_extensions() const { return "obj"; } + + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + size_t binary_size(BaseExporter&, Options) const { return 0; } + +private: + + mutable std::string path_; + mutable std::string objName_; + + mutable std::vector< OpenMesh::Vec3f > material_; + mutable std::vector< OpenMesh::Vec4f > materialA_; + + size_t getMaterial(OpenMesh::Vec3f _color) const; + + size_t getMaterial(OpenMesh::Vec4f _color) const; + + bool writeMaterial(std::ostream& _out, BaseExporter&, Options) const; + + +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the OBJ writer +extern _OBJWriter_ __OBJWriterinstance; +OPENMESHDLLEXPORT _OBJWriter_& OBJWriter(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OFFWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OFFWriter.hh new file mode 100644 index 0000000..b6f4e14 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OFFWriter.hh @@ -0,0 +1,138 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a writer module for OFF files +// +//============================================================================= + + +#ifndef __OFFWRITER_HH__ +#define __OFFWRITER_HH__ + + +//=== INCLUDES ================================================================ + +#include +#include + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + Implementation of the OFF format writer. This class is singleton'ed by + SingletonT to OFFWriter. + + By passing Options to the write function you can manipulate the writing behavoir. + The following options can be set: + + Binary + VertexNormal + VertexColor + VertexTexCoord + FaceColor + ColorAlpha + +*/ +class OPENMESHDLLEXPORT _OFFWriter_ : public BaseWriter +{ +public: + + _OFFWriter_(); + + virtual ~_OFFWriter_() {}; + + std::string get_description() const { return "no description"; } + std::string get_extensions() const { return "off"; } + + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + size_t binary_size(BaseExporter& _be, Options _opt) const; + + +protected: + void writeValue(std::ostream& _out, int value) const; + void writeValue(std::ostream& _out, unsigned int value) const; + void writeValue(std::ostream& _out, float value) const; + + bool write_ascii(std::ostream& _in, BaseExporter&, Options) const; + bool write_binary(std::ostream& _in, BaseExporter&, Options) const; +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the OFF writer. +extern _OFFWriter_ __OFFWriterInstance; +OPENMESHDLLEXPORT _OFFWriter_& OFFWriter(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OMWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OMWriter.hh new file mode 100644 index 0000000..efc48a8 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/OMWriter.hh @@ -0,0 +1,147 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a writer module for OM files +// +//============================================================================= + + +#ifndef __OMWRITER_HH__ +#define __OMWRITER_HH__ + + +//=== INCLUDES ================================================================ + + +// STD C++ +#include +#include + +// OpenMesh +#include +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + +//=== FORWARDS ================================================================ + + +class BaseExporter; + + +//=== IMPLEMENTATION ========================================================== + + +/** + * Implementation of the OM format writer. This class is singleton'ed by + * SingletonT to OMWriter. + */ +class OPENMESHDLLEXPORT _OMWriter_ : public BaseWriter +{ +public: + + /// Constructor + _OMWriter_(); + + /// Destructor + virtual ~_OMWriter_() {}; + + std::string get_description() const + { return "OpenMesh Format"; } + + std::string get_extensions() const + { return "om"; } + + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + + + size_t binary_size(BaseExporter& _be, Options _opt) const; + + +protected: + + static const OMFormat::uchar magic_[3]; + static const OMFormat::uint8 version_; + + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + bool write_binary(std::ostream&, BaseExporter&, Options) const; + + + size_t store_binary_custom_chunk( std::ostream&, const BaseProperty&, + OMFormat::Chunk::Entity, bool) const; +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the OM writer. +extern _OMWriter_ __OMWriterInstance; +OPENMESHDLLEXPORT _OMWriter_& OMWriter(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/PLYWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/PLYWriter.hh new file mode 100644 index 0000000..65addb6 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/PLYWriter.hh @@ -0,0 +1,177 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a writer module for PLY files +// +//============================================================================= + + +#ifndef __PLYWRITER_HH__ +#define __PLYWRITER_HH__ + + +//=== INCLUDES ================================================================ + +#include +#include +#include + +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + Implementation of the PLY format writer. This class is singleton'ed by + SingletonT to PLYWriter. + + currently supported options: + - VertexColors + - Binary + - Binary -> MSB +*/ +class OPENMESHDLLEXPORT _PLYWriter_ : public BaseWriter +{ +public: + + _PLYWriter_(); + + /// Destructor + virtual ~_PLYWriter_() {}; + + std::string get_description() const { return "PLY polygon file format"; } + std::string get_extensions() const { return "ply"; } + + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + size_t binary_size(BaseExporter& _be, Options _opt) const; + + enum ValueType { + Unsupported = 0, + ValueTypeFLOAT32, ValueTypeFLOAT, + ValueTypeINT32, ValueTypeINT , ValueTypeUINT, + ValueTypeUCHAR, ValueTypeCHAR, ValueTypeUINT8, + ValueTypeUSHORT, ValueTypeSHORT, + ValueTypeDOUBLE + }; + +private: + mutable Options options_; + + struct CustomProperty + { + ValueType type; + const BaseProperty* property; + CustomProperty(const BaseProperty* const _p):type(Unsupported),property(_p){} + }; + + const char* nameOfType_[12]; + + /// write custom persistant properties into the header for the current element, returns all properties, which were written sorted + std::vector writeCustomTypeHeader(std::ostream& _out, BaseKernel::const_prop_iterator _begin, BaseKernel::const_prop_iterator _end) const; + template + void write_customProp(std::ostream& _our, const CustomProperty& _prop, size_t _index) const; + template + void writeProxy(ValueType _type, std::ostream& _out, T _value, OpenMesh::GenProg::TrueType /*_binary*/) const + { + writeValue(_type, _out, _value); + } + template + void writeProxy(ValueType _type, std::ostream& _out, T _value, OpenMesh::GenProg::FalseType /*_binary*/) const + { + _out << " " << _value; + } + +protected: + void writeValue(ValueType _type, std::ostream& _out, signed char value) const; + void writeValue(ValueType _type, std::ostream& _out, unsigned char value) const; + void writeValue(ValueType _type, std::ostream& _out, short value) const; + void writeValue(ValueType _type, std::ostream& _out, unsigned short value) const; + void writeValue(ValueType _type, std::ostream& _out, int value) const; + void writeValue(ValueType _type, std::ostream& _out, unsigned int value) const; + void writeValue(ValueType _type, std::ostream& _out, float value) const; + void writeValue(ValueType _type, std::ostream& _out, double value) const; + + bool write_ascii(std::ostream& _out, BaseExporter&, Options) const; + bool write_binary(std::ostream& _out, BaseExporter&, Options) const; + /// write header into the stream _out. Returns custom properties (vertex and face) which are written into the header + void write_header(std::ostream& _out, BaseExporter& _be, Options& _opt, std::vector& _ovProps, std::vector& _ofProps) const; +}; + + +//== TYPE DEFINITION ========================================================== + + +/// Declare the single entity of the PLY writer. +extern _PLYWriter_ __PLYWriterInstance; +OPENMESHDLLEXPORT _PLYWriter_& PLYWriter(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/STLWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/STLWriter.hh new file mode 100644 index 0000000..92a0113 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/STLWriter.hh @@ -0,0 +1,126 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a writer module for STL ascii files +// +//============================================================================= +// $Id: STLWriter.hh,v 1.2 2007-05-18 15:17:43 habbecke Exp $ + +#ifndef __STLWRITER_HH__ +#define __STLWRITER_HH__ + + +//=== INCLUDES ================================================================ + +// -------------------- STL +#include +#include +// -------------------- OpenMesh +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace IO { + + +//=== IMPLEMENTATION ========================================================== + + +/** + Implementation of the STL format writer. This class is singleton'ed by + SingletonT to STLWriter. +*/ +class OPENMESHDLLEXPORT _STLWriter_ : public BaseWriter +{ +public: + + _STLWriter_(); + + /// Destructor + virtual ~_STLWriter_() {}; + + std::string get_description() const { return "Stereolithography Format"; } + std::string get_extensions() const { return "stl stla stlb"; } + + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + size_t binary_size(BaseExporter&, Options) const; + +private: + bool write_stla(const std::string&, BaseExporter&, Options) const; + bool write_stla(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + bool write_stlb(const std::string&, BaseExporter&, Options) const; + bool write_stlb(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; +}; + + +//== TYPE DEFINITION ========================================================== + + +// Declare the single entity of STL writer. +extern _STLWriter_ __STLWriterInstance; +OPENMESHDLLEXPORT _STLWriter_& STLWriter(); + + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/writer/VTKWriter.hh b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/VTKWriter.hh new file mode 100644 index 0000000..40d9e11 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/writer/VTKWriter.hh @@ -0,0 +1,52 @@ +//============================================================================= +// +// Implements an IOManager writer module for VTK files +// +//============================================================================= + +#ifndef __VTKWRITER_HH__ +#define __VTKWRITER_HH__ + +//=== INCLUDES ================================================================ + +#include +#include + +#include +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + +//=== IMPLEMENTATION ========================================================== + +class OPENMESHDLLEXPORT _VTKWriter_ : public BaseWriter +{ +public: + _VTKWriter_(); + + std::string get_description() const { return "VTK"; } + std::string get_extensions() const { return "vtk"; } + + bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const; + bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const; + + size_t binary_size(BaseExporter&, Options) const { return 0; } +}; + +//== TYPE DEFINITION ========================================================== + +/// Declare the single entity of the OBJ writer +extern _VTKWriter_ __VTKWriterinstance; +OPENMESHDLLEXPORT _VTKWriter_& VTKWriter(); + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayItems.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayItems.hh new file mode 100644 index 0000000..c49944b --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayItems.hh @@ -0,0 +1,130 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_ARRAY_ITEMS_HH +#define OPENMESH_ARRAY_ITEMS_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/// Definition of mesh items for use in the ArrayKernel +struct ArrayItems +{ + + //------------------------------------------------------ internal vertex type + + /// The vertex item + class Vertex + { + friend class ArrayKernel; + HalfedgeHandle halfedge_handle_; + }; + + + //---------------------------------------------------- internal halfedge type + +#ifndef DOXY_IGNORE_THIS + class Halfedge_without_prev + { + friend class ArrayKernel; + FaceHandle face_handle_; + VertexHandle vertex_handle_; + HalfedgeHandle next_halfedge_handle_; + }; +#endif + +#ifndef DOXY_IGNORE_THIS + class Halfedge_with_prev : public Halfedge_without_prev + { + friend class ArrayKernel; + HalfedgeHandle prev_halfedge_handle_; + }; +#endif + + //TODO: should be selected with config.h define + typedef Halfedge_with_prev Halfedge; + typedef GenProg::Bool2Type HasPrevHalfedge; + + //-------------------------------------------------------- internal edge type +#ifndef DOXY_IGNORE_THIS + class Edge + { + friend class ArrayKernel; + Halfedge halfedges_[2]; + }; +#endif + + //-------------------------------------------------------- internal face type +#ifndef DOXY_IGNORE_THIS + class Face + { + friend class ArrayKernel; + HalfedgeHandle halfedge_handle_; + }; +}; +#endif + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_ITEMS_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernel.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernel.hh new file mode 100644 index 0000000..ccf2748 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernel.hh @@ -0,0 +1,915 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS ArrayKernel +// +//============================================================================= + + +#ifndef OPENMESH_ARRAY_KERNEL_HH +#define OPENMESH_ARRAY_KERNEL_HH + + +//== INCLUDES ================================================================= +#include + +#include +#include + +#include +#include +#include + +//== NAMESPACES =============================================================== +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= +/** \ingroup mesh_kernels_group + + Mesh kernel using arrays for mesh item storage. + + This mesh kernel uses the std::vector as container to store the + mesh items. Therefore all handle types are internally represented + by integers. To get the index from a handle use the handle's \c + idx() method. + + \note For a description of the minimal kernel interface see + OpenMesh::Mesh::BaseKernel. + \note You do not have to use this class directly, use the predefined + mesh-kernel combinations in \ref mesh_types_group. + \see OpenMesh::Concepts::KernelT, \ref mesh_type +*/ + +class OPENMESHDLLEXPORT ArrayKernel : public BaseKernel, public ArrayItems +{ +public: + + // handles + typedef OpenMesh::VertexHandle VertexHandle; + typedef OpenMesh::HalfedgeHandle HalfedgeHandle; + typedef OpenMesh::EdgeHandle EdgeHandle; + typedef OpenMesh::FaceHandle FaceHandle; + typedef Attributes::StatusInfo StatusInfo; + typedef VPropHandleT VertexStatusPropertyHandle; + typedef HPropHandleT HalfedgeStatusPropertyHandle; + typedef EPropHandleT EdgeStatusPropertyHandle; + typedef FPropHandleT FaceStatusPropertyHandle; + +public: + + // --- constructor/destructor --- + ArrayKernel(); + virtual ~ArrayKernel(); + + /** ArrayKernel uses the default copy constructor and assignment operator, which means + that the connectivity and all properties are copied, including reference + counters, allocated bit status masks, etc.. In contrast assign_connectivity + copies only the connectivity, i.e. vertices, edges, faces and their status fields. + NOTE: The geometry (the points property) is NOT copied. Poly/TriConnectivity + override(and hide) that function to provide connectivity consistence.*/ + void assign_connectivity(const ArrayKernel& _other); + + // --- handle -> item --- + VertexHandle handle(const Vertex& _v) const; + + HalfedgeHandle handle(const Halfedge& _he) const; + + EdgeHandle handle(const Edge& _e) const; + + FaceHandle handle(const Face& _f) const; + + + ///checks handle validity - useful for debugging + bool is_valid_handle(VertexHandle _vh) const; + + ///checks handle validity - useful for debugging + bool is_valid_handle(HalfedgeHandle _heh) const; + + ///checks handle validity - useful for debugging + bool is_valid_handle(EdgeHandle _eh) const; + + ///checks handle validity - useful for debugging + bool is_valid_handle(FaceHandle _fh) const; + + + // --- item -> handle --- + const Vertex& vertex(VertexHandle _vh) const + { + assert(is_valid_handle(_vh)); + return vertices_[_vh.idx()]; + } + + Vertex& vertex(VertexHandle _vh) + { + assert(is_valid_handle(_vh)); + return vertices_[_vh.idx()]; + } + + const Halfedge& halfedge(HalfedgeHandle _heh) const + { + assert(is_valid_handle(_heh)); + return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1]; + } + + Halfedge& halfedge(HalfedgeHandle _heh) + { + assert(is_valid_handle(_heh)); + return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1]; + } + + const Edge& edge(EdgeHandle _eh) const + { + assert(is_valid_handle(_eh)); + return edges_[_eh.idx()]; + } + + Edge& edge(EdgeHandle _eh) + { + assert(is_valid_handle(_eh)); + return edges_[_eh.idx()]; + } + + const Face& face(FaceHandle _fh) const + { + assert(is_valid_handle(_fh)); + return faces_[_fh.idx()]; + } + + Face& face(FaceHandle _fh) + { + assert(is_valid_handle(_fh)); + return faces_[_fh.idx()]; + } + + // --- get i'th items --- + + VertexHandle vertex_handle(unsigned int _i) const + { return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); } + + HalfedgeHandle halfedge_handle(unsigned int _i) const + { + return (_i < n_halfedges()) ? + halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle(); + } + + EdgeHandle edge_handle(unsigned int _i) const + { return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); } + + FaceHandle face_handle(unsigned int _i) const + { return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); } + +public: + + /** + * \brief Add a new vertex. + * + * If you are rebuilding a mesh that you previously erased using clean() or + * clean_keep_reservation() you probably want to use new_vertex_dirty() + * instead. + * + * \sa new_vertex_dirty() + */ + inline VertexHandle new_vertex() + { + vertices_.push_back(Vertex()); + vprops_resize(n_vertices());//TODO:should it be push_back()? + + return handle(vertices_.back()); + } + + /** + * Same as new_vertex() but uses PropertyContainer::resize_if_smaller() to + * resize the vertex property container. + * + * If you are rebuilding a mesh that you erased with clean() or + * clean_keep_reservation() using this method instead of new_vertex() saves + * reallocation and reinitialization of property memory. + * + * \sa new_vertex() + */ + inline VertexHandle new_vertex_dirty() + { + vertices_.push_back(Vertex()); + vprops_resize_if_smaller(n_vertices());//TODO:should it be push_back()? + + return handle(vertices_.back()); + } + + inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh) + { +// assert(_start_vh != _end_vh); + edges_.push_back(Edge()); + eprops_resize(n_edges());//TODO:should it be push_back()? + hprops_resize(n_halfedges());//TODO:should it be push_back()? + + EdgeHandle eh(handle(edges_.back())); + HalfedgeHandle heh0(halfedge_handle(eh, 0)); + HalfedgeHandle heh1(halfedge_handle(eh, 1)); + set_vertex_handle(heh0, _end_vh); + set_vertex_handle(heh1, _start_vh); + return heh0; + } + + inline FaceHandle new_face() + { + faces_.push_back(Face()); + fprops_resize(n_faces()); + return handle(faces_.back()); + } + + inline FaceHandle new_face(const Face& _f) + { + faces_.push_back(_f); + fprops_resize(n_faces()); + return handle(faces_.back()); + } + +public: + // --- resize/reserve --- + void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces ); + void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces ); + + // --- deletion --- + /** \brief garbage collection + * + * Usually if you delete primitives in OpenMesh, they are only flagged as deleted. + * Only when you call garbage collection, they will be actually removed. + * + * \note Garbage collection invalidates all handles. If you need to keep track of + * a set of handles, you can pass them to the second garbage collection + * function, which will update a vector of handles. + * See also \ref deletedElements. + * + * @param _v Remove deleted vertices? + * @param _e Remove deleted edges? + * @param _f Remove deleted faces? + * + */ + void garbage_collection(bool _v=true, bool _e=true, bool _f=true); + + /** \brief garbage collection with handle tracking + * + * Usually if you delete primitives in OpenMesh, they are only flagged as deleted. + * Only when you call garbage collection, they will be actually removed. + * + * \note Garbage collection invalidates all handles. If you need to keep track of + * a set of handles, you can pass them to this function. The handles that the + * given pointers point to are updated in place. + * See also \ref deletedElements. + * + * @param vh_to_update Pointers to vertex handles that should get updated + * @param hh_to_update Pointers to halfedge handles that should get updated + * @param fh_to_update Pointers to face handles that should get updated + * @param _v Remove deleted vertices? + * @param _e Remove deleted edges? + * @param _f Remove deleted faces? + */ + template + void garbage_collection(std_API_Container_VHandlePointer& vh_to_update, + std_API_Container_HHandlePointer& hh_to_update, + std_API_Container_FHandlePointer& fh_to_update, + bool _v=true, bool _e=true, bool _f=true); + + /// \brief Does the same as clean() and in addition erases all properties. + void clear(); + + /** \brief Remove all vertices, edges and faces and deallocates their memory. + * + * In contrast to clear() this method does neither erases the properties + * nor clears the property vectors. Depending on how you add any new entities + * to the mesh after calling this method, your properties will be initialized + * with old values. + * + * \sa clean_keep_reservation() + */ + void clean(); + + /** \brief Remove all vertices, edges and faces but keep memory allocated. + * + * This method behaves like clean() (also regarding the properties) but + * leaves the memory used for vertex, edge and face storage allocated. This + * leads to no reduction in memory consumption but allows for faster + * performance when rebuilding the mesh. + */ + void clean_keep_reservation(); + + // --- number of items --- + size_t n_vertices() const { return vertices_.size(); } + size_t n_halfedges() const { return 2*edges_.size(); } + size_t n_edges() const { return edges_.size(); } + size_t n_faces() const { return faces_.size(); } + + bool vertices_empty() const { return vertices_.empty(); } + bool halfedges_empty() const { return edges_.empty(); } + bool edges_empty() const { return edges_.empty(); } + bool faces_empty() const { return faces_.empty(); } + + // --- vertex connectivity --- + + HalfedgeHandle halfedge_handle(VertexHandle _vh) const + { return vertex(_vh).halfedge_handle_; } + + void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh) + { +// assert(is_valid_handle(_heh)); + vertex(_vh).halfedge_handle_ = _heh; + } + + bool is_isolated(VertexHandle _vh) const + { return !halfedge_handle(_vh).is_valid(); } + + void set_isolated(VertexHandle _vh) + { vertex(_vh).halfedge_handle_.invalidate(); } + + unsigned int delete_isolated_vertices(); + + // --- halfedge connectivity --- + VertexHandle to_vertex_handle(HalfedgeHandle _heh) const + { return halfedge(_heh).vertex_handle_; } + + VertexHandle from_vertex_handle(HalfedgeHandle _heh) const + { return to_vertex_handle(opposite_halfedge_handle(_heh)); } + + void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh) + { +// assert(is_valid_handle(_vh)); + halfedge(_heh).vertex_handle_ = _vh; + } + + FaceHandle face_handle(HalfedgeHandle _heh) const + { return halfedge(_heh).face_handle_; } + + void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh) + { +// assert(is_valid_handle(_fh)); + halfedge(_heh).face_handle_ = _fh; + } + + void set_boundary(HalfedgeHandle _heh) + { halfedge(_heh).face_handle_.invalidate(); } + + /// Is halfedge _heh a boundary halfedge (is its face handle invalid) ? + bool is_boundary(HalfedgeHandle _heh) const + { return !face_handle(_heh).is_valid(); } + + HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const + { return halfedge(_heh).next_halfedge_handle_; } + + void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh) + { + assert(is_valid_handle(_nheh)); +// assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh)); + halfedge(_heh).next_halfedge_handle_ = _nheh; + set_prev_halfedge_handle(_nheh, _heh); + } + + + void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh) + { + assert(is_valid_handle(_pheh)); + set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge()); + } + + void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh, + GenProg::TrueType) + { halfedge(_heh).prev_halfedge_handle_ = _pheh; } + + void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */, + GenProg::FalseType) + {} + + HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const + { return prev_halfedge_handle(_heh, HasPrevHalfedge() ); } + + HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const + { return halfedge(_heh).prev_halfedge_handle_; } + + HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const + { + if (is_boundary(_heh)) + {//iterating around the vertex should be faster than iterating the boundary + HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh)); + HalfedgeHandle next_heh(next_halfedge_handle(curr_heh)); + do + { + curr_heh = opposite_halfedge_handle(next_heh); + next_heh = next_halfedge_handle(curr_heh); + } + while (next_heh != _heh); + return curr_heh; + } + else + { + HalfedgeHandle heh(_heh); + HalfedgeHandle next_heh(next_halfedge_handle(heh)); + while (next_heh != _heh) { + heh = next_heh; + next_heh = next_halfedge_handle(next_heh); + } + return heh; + } + } + + + HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const + { return HalfedgeHandle(_heh.idx() ^ 1); } + + + HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const + { return opposite_halfedge_handle(prev_halfedge_handle(_heh)); } + + + HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const + { return next_halfedge_handle(opposite_halfedge_handle(_heh)); } + + // --- edge connectivity --- + static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i) + { + assert(_i<=1); + return HalfedgeHandle((_eh.idx() << 1) + _i); + } + + static EdgeHandle s_edge_handle(HalfedgeHandle _heh) + { return EdgeHandle(_heh.idx() >> 1); } + + HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const + { + return s_halfedge_handle(_eh, _i); + } + + EdgeHandle edge_handle(HalfedgeHandle _heh) const + { return s_edge_handle(_heh); } + + // --- face connectivity --- + HalfedgeHandle halfedge_handle(FaceHandle _fh) const + { return face(_fh).halfedge_handle_; } + + void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh) + { +// assert(is_valid_handle(_heh)); + face(_fh).halfedge_handle_ = _heh; + } + + /// Status Query API + //------------------------------------------------------------ vertex status + const StatusInfo& status(VertexHandle _vh) const + { return property(vertex_status_, _vh); } + + StatusInfo& status(VertexHandle _vh) + { return property(vertex_status_, _vh); } + + /** + * Reinitializes the status of all vertices using the StatusInfo default + * constructor, i.e. all flags will be set to false. + */ + void reset_status() { + PropertyT &status_prop = property(vertex_status_); + PropertyT::vector_type &sprop_v = status_prop.data_vector(); + std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo()); + } + + //----------------------------------------------------------- halfedge status + const StatusInfo& status(HalfedgeHandle _hh) const + { return property(halfedge_status_, _hh); } + + StatusInfo& status(HalfedgeHandle _hh) + { return property(halfedge_status_, _hh); } + + //--------------------------------------------------------------- edge status + const StatusInfo& status(EdgeHandle _eh) const + { return property(edge_status_, _eh); } + + StatusInfo& status(EdgeHandle _eh) + { return property(edge_status_, _eh); } + + //--------------------------------------------------------------- face status + const StatusInfo& status(FaceHandle _fh) const + { return property(face_status_, _fh); } + + StatusInfo& status(FaceHandle _fh) + { return property(face_status_, _fh); } + + inline bool has_vertex_status() const + { return vertex_status_.is_valid(); } + + inline bool has_halfedge_status() const + { return halfedge_status_.is_valid(); } + + inline bool has_edge_status() const + { return edge_status_.is_valid(); } + + inline bool has_face_status() const + { return face_status_.is_valid(); } + + inline VertexStatusPropertyHandle vertex_status_pph() const + { return vertex_status_; } + + inline HalfedgeStatusPropertyHandle halfedge_status_pph() const + { return halfedge_status_; } + + inline EdgeStatusPropertyHandle edge_status_pph() const + { return edge_status_; } + + inline FaceStatusPropertyHandle face_status_pph() const + { return face_status_; } + + /// status property by handle + inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const + { return vertex_status_pph(); } + + inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const + { return halfedge_status_pph(); } + + inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const + { return edge_status_pph(); } + + inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const + { return face_status_pph(); } + + /// Status Request API + void request_vertex_status() + { + if (!refcount_vstatus_++) + add_property( vertex_status_, "v:status" ); + } + + void request_halfedge_status() + { + if (!refcount_hstatus_++) + add_property( halfedge_status_, "h:status" ); + } + + void request_edge_status() + { + if (!refcount_estatus_++) + add_property( edge_status_, "e:status" ); + } + + void request_face_status() + { + if (!refcount_fstatus_++) + add_property( face_status_, "f:status" ); + } + + /// Status Release API + void release_vertex_status() + { + if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_)) + remove_property(vertex_status_); + } + + void release_halfedge_status() + { + if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_)) + remove_property(halfedge_status_); + } + + void release_edge_status() + { + if ((refcount_estatus_ > 0) && (! --refcount_estatus_)) + remove_property(edge_status_); + } + + void release_face_status() + { + if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_)) + remove_property(face_status_); + } + + /// --- StatusSet API --- + + /*! + Implements a set of connectivity entities (vertex, edge, face, halfedge) + using the available bits in the corresponding mesh status field. + + Status-based sets are much faster than std::set<> and equivalent + in performance to std::vector, but much more convenient. + */ + template + class StatusSetT + { + public: + typedef HandleT Handle; + + protected: + ArrayKernel& kernel_; + + public: + const unsigned int bit_mask_; + + public: + StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask) + : kernel_(_kernel), bit_mask_(_bit_mask) + {} + + ~StatusSetT() + {} + + inline bool is_in(Handle _hnd) const + { return kernel_.status(_hnd).is_bit_set(bit_mask_); } + + inline void insert(Handle _hnd) + { kernel_.status(_hnd).set_bit(bit_mask_); } + + inline void erase(Handle _hnd) + { kernel_.status(_hnd).unset_bit(bit_mask_); } + + //! Note: 0(n) complexity + size_t size() const + { + const int n = kernel_.status_pph(Handle()).is_valid() ? + (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0; + + size_t sz = 0; + for (int i = 0; i < n; ++i) + sz += (size_t)is_in(Handle(i)); + return sz; + } + + //! Note: O(n) complexity + void clear() + { + const int n = kernel_.status_pph(Handle()).is_valid() ? + (int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0; + + for (int i = 0; i < n; ++i) + erase(Handle(i)); + } + }; + + friend class StatusSetT; + friend class StatusSetT; + friend class StatusSetT; + friend class StatusSetT; + + //! AutoStatusSetT: A status set that automatically picks a status bit + template + class AutoStatusSetT : public StatusSetT + { + private: + typedef HandleT Handle; + typedef StatusSetT Base; + + public: + AutoStatusSetT(ArrayKernel& _kernel) + : StatusSetT(_kernel, _kernel.pop_bit_mask(Handle())) + { /*assert(size() == 0);*/ } //the set should be empty on creation + + ~AutoStatusSetT() + { + //assert(size() == 0);//the set should be empty on leave? + Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_); + } + }; + + friend class AutoStatusSetT; + friend class AutoStatusSetT; + friend class AutoStatusSetT; + friend class AutoStatusSetT; + + typedef AutoStatusSetT VertexStatusSet; + typedef AutoStatusSetT EdgeStatusSet; + typedef AutoStatusSetT FaceStatusSet; + typedef AutoStatusSetT HalfedgeStatusSet; + + //! ExtStatusSet: A status set augmented with an array + template + class ExtStatusSetT : public AutoStatusSetT + { + public: + typedef HandleT Handle; + typedef AutoStatusSetT Base; + + protected: + typedef std::vector HandleContainer; + HandleContainer handles_; + + public: + typedef typename HandleContainer::iterator + iterator; + typedef typename HandleContainer::const_iterator + const_iterator; + public: + ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0) + : Base(_kernel) + { handles_.reserve(_capacity_hint); } + + ~ExtStatusSetT() + { clear(); } + + // Complexity: O(1) + inline void insert(Handle _hnd) + { + if (!is_in(_hnd)) + { + Base::insert(_hnd); + handles_.push_back(_hnd); + } + } + + //! Complexity: O(k), (k - number of the elements in the set) + inline void erase(Handle _hnd) + { + if (is_in(_hnd)) + { + iterator it = std::find(begin(), end(), _hnd); + erase(it); + } + } + + //! Complexity: O(1) + inline void erase(iterator _it) + { + assert(_it != end() && is_in(*_it)); + Base::erase(*_it); + *_it = handles_.back(); + _it.pop_back(); + } + + inline void clear() + { + for (iterator it = begin(); it != end(); ++it) + { + assert(is_in(*it)); + Base::erase(*it); + } + handles_.clear(); + } + + /// Complexity: 0(1) + inline unsigned int size() const + { return handles_.size(); } + inline bool empty() const + { return handles_.empty(); } + + //Vector API + inline iterator begin() + { return handles_.begin(); } + inline const_iterator begin() const + { return handles_.begin(); } + + inline iterator end() + { return handles_.end(); } + inline const_iterator end() const + { return handles_.end(); } + + inline Handle& front() + { return handles_.front(); } + inline const Handle& front() const + { return handles_.front(); } + + inline Handle& back() + { return handles_.back(); } + inline const Handle& back() const + { return handles_.back(); } + }; + + typedef ExtStatusSetT ExtFaceStatusSet; + typedef ExtStatusSetT ExtVertexStatusSet; + typedef ExtStatusSetT ExtEdgeStatusSet; + typedef ExtStatusSetT ExtHalfedgeStatusSet; + +private: + // iterators + typedef std::vector VertexContainer; + typedef std::vector EdgeContainer; + typedef std::vector FaceContainer; + typedef VertexContainer::iterator KernelVertexIter; + typedef VertexContainer::const_iterator KernelConstVertexIter; + typedef EdgeContainer::iterator KernelEdgeIter; + typedef EdgeContainer::const_iterator KernelConstEdgeIter; + typedef FaceContainer::iterator KernelFaceIter; + typedef FaceContainer::const_iterator KernelConstFaceIter; + typedef std::vector BitMaskContainer; + + + KernelVertexIter vertices_begin() { return vertices_.begin(); } + KernelConstVertexIter vertices_begin() const { return vertices_.begin(); } + KernelVertexIter vertices_end() { return vertices_.end(); } + KernelConstVertexIter vertices_end() const { return vertices_.end(); } + + KernelEdgeIter edges_begin() { return edges_.begin(); } + KernelConstEdgeIter edges_begin() const { return edges_.begin(); } + KernelEdgeIter edges_end() { return edges_.end(); } + KernelConstEdgeIter edges_end() const { return edges_.end(); } + + KernelFaceIter faces_begin() { return faces_.begin(); } + KernelConstFaceIter faces_begin() const { return faces_.begin(); } + KernelFaceIter faces_end() { return faces_.end(); } + KernelConstFaceIter faces_end() const { return faces_.end(); } + + /// bit mask container by handle + inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/) + { return vertex_bit_masks_; } + inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/) + { return edge_bit_masks_; } + inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/) + { return face_bit_masks_; } + inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/) + { return halfedge_bit_masks_; } + + template + unsigned int pop_bit_mask(Handle _hnd) + { + assert(!bit_masks(_hnd).empty());//check if the client request too many status sets + unsigned int bit_mask = bit_masks(_hnd).back(); + bit_masks(_hnd).pop_back(); + return bit_mask; + } + + template + void push_bit_mask(Handle _hnd, unsigned int _bit_mask) + { + assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) == + bit_masks(_hnd).end());//this mask should be not already used + bit_masks(_hnd).push_back(_bit_mask); + } + + void init_bit_masks(BitMaskContainer& _bmc); + void init_bit_masks(); + +protected: + + VertexStatusPropertyHandle vertex_status_; + HalfedgeStatusPropertyHandle halfedge_status_; + EdgeStatusPropertyHandle edge_status_; + FaceStatusPropertyHandle face_status_; + + unsigned int refcount_vstatus_; + unsigned int refcount_hstatus_; + unsigned int refcount_estatus_; + unsigned int refcount_fstatus_; + +private: + VertexContainer vertices_; + EdgeContainer edges_; + FaceContainer faces_; + + BitMaskContainer halfedge_bit_masks_; + BitMaskContainer edge_bit_masks_; + BitMaskContainer vertex_bit_masks_; + BitMaskContainer face_bit_masks_; +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C) +# define OPENMESH_ARRAY_KERNEL_TEMPLATES +# include "ArrayKernelT.cc" +#endif +//============================================================================= +#endif // OPENMESH_ARRAY_KERNEL_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/AttribKernelT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/AttribKernelT.hh new file mode 100644 index 0000000..c0d52a8 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/AttribKernelT.hh @@ -0,0 +1,782 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_ATTRIBKERNEL_HH +#define OPENMESH_ATTRIBKERNEL_HH + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + +/** \class AttribKernelT AttribKernelT.hh + + The attribute kernel adds all standard properties to the kernel. Therefore + the functions/types defined here provide a subset of the kernel + interface as described in Concepts::KernelT. + + \see Concepts::KernelT +*/ +template +class AttribKernelT : public Connectivity +{ +public: + + //---------------------------------------------------------------- item types + + typedef MeshItems MeshItemsT; + typedef Connectivity ConnectivityT; + typedef typename Connectivity::Vertex Vertex; + typedef typename Connectivity::Halfedge Halfedge; + typedef typename Connectivity::Edge Edge; + typedef typename Connectivity::Face Face; + + typedef typename MeshItems::Point Point; + typedef typename MeshItems::Normal Normal; + typedef typename MeshItems::Color Color; + typedef typename MeshItems::TexCoord1D TexCoord1D; + typedef typename MeshItems::TexCoord2D TexCoord2D; + typedef typename MeshItems::TexCoord3D TexCoord3D; + typedef typename MeshItems::Scalar Scalar; + typedef typename MeshItems::TextureIndex TextureIndex; + + typedef typename MeshItems::VertexData VertexData; + typedef typename MeshItems::HalfedgeData HalfedgeData; + typedef typename MeshItems::EdgeData EdgeData; + typedef typename MeshItems::FaceData FaceData; + + typedef AttribKernelT AttribKernel; + + enum Attribs { + VAttribs = MeshItems::VAttribs, + HAttribs = MeshItems::HAttribs, + EAttribs = MeshItems::EAttribs, + FAttribs = MeshItems::FAttribs + }; + + typedef VPropHandleT DataVPropHandle; + typedef HPropHandleT DataHPropHandle; + typedef EPropHandleT DataEPropHandle; + typedef FPropHandleT DataFPropHandle; + +public: + + //-------------------------------------------------- constructor / destructor + + AttribKernelT() + : refcount_vnormals_(0), + refcount_vcolors_(0), + refcount_vtexcoords1D_(0), + refcount_vtexcoords2D_(0), + refcount_vtexcoords3D_(0), + refcount_htexcoords1D_(0), + refcount_htexcoords2D_(0), + refcount_htexcoords3D_(0), + refcount_henormals_(0), + refcount_hecolors_(0), + refcount_ecolors_(0), + refcount_fnormals_(0), + refcount_fcolors_(0), + refcount_ftextureIndex_(0) + { + this->add_property( points_, "v:points" ); + + if (VAttribs & Attributes::Normal) + request_vertex_normals(); + + if (VAttribs & Attributes::Color) + request_vertex_colors(); + + if (VAttribs & Attributes::TexCoord1D) + request_vertex_texcoords1D(); + + if (VAttribs & Attributes::TexCoord2D) + request_vertex_texcoords2D(); + + if (VAttribs & Attributes::TexCoord3D) + request_vertex_texcoords3D(); + + if (HAttribs & Attributes::TexCoord1D) + request_halfedge_texcoords1D(); + + if (HAttribs & Attributes::TexCoord2D) + request_halfedge_texcoords2D(); + + if (HAttribs & Attributes::TexCoord3D) + request_halfedge_texcoords3D(); + + if (HAttribs & Attributes::Color) + request_halfedge_colors(); + + if (VAttribs & Attributes::Status) + Connectivity::request_vertex_status(); + + if (HAttribs & Attributes::Status) + Connectivity::request_halfedge_status(); + + if (HAttribs & Attributes::Normal) + request_halfedge_normals(); + + if (EAttribs & Attributes::Status) + Connectivity::request_edge_status(); + + if (EAttribs & Attributes::Color) + request_edge_colors(); + + if (FAttribs & Attributes::Normal) + request_face_normals(); + + if (FAttribs & Attributes::Color) + request_face_colors(); + + if (FAttribs & Attributes::Status) + Connectivity::request_face_status(); + + if (FAttribs & Attributes::TextureIndex) + request_face_texture_index(); + + //FIXME: data properties might actually cost storage even + //if there are no data traits?? + this->add_property(data_vpph_); + this->add_property(data_fpph_); + this->add_property(data_hpph_); + this->add_property(data_epph_); + } + + virtual ~AttribKernelT() + { + // should remove properties, but this will be done in + // BaseKernel's destructor anyway... + } + + /** Assignment from another mesh of \em another type. + \note All that's copied is connectivity and vertex positions. + All other information (like e.g. attributes or additional + elements from traits classes) is not copied. + \note If you want to copy all information, including *custom* properties, + use PolyMeshT::operator=() instead. + */ + template + void assign(const _AttribKernel& _other, bool copyStandardProperties = false) + { + //copy standard properties if necessary + if(copyStandardProperties) + this->copy_all_kernel_properties(_other); + + this->assign_connectivity(_other); + for (typename Connectivity::VertexIter v_it = Connectivity::vertices_begin(); + v_it != Connectivity::vertices_end(); ++v_it) + {//assumes Point constructor supports cast from _AttribKernel::Point + set_point(*v_it, (Point)_other.point(*v_it)); + } + + //initialize standard properties if necessary + if(copyStandardProperties) + initializeStandardProperties(); + } + + //-------------------------------------------------------------------- points + + const Point* points() const + { return this->property(points_).data(); } + + const Point& point(VertexHandle _vh) const + { return this->property(points_, _vh); } + + Point& point(VertexHandle _vh) + { return this->property(points_, _vh); } + + void set_point(VertexHandle _vh, const Point& _p) + { this->property(points_, _vh) = _p; } + + + //------------------------------------------------------------ vertex normals + + const Normal* vertex_normals() const + { return this->property(vertex_normals_).data(); } + + const Normal& normal(VertexHandle _vh) const + { return this->property(vertex_normals_, _vh); } + + void set_normal(VertexHandle _vh, const Normal& _n) + { this->property(vertex_normals_, _vh) = _n; } + + + //------------------------------------------------------------- vertex colors + + const Color* vertex_colors() const + { return this->property(vertex_colors_).data(); } + + const Color& color(VertexHandle _vh) const + { return this->property(vertex_colors_, _vh); } + + void set_color(VertexHandle _vh, const Color& _c) + { this->property(vertex_colors_, _vh) = _c; } + + + //------------------------------------------------------- vertex 1D texcoords + + const TexCoord1D* texcoords1D() const { + return this->property(vertex_texcoords1D_).data(); + } + + const TexCoord1D& texcoord1D(VertexHandle _vh) const { + return this->property(vertex_texcoords1D_, _vh); + } + + void set_texcoord1D(VertexHandle _vh, const TexCoord1D& _t) { + this->property(vertex_texcoords1D_, _vh) = _t; + } + + + //------------------------------------------------------- vertex 2D texcoords + + const TexCoord2D* texcoords2D() const { + return this->property(vertex_texcoords2D_).data(); + } + + const TexCoord2D& texcoord2D(VertexHandle _vh) const { + return this->property(vertex_texcoords2D_, _vh); + } + + void set_texcoord2D(VertexHandle _vh, const TexCoord2D& _t) { + this->property(vertex_texcoords2D_, _vh) = _t; + } + + + //------------------------------------------------------- vertex 3D texcoords + + const TexCoord3D* texcoords3D() const { + return this->property(vertex_texcoords3D_).data(); + } + + const TexCoord3D& texcoord3D(VertexHandle _vh) const { + return this->property(vertex_texcoords3D_, _vh); + } + + void set_texcoord3D(VertexHandle _vh, const TexCoord3D& _t) { + this->property(vertex_texcoords3D_, _vh) = _t; + } + + //.------------------------------------------------------ halfedge 1D texcoords + + const TexCoord1D* htexcoords1D() const { + return this->property(halfedge_texcoords1D_).data(); + } + + const TexCoord1D& texcoord1D(HalfedgeHandle _heh) const { + return this->property(halfedge_texcoords1D_, _heh); + } + + void set_texcoord1D(HalfedgeHandle _heh, const TexCoord1D& _t) { + this->property(halfedge_texcoords1D_, _heh) = _t; + } + + + //------------------------------------------------------- halfedge 2D texcoords + + const TexCoord2D* htexcoords2D() const { + return this->property(halfedge_texcoords2D_).data(); + } + + const TexCoord2D& texcoord2D(HalfedgeHandle _heh) const { + return this->property(halfedge_texcoords2D_, _heh); + } + + void set_texcoord2D(HalfedgeHandle _heh, const TexCoord2D& _t) { + this->property(halfedge_texcoords2D_, _heh) = _t; + } + + + //------------------------------------------------------- halfedge 3D texcoords + + const TexCoord3D* htexcoords3D() const { + return this->property(halfedge_texcoords3D_).data(); + } + + const TexCoord3D& texcoord3D(HalfedgeHandle _heh) const { + return this->property(halfedge_texcoords3D_, _heh); + } + + void set_texcoord3D(HalfedgeHandle _heh, const TexCoord3D& _t) { + this->property(halfedge_texcoords3D_, _heh) = _t; + } + + //------------------------------------------------------------- edge colors + + const Color* edge_colors() const + { return this->property(edge_colors_).data(); } + + const Color& color(EdgeHandle _eh) const + { return this->property(edge_colors_, _eh); } + + void set_color(EdgeHandle _eh, const Color& _c) + { this->property(edge_colors_, _eh) = _c; } + + + //------------------------------------------------------------- halfedge normals + + const Normal& normal(HalfedgeHandle _heh) const + { return this->property(halfedge_normals_, _heh); } + + void set_normal(HalfedgeHandle _heh, const Normal& _n) + { this->property(halfedge_normals_, _heh) = _n; } + + + //------------------------------------------------------------- halfedge colors + + const Color* halfedge_colors() const + { return this->property(halfedge_colors_).data(); } + + const Color& color(HalfedgeHandle _heh) const + { return this->property(halfedge_colors_, _heh); } + + void set_color(HalfedgeHandle _heh, const Color& _c) + { this->property(halfedge_colors_, _heh) = _c; } + + //-------------------------------------------------------------- face normals + + const Normal& normal(FaceHandle _fh) const + { return this->property(face_normals_, _fh); } + + void set_normal(FaceHandle _fh, const Normal& _n) + { this->property(face_normals_, _fh) = _n; } + + //-------------------------------------------------------------- per Face Texture index + + const TextureIndex& texture_index(FaceHandle _fh) const + { return this->property(face_texture_index_, _fh); } + + void set_texture_index(FaceHandle _fh, const TextureIndex& _t) + { this->property(face_texture_index_, _fh) = _t; } + + //--------------------------------------------------------------- face colors + + const Color& color(FaceHandle _fh) const + { return this->property(face_colors_, _fh); } + + void set_color(FaceHandle _fh, const Color& _c) + { this->property(face_colors_, _fh) = _c; } + + //------------------------------------------------ request / alloc properties + + void request_vertex_normals() + { + if (!refcount_vnormals_++) + this->add_property( vertex_normals_, "v:normals" ); + } + + void request_vertex_colors() + { + if (!refcount_vcolors_++) + this->add_property( vertex_colors_, "v:colors" ); + } + + void request_vertex_texcoords1D() + { + if (!refcount_vtexcoords1D_++) + this->add_property( vertex_texcoords1D_, "v:texcoords1D" ); + } + + void request_vertex_texcoords2D() + { + if (!refcount_vtexcoords2D_++) + this->add_property( vertex_texcoords2D_, "v:texcoords2D" ); + } + + void request_vertex_texcoords3D() + { + if (!refcount_vtexcoords3D_++) + this->add_property( vertex_texcoords3D_, "v:texcoords3D" ); + } + + void request_halfedge_texcoords1D() + { + if (!refcount_htexcoords1D_++) + this->add_property( halfedge_texcoords1D_, "h:texcoords1D" ); + } + + void request_halfedge_texcoords2D() + { + if (!refcount_htexcoords2D_++) + this->add_property( halfedge_texcoords2D_, "h:texcoords2D" ); + } + + void request_halfedge_texcoords3D() + { + if (!refcount_htexcoords3D_++) + this->add_property( halfedge_texcoords3D_, "h:texcoords3D" ); + } + + void request_edge_colors() + { + if (!refcount_ecolors_++) + this->add_property( edge_colors_, "e:colors" ); + } + + void request_halfedge_normals() + { + if (!refcount_henormals_++) + this->add_property( halfedge_normals_, "h:normals" ); + } + + void request_halfedge_colors() + { + if (!refcount_hecolors_++) + this->add_property( halfedge_colors_, "h:colors" ); + } + + void request_face_normals() + { + if (!refcount_fnormals_++) + this->add_property( face_normals_, "f:normals" ); + } + + void request_face_colors() + { + if (!refcount_fcolors_++) + this->add_property( face_colors_, "f:colors" ); + } + + void request_face_texture_index() + { + if (!refcount_ftextureIndex_++) + this->add_property( face_texture_index_, "f:textureindex" ); + } + + //------------------------------------------------- release / free properties + + void release_vertex_normals() + { + if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_)) + this->remove_property(vertex_normals_); + } + + void release_vertex_colors() + { + if ((refcount_vcolors_ > 0) && (! --refcount_vcolors_)) + this->remove_property(vertex_colors_); + } + + void release_vertex_texcoords1D() { + if ((refcount_vtexcoords1D_ > 0) && (! --refcount_vtexcoords1D_)) + this->remove_property(vertex_texcoords1D_); + } + + void release_vertex_texcoords2D() { + if ((refcount_vtexcoords2D_ > 0) && (! --refcount_vtexcoords2D_)) + this->remove_property(vertex_texcoords2D_); + } + + void release_vertex_texcoords3D() { + if ((refcount_vtexcoords3D_ > 0) && (! --refcount_vtexcoords3D_)) + this->remove_property(vertex_texcoords3D_); + } + + void release_halfedge_texcoords1D() { + if ((refcount_htexcoords1D_ > 0) && (! --refcount_htexcoords1D_)) + this->remove_property(halfedge_texcoords1D_); + } + + void release_halfedge_texcoords2D() { + if ((refcount_htexcoords2D_ > 0) && (! --refcount_htexcoords2D_)) + this->remove_property(halfedge_texcoords2D_); + } + + void release_halfedge_texcoords3D() { + if ((refcount_htexcoords3D_ > 0) && (! --refcount_htexcoords3D_)) + this->remove_property(halfedge_texcoords3D_); + } + + void release_edge_colors() + { + if ((refcount_ecolors_ > 0) && (! --refcount_ecolors_)) + this->remove_property(edge_colors_); + } + + void release_halfedge_normals() + { + if ((refcount_henormals_ > 0) && (! --refcount_henormals_)) + this->remove_property(halfedge_normals_); + } + + void release_halfedge_colors() + { + if ((refcount_hecolors_ > 0) && (! --refcount_hecolors_)) + this->remove_property(halfedge_colors_); + } + + void release_face_normals() + { + if ((refcount_fnormals_ > 0) && (! --refcount_fnormals_)) + this->remove_property(face_normals_); + } + + void release_face_colors() + { + if ((refcount_fcolors_ > 0) && (! --refcount_fcolors_)) + this->remove_property(face_colors_); + } + + void release_face_texture_index() + { + if ((refcount_ftextureIndex_ > 0) && (! --refcount_ftextureIndex_)) + this->remove_property(face_texture_index_); + } + + //---------------------------------------------- dynamic check for properties + + bool has_vertex_normals() const { return vertex_normals_.is_valid(); } + bool has_vertex_colors() const { return vertex_colors_.is_valid(); } + bool has_vertex_texcoords1D() const { return vertex_texcoords1D_.is_valid(); } + bool has_vertex_texcoords2D() const { return vertex_texcoords2D_.is_valid(); } + bool has_vertex_texcoords3D() const { return vertex_texcoords3D_.is_valid(); } + bool has_halfedge_texcoords1D() const { return halfedge_texcoords1D_.is_valid();} + bool has_halfedge_texcoords2D() const { return halfedge_texcoords2D_.is_valid();} + bool has_halfedge_texcoords3D() const { return halfedge_texcoords3D_.is_valid();} + bool has_edge_colors() const { return edge_colors_.is_valid(); } + bool has_halfedge_normals() const { return halfedge_normals_.is_valid(); } + bool has_halfedge_colors() const { return halfedge_colors_.is_valid(); } + bool has_face_normals() const { return face_normals_.is_valid(); } + bool has_face_colors() const { return face_colors_.is_valid(); } + bool has_face_texture_index() const { return face_texture_index_.is_valid(); } + +public: + + typedef VPropHandleT PointsPropertyHandle; + typedef VPropHandleT VertexNormalsPropertyHandle; + typedef VPropHandleT VertexColorsPropertyHandle; + typedef VPropHandleT VertexTexCoords1DPropertyHandle; + typedef VPropHandleT VertexTexCoords2DPropertyHandle; + typedef VPropHandleT VertexTexCoords3DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords1DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords2DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords3DPropertyHandle; + typedef EPropHandleT EdgeColorsPropertyHandle; + typedef HPropHandleT HalfedgeNormalsPropertyHandle; + typedef HPropHandleT HalfedgeColorsPropertyHandle; + typedef FPropHandleT FaceNormalsPropertyHandle; + typedef FPropHandleT FaceColorsPropertyHandle; + typedef FPropHandleT FaceTextureIndexPropertyHandle; + +public: + //standard vertex properties + PointsPropertyHandle points_pph() const + { return points_; } + + VertexNormalsPropertyHandle vertex_normals_pph() const + { return vertex_normals_; } + + VertexColorsPropertyHandle vertex_colors_pph() const + { return vertex_colors_; } + + VertexTexCoords1DPropertyHandle vertex_texcoords1D_pph() const + { return vertex_texcoords1D_; } + + VertexTexCoords2DPropertyHandle vertex_texcoords2D_pph() const + { return vertex_texcoords2D_; } + + VertexTexCoords3DPropertyHandle vertex_texcoords3D_pph() const + { return vertex_texcoords3D_; } + + //standard halfedge properties + HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_pph() const + { return halfedge_texcoords1D_; } + + HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_pph() const + { return halfedge_texcoords2D_; } + + HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_pph() const + { return halfedge_texcoords3D_; } + + // standard edge properties + HalfedgeNormalsPropertyHandle halfedge_normals_pph() const + { return halfedge_normals_; } + + + // standard edge properties + HalfedgeColorsPropertyHandle halfedge_colors_pph() const + { return halfedge_colors_; } + + // standard edge properties + EdgeColorsPropertyHandle edge_colors_pph() const + { return edge_colors_; } + + //standard face properties + FaceNormalsPropertyHandle face_normals_pph() const + { return face_normals_; } + + FaceColorsPropertyHandle face_colors_pph() const + { return face_colors_; } + + FaceTextureIndexPropertyHandle face_texture_index_pph() const + { return face_texture_index_; } + + VertexData& data(VertexHandle _vh) + { return this->property(data_vpph_, _vh); } + + const VertexData& data(VertexHandle _vh) const + { return this->property(data_vpph_, _vh); } + + FaceData& data(FaceHandle _fh) + { return this->property(data_fpph_, _fh); } + + const FaceData& data(FaceHandle _fh) const + { return this->property(data_fpph_, _fh); } + + EdgeData& data(EdgeHandle _eh) + { return this->property(data_epph_, _eh); } + + const EdgeData& data(EdgeHandle _eh) const + { return this->property(data_epph_, _eh); } + + HalfedgeData& data(HalfedgeHandle _heh) + { return this->property(data_hpph_, _heh); } + + const HalfedgeData& data(HalfedgeHandle _heh) const + { return this->property(data_hpph_, _heh); } + +private: + //standard vertex properties + PointsPropertyHandle points_; + VertexNormalsPropertyHandle vertex_normals_; + VertexColorsPropertyHandle vertex_colors_; + VertexTexCoords1DPropertyHandle vertex_texcoords1D_; + VertexTexCoords2DPropertyHandle vertex_texcoords2D_; + VertexTexCoords3DPropertyHandle vertex_texcoords3D_; + //standard halfedge properties + HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_; + HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_; + HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_; + HalfedgeNormalsPropertyHandle halfedge_normals_; + HalfedgeColorsPropertyHandle halfedge_colors_; + // standard edge properties + EdgeColorsPropertyHandle edge_colors_; + //standard face properties + FaceNormalsPropertyHandle face_normals_; + FaceColorsPropertyHandle face_colors_; + FaceTextureIndexPropertyHandle face_texture_index_; + //data properties handles + DataVPropHandle data_vpph_; + DataHPropHandle data_hpph_; + DataEPropHandle data_epph_; + DataFPropHandle data_fpph_; + + unsigned int refcount_vnormals_; + unsigned int refcount_vcolors_; + unsigned int refcount_vtexcoords1D_; + unsigned int refcount_vtexcoords2D_; + unsigned int refcount_vtexcoords3D_; + unsigned int refcount_htexcoords1D_; + unsigned int refcount_htexcoords2D_; + unsigned int refcount_htexcoords3D_; + unsigned int refcount_henormals_; + unsigned int refcount_hecolors_; + unsigned int refcount_ecolors_; + unsigned int refcount_fnormals_; + unsigned int refcount_fcolors_; + unsigned int refcount_ftextureIndex_; + + /** + * @brief initializeStandardProperties Initializes the standard properties + * and sets refcount to 1 if found. (e.g. when the copy constructor was used) + */ + void initializeStandardProperties() + { + if(!this->get_property_handle(points_, + "v:points")) + { + //mesh has no points? + } + refcount_vnormals_ = this->get_property_handle(vertex_normals_, + "v:normals") ? 1 : 0 ; + refcount_vcolors_ = this->get_property_handle(vertex_colors_, + "v:colors") ? 1 : 0 ; + refcount_vtexcoords1D_ = this->get_property_handle(vertex_texcoords1D_, + "v:texcoords1D") ? 1 : 0 ; + refcount_vtexcoords2D_ = this->get_property_handle(vertex_texcoords2D_, + "v:texcoords2D") ? 1 : 0 ; + refcount_vtexcoords3D_ = this->get_property_handle(vertex_texcoords3D_, + "v:texcoords3D") ? 1 : 0 ; + refcount_htexcoords1D_ = this->get_property_handle(halfedge_texcoords1D_, + "h:texcoords1D") ? 1 : 0 ; + refcount_htexcoords2D_ = this->get_property_handle(halfedge_texcoords2D_, + "h:texcoords2D") ? 1 : 0 ; + refcount_htexcoords3D_ = this->get_property_handle(halfedge_texcoords3D_, + "h:texcoords3D") ? 1 : 0 ; + refcount_henormals_ = this->get_property_handle(halfedge_normals_, + "h:normals") ? 1 : 0 ; + refcount_hecolors_ = this->get_property_handle(halfedge_colors_, + "h:colors") ? 1 : 0 ; + refcount_ecolors_ = this->get_property_handle(edge_colors_, + "e:colors") ? 1 : 0 ; + refcount_fnormals_ = this->get_property_handle(face_normals_, + "f:normals") ? 1 : 0 ; + refcount_fcolors_ = this->get_property_handle(face_colors_, + "f:colors") ? 1 : 0 ; + refcount_ftextureIndex_ = this->get_property_handle(face_texture_index_, + "f:textureindex") ? 1 : 0 ; + } +}; + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_ATTRIBKERNEL_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/Attributes.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Attributes.hh new file mode 100644 index 0000000..e53f021 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Attributes.hh @@ -0,0 +1,103 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +/** + \file Attributes.hh + This file provides some macros containing attribute usage. +*/ + + +#ifndef OPENMESH_ATTRIBUTES_HH +#define OPENMESH_ATTRIBUTES_HH + + +//== INCLUDES ================================================================= + + +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace Attributes { + + +//== CLASS DEFINITION ======================================================== + +/** Attribute bits + * + * Use the bits to define a standard property at compile time using traits. + * + * \include traits5.cc + * + * \see \ref mesh_type + */ +enum AttributeBits +{ + None = 0, ///< Clear all attribute bits + Normal = 1, ///< Add normals to mesh item (vertices/faces) + Color = 2, ///< Add colors to mesh item (vertices/faces/edges) + PrevHalfedge = 4, ///< Add storage for previous halfedge (halfedges). The bit is set by default in the DefaultTraits. + Status = 8, ///< Add status to mesh item (all items) + TexCoord1D = 16, ///< Add 1D texture coordinates (vertices, halfedges) + TexCoord2D = 32, ///< Add 2D texture coordinates (vertices, halfedges) + TexCoord3D = 64, ///< Add 3D texture coordinates (vertices, halfedges) + TextureIndex = 128 ///< Add texture index (faces) +}; + + +//============================================================================= +} // namespace Attributes +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_ATTRIBUTES_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/BaseKernel.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/BaseKernel.hh new file mode 100644 index 0000000..6bca014 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/BaseKernel.hh @@ -0,0 +1,826 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS BaseKernel +// +//============================================================================= + + +#ifndef OPENMESH_BASE_KERNEL_HH +#define OPENMESH_BASE_KERNEL_HH + + +//== INCLUDES ================================================================= + + +#include +// -------------------- +#include +#include +#include +#include +// -------------------- +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + +/// This class provides low-level property management like adding/removing +/// properties and access to properties. Under most circumstances, it is +/// advisable to use the high-level property management provided by +/// PropertyManager, instead. +/// +/// All operations provided by %BaseKernel need at least a property handle +/// (VPropHandleT, EPropHandleT, HPropHandleT, FPropHandleT, MPropHandleT). +/// which keeps the data type of the property, too. +/// +/// There are two types of properties: +/// -# Standard properties - mesh data (e.g. vertex normal or face color) +/// -# Custom properties - user defined data +/// +/// The differentiation is only semantically, technically both are +/// equally handled. Therefore the methods provided by the %BaseKernel +/// are applicable to both property types. +/// +/// \attention Since the class PolyMeshT derives from a kernel, hence all public +/// elements of %BaseKernel are usable. + +class OPENMESHDLLEXPORT BaseKernel +{ +public: //-------------------------------------------- constructor / destructor + + BaseKernel() {} + virtual ~BaseKernel() { + vprops_.clear(); + eprops_.clear(); + hprops_.clear(); + fprops_.clear(); + } + + +public: //-------------------------------------------------- add new properties + + /// \name Add a property to a mesh item + + //@{ + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper and/or one of its helper functions such as + * makePropertyManagerFromNew, makePropertyManagerFromExisting, or + * makePropertyManagerFromExistingOrNew. + * + * Adds a property + * + * Depending on the property handle type a vertex, (half-)edge, face or + * mesh property is added to the mesh. If the action fails the handle + * is invalid. + * On success the handle must be used to access the property data with + * property(). + * + * \param _ph A property handle defining the data type to bind to mesh. + * On success the handle is valid else invalid. + * \param _name Optional name of property. Following restrictions apply + * to the name: + * -# Maximum length of name is 256 characters + * -# The prefixes matching "^[vhefm]:" are reserved for + * internal usage. + * -# The expression "^<.*>$" is reserved for internal usage. + * + */ + + template + void add_property( VPropHandleT& _ph, const std::string& _name="") + { + _ph = VPropHandleT( vprops_.add(T(), _name) ); + vprops_.resize(n_vertices()); + } + + template + void add_property( HPropHandleT& _ph, const std::string& _name="") + { + _ph = HPropHandleT( hprops_.add(T(), _name) ); + hprops_.resize(n_halfedges()); + } + + template + void add_property( EPropHandleT& _ph, const std::string& _name="") + { + _ph = EPropHandleT( eprops_.add(T(), _name) ); + eprops_.resize(n_edges()); + } + + template + void add_property( FPropHandleT& _ph, const std::string& _name="") + { + _ph = FPropHandleT( fprops_.add(T(), _name) ); + fprops_.resize(n_faces()); + } + + template + void add_property( MPropHandleT& _ph, const std::string& _name="") + { + _ph = MPropHandleT( mprops_.add(T(), _name) ); + mprops_.resize(1); + } + + //@} + + +public: //--------------------------------------------------- remove properties + + /// \name Removing a property from a mesh tiem + //@{ + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper to manage (and remove) properties. + * + * Remove a property. + * + * Removes the property represented by the handle from the apropriate + * mesh item. + * \param _ph Property to be removed. The handle is invalid afterwords. + */ + + template + void remove_property(VPropHandleT& _ph) + { + if (_ph.is_valid()) + vprops_.remove(_ph); + _ph.reset(); + } + + template + void remove_property(HPropHandleT& _ph) + { + if (_ph.is_valid()) + hprops_.remove(_ph); + _ph.reset(); + } + + template + void remove_property(EPropHandleT& _ph) + { + if (_ph.is_valid()) + eprops_.remove(_ph); + _ph.reset(); + } + + template + void remove_property(FPropHandleT& _ph) + { + if (_ph.is_valid()) + fprops_.remove(_ph); + _ph.reset(); + } + + template + void remove_property(MPropHandleT& _ph) + { + if (_ph.is_valid()) + mprops_.remove(_ph); + _ph.reset(); + } + + //@} + +public: //------------------------------------------------ get handle from name + + /// \name Get property handle by name + //@{ + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper (e.g. PropertyManager::propertyExists) or one of + * its higher level helper functions such as + * makePropertyManagerFromExisting, or makePropertyManagerFromExistingOrNew. + * + * Retrieves the handle to a named property by it's name. + * + * \param _ph A property handle. On success the handle is valid else + * invalid. + * \param _name Name of wanted property. + * \return \c true if such a named property is available, else \c false. + */ + + template + bool get_property_handle(VPropHandleT& _ph, + const std::string& _name) const + { + return (_ph = VPropHandleT(vprops_.handle(T(), _name))).is_valid(); + } + + template + bool get_property_handle(HPropHandleT& _ph, + const std::string& _name) const + { + return (_ph = HPropHandleT(hprops_.handle(T(), _name))).is_valid(); + } + + template + bool get_property_handle(EPropHandleT& _ph, + const std::string& _name) const + { + return (_ph = EPropHandleT(eprops_.handle(T(), _name))).is_valid(); + } + + template + bool get_property_handle(FPropHandleT& _ph, + const std::string& _name) const + { + return (_ph = FPropHandleT(fprops_.handle(T(), _name))).is_valid(); + } + + template + bool get_property_handle(MPropHandleT& _ph, + const std::string& _name) const + { + return (_ph = MPropHandleT(mprops_.handle(T(), _name))).is_valid(); + } + + //@} + +public: //--------------------------------------------------- access properties + + /// \name Access a property + //@{ + + /** In most cases you should use the convenient PropertyManager wrapper + * and use of this function should not be necessary. Under some + * circumstances, however (i.e. making a property persistent), it might be + * necessary to use this function. + * + * Access a property + * + * This method returns a reference to property. The property handle + * must be valid! The result is unpredictable if the handle is invalid! + * + * \param _ph A \em valid (!) property handle. + * \return The wanted property if the handle is valid. + */ + + template + PropertyT& property(VPropHandleT _ph) { + return vprops_.property(_ph); + } + template + const PropertyT& property(VPropHandleT _ph) const { + return vprops_.property(_ph); + } + + template + PropertyT& property(HPropHandleT _ph) { + return hprops_.property(_ph); + } + template + const PropertyT& property(HPropHandleT _ph) const { + return hprops_.property(_ph); + } + + template + PropertyT& property(EPropHandleT _ph) { + return eprops_.property(_ph); + } + template + const PropertyT& property(EPropHandleT _ph) const { + return eprops_.property(_ph); + } + + template + PropertyT& property(FPropHandleT _ph) { + return fprops_.property(_ph); + } + template + const PropertyT& property(FPropHandleT _ph) const { + return fprops_.property(_ph); + } + + template + PropertyT& mproperty(MPropHandleT _ph) { + return mprops_.property(_ph); + } + template + const PropertyT& mproperty(MPropHandleT _ph) const { + return mprops_.property(_ph); + } + + //@} + +public: //-------------------------------------------- access property elements + + /// \name Access a property element using a handle to a mesh item + //@{ + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper. + * + * Return value of property for an item + */ + + template + typename VPropHandleT::reference + property(VPropHandleT _ph, VertexHandle _vh) { + return vprops_.property(_ph)[_vh.idx()]; + } + + template + typename VPropHandleT::const_reference + property(VPropHandleT _ph, VertexHandle _vh) const { + return vprops_.property(_ph)[_vh.idx()]; + } + + + template + typename HPropHandleT::reference + property(HPropHandleT _ph, HalfedgeHandle _hh) { + return hprops_.property(_ph)[_hh.idx()]; + } + + template + typename HPropHandleT::const_reference + property(HPropHandleT _ph, HalfedgeHandle _hh) const { + return hprops_.property(_ph)[_hh.idx()]; + } + + + template + typename EPropHandleT::reference + property(EPropHandleT _ph, EdgeHandle _eh) { + return eprops_.property(_ph)[_eh.idx()]; + } + + template + typename EPropHandleT::const_reference + property(EPropHandleT _ph, EdgeHandle _eh) const { + return eprops_.property(_ph)[_eh.idx()]; + } + + + template + typename FPropHandleT::reference + property(FPropHandleT _ph, FaceHandle _fh) { + return fprops_.property(_ph)[_fh.idx()]; + } + + template + typename FPropHandleT::const_reference + property(FPropHandleT _ph, FaceHandle _fh) const { + return fprops_.property(_ph)[_fh.idx()]; + } + + + template + typename MPropHandleT::reference + property(MPropHandleT _ph) { + return mprops_.property(_ph)[0]; + } + + template + typename MPropHandleT::const_reference + property(MPropHandleT _ph) const { + return mprops_.property(_ph)[0]; + } + + //@} + + +public: //------------------------------------------------ copy property + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper (e.g. PropertyManager::copy_to or + * PropertyManager::copy). + * + * Copies a single property from one mesh element to another (of the same type) + * + * @param _ph A vertex property handle + * @param _vh_from From vertex handle + * @param _vh_to To vertex handle + */ + template + void copy_property(VPropHandleT& _ph, VertexHandle _vh_from, VertexHandle _vh_to) { + if(_vh_from.is_valid() && _vh_to.is_valid()) + vprops_.property(_ph)[_vh_to.idx()] = vprops_.property(_ph)[_vh_from.idx()]; + } + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper (e.g. PropertyManager::copy_to or + * PropertyManager::copy). + * + * Copies a single property from one mesh element to another (of the same type) + * + * @param _ph A halfedge property handle + * @param _hh_from From halfedge handle + * @param _hh_to To halfedge handle + */ + template + void copy_property(HPropHandleT _ph, HalfedgeHandle _hh_from, HalfedgeHandle _hh_to) { + if(_hh_from.is_valid() && _hh_to.is_valid()) + hprops_.property(_ph)[_hh_to.idx()] = hprops_.property(_ph)[_hh_from.idx()]; + } + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper (e.g. PropertyManager::copy_to or + * PropertyManager::copy). + * + * Copies a single property from one mesh element to another (of the same type) + * + * @param _ph An edge property handle + * @param _eh_from From edge handle + * @param _eh_to To edge handle + */ + template + void copy_property(EPropHandleT _ph, EdgeHandle _eh_from, EdgeHandle _eh_to) { + if(_eh_from.is_valid() && _eh_to.is_valid()) + eprops_.property(_ph)[_eh_to.idx()] = eprops_.property(_ph)[_eh_from.idx()]; + } + + /** You should not use this function directly. Instead, use the convenient + * PropertyManager wrapper (e.g. PropertyManager::copy_to or + * PropertyManager::copy). + * + * Copies a single property from one mesh element to another (of the same type) + * + * @param _ph A face property handle + * @param _fh_from From face handle + * @param _fh_to To face handle + */ + template + void copy_property(FPropHandleT _ph, FaceHandle _fh_from, FaceHandle _fh_to) { + if(_fh_from.is_valid() && _fh_to.is_valid()) + fprops_.property(_ph)[_fh_to.idx()] = fprops_.property(_ph)[_fh_from.idx()]; + } + + +public: + //------------------------------------------------ copy all properties + + /** Copies all properties from one mesh element to another (of the same type) + * + * + * @param _vh_from A vertex handle - source + * @param _vh_to A vertex handle - target + * @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied? + */ + void copy_all_properties(VertexHandle _vh_from, VertexHandle _vh_to, bool _copyBuildIn = false) { + + for( PropertyContainer::iterator p_it = vprops_.begin(); + p_it != vprops_.end(); ++p_it) { + + // Copy all properties, if build in is true + // Otherwise, copy only properties without build in specifier + if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "v:" ) ) + (*p_it)->copy(_vh_from.idx(), _vh_to.idx()); + + } + } + + /** Copies all properties from one mesh element to another (of the same type) + * + * @param _hh_from A halfedge handle - source + * @param _hh_to A halfedge handle - target + * @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied? + */ + void copy_all_properties(HalfedgeHandle _hh_from, HalfedgeHandle _hh_to, bool _copyBuildIn = false) { + + for( PropertyContainer::iterator p_it = hprops_.begin(); + p_it != hprops_.end(); ++p_it) { + + // Copy all properties, if build in is true + // Otherwise, copy only properties without build in specifier + if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "h:") ) + (*p_it)->copy(_hh_from.idx(), _hh_to.idx()); + + } + } + + /** Copies all properties from one mesh element to another (of the same type) + * + * @param _eh_from An edge handle - source + * @param _eh_to An edge handle - target + * @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied? + */ + void copy_all_properties(EdgeHandle _eh_from, EdgeHandle _eh_to, bool _copyBuildIn = false) { + for( PropertyContainer::iterator p_it = eprops_.begin(); + p_it != eprops_.end(); ++p_it) { + + // Copy all properties, if build in is true + // Otherwise, copy only properties without build in specifier + if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "e:") ) + (*p_it)->copy(_eh_from.idx(), _eh_to.idx()); + + } + } + + /** Copies all properties from one mesh element to another (of the same type) + * + * @param _fh_from A face handle - source + * @param _fh_to A face handle - target + * @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied? + * + */ + void copy_all_properties(FaceHandle _fh_from, FaceHandle _fh_to, bool _copyBuildIn = false) { + + for( PropertyContainer::iterator p_it = fprops_.begin(); + p_it != fprops_.end(); ++p_it) { + + // Copy all properties, if build in is true + // Otherwise, copy only properties without build in specifier + if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "f:") ) + (*p_it)->copy(_fh_from.idx(), _fh_to.idx()); + } + + } + + /** + * @brief copy_all_kernel_properties uses the = operator to copy all properties from a given other BaseKernel. + * @param _other Another BaseKernel, to copy the properties from. + */ + void copy_all_kernel_properties(const BaseKernel & _other) + { + this->vprops_ = _other.vprops_; + this->eprops_ = _other.eprops_; + this->hprops_ = _other.hprops_; + this->fprops_ = _other.fprops_; + } + +protected: //------------------------------------------------- low-level access + +public: // used by non-native kernel and MeshIO, should be protected + + size_t n_vprops(void) const { return vprops_.size(); } + + size_t n_eprops(void) const { return eprops_.size(); } + + size_t n_hprops(void) const { return hprops_.size(); } + + size_t n_fprops(void) const { return fprops_.size(); } + + size_t n_mprops(void) const { return mprops_.size(); } + + BaseProperty* _get_vprop( const std::string& _name) + { return vprops_.property(_name); } + + BaseProperty* _get_eprop( const std::string& _name) + { return eprops_.property(_name); } + + BaseProperty* _get_hprop( const std::string& _name) + { return hprops_.property(_name); } + + BaseProperty* _get_fprop( const std::string& _name) + { return fprops_.property(_name); } + + BaseProperty* _get_mprop( const std::string& _name) + { return mprops_.property(_name); } + + const BaseProperty* _get_vprop( const std::string& _name) const + { return vprops_.property(_name); } + + const BaseProperty* _get_eprop( const std::string& _name) const + { return eprops_.property(_name); } + + const BaseProperty* _get_hprop( const std::string& _name) const + { return hprops_.property(_name); } + + const BaseProperty* _get_fprop( const std::string& _name) const + { return fprops_.property(_name); } + + const BaseProperty* _get_mprop( const std::string& _name) const + { return mprops_.property(_name); } + + BaseProperty& _vprop( size_t _idx ) { return vprops_._property( _idx ); } + BaseProperty& _eprop( size_t _idx ) { return eprops_._property( _idx ); } + BaseProperty& _hprop( size_t _idx ) { return hprops_._property( _idx ); } + BaseProperty& _fprop( size_t _idx ) { return fprops_._property( _idx ); } + BaseProperty& _mprop( size_t _idx ) { return mprops_._property( _idx ); } + + const BaseProperty& _vprop( size_t _idx ) const + { return vprops_._property( _idx ); } + const BaseProperty& _eprop( size_t _idx ) const + { return eprops_._property( _idx ); } + const BaseProperty& _hprop( size_t _idx ) const + { return hprops_._property( _idx ); } + const BaseProperty& _fprop( size_t _idx ) const + { return fprops_._property( _idx ); } + const BaseProperty& _mprop( size_t _idx ) const + { return mprops_._property( _idx ); } + + size_t _add_vprop( BaseProperty* _bp ) { return vprops_._add( _bp ); } + size_t _add_eprop( BaseProperty* _bp ) { return eprops_._add( _bp ); } + size_t _add_hprop( BaseProperty* _bp ) { return hprops_._add( _bp ); } + size_t _add_fprop( BaseProperty* _bp ) { return fprops_._add( _bp ); } + size_t _add_mprop( BaseProperty* _bp ) { return mprops_._add( _bp ); } + +protected: // low-level access non-public + + BaseProperty& _vprop( BaseHandle _h ) + { return vprops_._property( _h.idx() ); } + BaseProperty& _eprop( BaseHandle _h ) + { return eprops_._property( _h.idx() ); } + BaseProperty& _hprop( BaseHandle _h ) + { return hprops_._property( _h.idx() ); } + BaseProperty& _fprop( BaseHandle _h ) + { return fprops_._property( _h.idx() ); } + BaseProperty& _mprop( BaseHandle _h ) + { return mprops_._property( _h.idx() ); } + + const BaseProperty& _vprop( BaseHandle _h ) const + { return vprops_._property( _h.idx() ); } + const BaseProperty& _eprop( BaseHandle _h ) const + { return eprops_._property( _h.idx() ); } + const BaseProperty& _hprop( BaseHandle _h ) const + { return hprops_._property( _h.idx() ); } + const BaseProperty& _fprop( BaseHandle _h ) const + { return fprops_._property( _h.idx() ); } + const BaseProperty& _mprop( BaseHandle _h ) const + { return mprops_._property( _h.idx() ); } + + +public: //----------------------------------------------------- element numbers + + + virtual size_t n_vertices() const { return 0; } + virtual size_t n_halfedges() const { return 0; } + virtual size_t n_edges() const { return 0; } + virtual size_t n_faces() const { return 0; } + + +protected: //------------------------------------------- synchronize properties + + /// Reserves space for \p _n elements in all vertex property vectors. + void vprops_reserve(size_t _n) const { vprops_.reserve(_n); } + + /// Resizes all vertex property vectors to the specified size. + void vprops_resize(size_t _n) const { vprops_.resize(_n); } + + /** + * Same as vprops_resize() but ignores vertex property vectors that have + * a size larger than \p _n. + * + * Use this method instead of vprops_resize() if you plan to frequently reduce + * and enlarge the property container and you don't want to waste time + * reallocating the property vectors every time. + */ + void vprops_resize_if_smaller(size_t _n) const { vprops_.resize_if_smaller(_n); } + + void vprops_clear() { + vprops_.clear(); + } + + void vprops_swap(unsigned int _i0, unsigned int _i1) const { + vprops_.swap(_i0, _i1); + } + + void hprops_reserve(size_t _n) const { hprops_.reserve(_n); } + void hprops_resize(size_t _n) const { hprops_.resize(_n); } + void hprops_clear() { + hprops_.clear(); + } + void hprops_swap(unsigned int _i0, unsigned int _i1) const { + hprops_.swap(_i0, _i1); + } + + void eprops_reserve(size_t _n) const { eprops_.reserve(_n); } + void eprops_resize(size_t _n) const { eprops_.resize(_n); } + void eprops_clear() { + eprops_.clear(); + } + void eprops_swap(unsigned int _i0, unsigned int _i1) const { + eprops_.swap(_i0, _i1); + } + + void fprops_reserve(size_t _n) const { fprops_.reserve(_n); } + void fprops_resize(size_t _n) const { fprops_.resize(_n); } + void fprops_clear() { + fprops_.clear(); + } + void fprops_swap(unsigned int _i0, unsigned int _i1) const { + fprops_.swap(_i0, _i1); + } + + void mprops_resize(size_t _n) const { mprops_.resize(_n); } + void mprops_clear() { + mprops_.clear(); + } + +public: + + // uses std::clog as output stream + void property_stats() const; + void property_stats(std::ostream& _ostr) const; + + void vprop_stats( std::string& _string ) const; + void hprop_stats( std::string& _string ) const; + void eprop_stats( std::string& _string ) const; + void fprop_stats( std::string& _string ) const; + void mprop_stats( std::string& _string ) const; + + // uses std::clog as output stream + void vprop_stats() const; + void hprop_stats() const; + void eprop_stats() const; + void fprop_stats() const; + void mprop_stats() const; + + void vprop_stats(std::ostream& _ostr) const; + void hprop_stats(std::ostream& _ostr) const; + void eprop_stats(std::ostream& _ostr) const; + void fprop_stats(std::ostream& _ostr) const; + void mprop_stats(std::ostream& _ostr) const; + +public: + + typedef PropertyContainer::iterator prop_iterator; + typedef PropertyContainer::const_iterator const_prop_iterator; + + prop_iterator vprops_begin() { return vprops_.begin(); } + prop_iterator vprops_end() { return vprops_.end(); } + const_prop_iterator vprops_begin() const { return vprops_.begin(); } + const_prop_iterator vprops_end() const { return vprops_.end(); } + + prop_iterator eprops_begin() { return eprops_.begin(); } + prop_iterator eprops_end() { return eprops_.end(); } + const_prop_iterator eprops_begin() const { return eprops_.begin(); } + const_prop_iterator eprops_end() const { return eprops_.end(); } + + prop_iterator hprops_begin() { return hprops_.begin(); } + prop_iterator hprops_end() { return hprops_.end(); } + const_prop_iterator hprops_begin() const { return hprops_.begin(); } + const_prop_iterator hprops_end() const { return hprops_.end(); } + + prop_iterator fprops_begin() { return fprops_.begin(); } + prop_iterator fprops_end() { return fprops_.end(); } + const_prop_iterator fprops_begin() const { return fprops_.begin(); } + const_prop_iterator fprops_end() const { return fprops_.end(); } + + prop_iterator mprops_begin() { return mprops_.begin(); } + prop_iterator mprops_end() { return mprops_.end(); } + const_prop_iterator mprops_begin() const { return mprops_.begin(); } + const_prop_iterator mprops_end() const { return mprops_.end(); } + +private: + + PropertyContainer vprops_; + PropertyContainer hprops_; + PropertyContainer eprops_; + PropertyContainer fprops_; + PropertyContainer mprops_; +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_BASE_KERNEL_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/BaseMesh.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/BaseMesh.hh new file mode 100644 index 0000000..bcf75eb --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/BaseMesh.hh @@ -0,0 +1,97 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS BaseMesh +// +//============================================================================= + + +#ifndef OPENMESH_BASEMESH_HH +#define OPENMESH_BASEMESH_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/** \class BaseMesh BaseMesh.hh + + Base class for all meshes. +*/ + +class BaseMesh { +public: + virtual ~BaseMesh(void) {;} +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= +#endif // OPENMESH_BASEMESH_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/Casts.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Casts.hh new file mode 100644 index 0000000..136c16f --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Casts.hh @@ -0,0 +1,77 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_CASTS_HH +#define OPENMESH_CASTS_HH +//== INCLUDES ================================================================= + +#include +#include + +//== NAMESPACES =============================================================== +namespace OpenMesh +{ + +template +inline TriMesh_ArrayKernelT& TRIMESH_CAST(PolyMesh_ArrayKernelT& _poly_mesh) +{ return reinterpret_cast< TriMesh_ArrayKernelT& >(_poly_mesh); } + +template +inline const TriMesh_ArrayKernelT& TRIMESH_CAST(const PolyMesh_ArrayKernelT& _poly_mesh) +{ return reinterpret_cast< const TriMesh_ArrayKernelT& >(_poly_mesh); } + +template +inline PolyMesh_ArrayKernelT& POLYMESH_CAST(TriMesh_ArrayKernelT& _tri_mesh) +{ return reinterpret_cast< PolyMesh_ArrayKernelT& >(_tri_mesh); } + +template +inline const PolyMesh_ArrayKernelT& POLYMESH_CAST(const TriMesh_ArrayKernelT& _tri_mesh) +{ return reinterpret_cast< const PolyMesh_ArrayKernelT& >(_tri_mesh); } + +}; +#endif//OPENMESH_CASTS_HH diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/CirculatorsT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/CirculatorsT.hh new file mode 100644 index 0000000..0656059 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -0,0 +1,598 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_CIRCULATORS_HH +#define OPENMESH_CIRCULATORS_HH +//============================================================================= +// +// Vertex and Face circulators for PolyMesh/TriMesh +// +//============================================================================= + + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace Iterators { + +template +class GenericCirculator_CenterEntityFnsT { + public: + static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter); + static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter); +}; + +template +class GenericCirculator_CenterEntityFnsT { + public: + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + heh = mesh->cw_rotated_halfedge_handle(heh); + if (heh == start) ++lap_counter; + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + if (heh == start) --lap_counter; + heh = mesh->ccw_rotated_halfedge_handle(heh); + } +}; + +template +class GenericCirculator_CenterEntityFnsT { + public: + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + heh = mesh->next_halfedge_handle(heh); + if (heh == start) ++lap_counter; + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + if (heh == start) --lap_counter; + heh = mesh->prev_halfedge_handle(heh); + } +}; + +///////////////////////////////////////////////////////////// +// CCW + +template +class GenericCirculator_CenterEntityFnsT { + public: + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + heh = mesh->ccw_rotated_halfedge_handle(heh); + if (heh == start) ++lap_counter; + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + if (heh == start) --lap_counter; + heh = mesh->cw_rotated_halfedge_handle(heh); + } +}; + +template +class GenericCirculator_CenterEntityFnsT { + public: + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + heh = mesh->prev_halfedge_handle(heh); + if (heh == start) ++lap_counter; + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + if (heh == start) --lap_counter; + heh = mesh->next_halfedge_handle(heh); + } +}; +///////////////////////////////////////////////////////////// + +template +class GenericCirculator_DereferenciabilityCheckT { + public: + //inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int &lap_counter); +}; + +template +class GenericCirculator_DereferenciabilityCheckT { + public: + inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) { + return mesh->face_handle(mesh->opposite_halfedge_handle(heh)).is_valid(); + } +}; + +template +class GenericCirculator_DereferenciabilityCheckT { + public: + inline static bool isDereferenciable(const Mesh *mesh, const typename Mesh::HalfedgeHandle &heh) { + return mesh->face_handle(heh).is_valid(); + } +}; + +template +class GenericCirculator_ValueHandleFnsT { + public: + inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) { + return ( heh.is_valid() && (lap_counter == 0 ) ); + } + inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {}; + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + GenericCirculator_CenterEntityFnsT::increment(mesh, heh, start, lap_counter); + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + GenericCirculator_CenterEntityFnsT::decrement(mesh, heh, start, lap_counter); + } +}; + +template +class GenericCirculator_ValueHandleFnsT { + public: + typedef GenericCirculator_DereferenciabilityCheckT GenericCirculator_DereferenciabilityCheck; + + inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const int lap_counter) { + return ( heh.is_valid() && (lap_counter == 0)); + } + inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 ) + increment(mesh, heh, start, lap_counter); + }; + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + do { + GenericCirculator_CenterEntityFnsT::increment(mesh, heh, start, lap_counter); + } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh)); + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + do { + GenericCirculator_CenterEntityFnsT::decrement(mesh, heh, start, lap_counter); + } while (is_valid(heh, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh)); + } +}; + +template +class GenericCirculatorBaseT { + public: + typedef const Mesh* mesh_ptr; + typedef const Mesh& mesh_ref; + + public: + GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {} + + GenericCirculatorBaseT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) : + mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast(end && heh.is_valid())) {} + + GenericCirculatorBaseT(const GenericCirculatorBaseT &rhs) : + mesh_(rhs.mesh_), start_(rhs.start_), heh_(rhs.heh_), lap_counter_(rhs.lap_counter_) {} + + inline typename Mesh::FaceHandle toFaceHandle() const { + return mesh_->face_handle(heh_); + } + + inline typename Mesh::FaceHandle toOppositeFaceHandle() const { + return mesh_->face_handle(toOppositeHalfedgeHandle()); + } + + inline typename Mesh::EdgeHandle toEdgeHandle() const { + return mesh_->edge_handle(heh_); + } + + inline typename Mesh::HalfedgeHandle toHalfedgeHandle() const { + return heh_; + } + + inline typename Mesh::HalfedgeHandle toOppositeHalfedgeHandle() const { + return mesh_->opposite_halfedge_handle(heh_); + } + + inline typename Mesh::VertexHandle toVertexHandle() const { + return mesh_->to_vertex_handle(heh_); + } + + inline GenericCirculatorBaseT &operator=(const GenericCirculatorBaseT &rhs) { + mesh_ = rhs.mesh_; + start_ = rhs.start_; + heh_ = rhs.heh_; + lap_counter_ = rhs.lap_counter_; + return *this; + } + + inline bool operator==(const GenericCirculatorBaseT &rhs) const { + return mesh_ == rhs.mesh_ && start_ == rhs.start_ && heh_ == rhs.heh_ && lap_counter_ == rhs.lap_counter_; + } + + inline bool operator!=(const GenericCirculatorBaseT &rhs) const { + return !operator==(rhs); + } + + protected: + mesh_ptr mesh_; + typename Mesh::HalfedgeHandle start_, heh_; + int lap_counter_; +}; + +template::*Handle2Value)() const, bool CW = true > +class GenericCirculatorT : protected GenericCirculatorBaseT { + public: + typedef std::ptrdiff_t difference_type; + typedef ValueHandle value_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename GenericCirculatorBaseT::mesh_ptr mesh_ptr; + typedef typename GenericCirculatorBaseT::mesh_ref mesh_ref; + typedef GenericCirculator_ValueHandleFnsT GenericCirculator_ValueHandleFns; + + public: + GenericCirculatorT() {} + GenericCirculatorT(mesh_ref mesh, CenterEntityHandle start, bool end = false) : + GenericCirculatorBaseT(mesh, mesh.halfedge_handle(start), end) { + + GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); + } + GenericCirculatorT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) : + GenericCirculatorBaseT(mesh, heh, end) { + + GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); + } + GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT(rhs) {} + + friend class GenericCirculatorT; + explicit GenericCirculatorT( const GenericCirculatorT& rhs ) + :GenericCirculatorBaseT(rhs){} + + GenericCirculatorT& operator++() { + assert(this->mesh_); + GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_); + return *this; + } + GenericCirculatorT& operator--() { + assert(this->mesh_); + GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_); + return *this; + } + + /// Post-increment + GenericCirculatorT operator++(int) { + assert(this->mesh_); + GenericCirculatorT cpy(*this); + ++(*this); + return cpy; + } + + /// Post-decrement + GenericCirculatorT operator--(int) { + assert(this->mesh_); + GenericCirculatorT cpy(*this); + --(*this); + return cpy; + } + + /// Standard dereferencing operator. + value_type operator*() const { + // We can't use this due to a GCC6 compiler bug + const GenericCirculatorBaseT* self = this; +#ifndef NDEBUG + assert(this->heh_.is_valid()); + value_type res = (self->*Handle2Value)(); + assert(res.is_valid()); + return res; +#else + return (self->*Handle2Value)(); +#endif + } + + /** + * @brief Pointer dereferentiation. + * + * This returns a pointer which points to a handle + * that loses its validity once this dereferentiation is + * invoked again. Thus, do not store the result of + * this operation. + */ + pointer operator->() const { + pointer_deref_value = **this; + return &pointer_deref_value; + } + + GenericCirculatorT &operator=(const GenericCirculatorT &rhs) { + GenericCirculatorBaseT::operator=(rhs); + return *this; + }; + + bool operator==(const GenericCirculatorT &rhs) const { + return GenericCirculatorBaseT::operator==(rhs); + } + + bool operator!=(const GenericCirculatorT &rhs) const { + return GenericCirculatorBaseT::operator!=(rhs); + } + + bool is_valid() const { + return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->lap_counter_); + } + + template + friend STREAM &operator<< (STREAM &s, const GenericCirculatorT &self) { + return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_; + } + + private: + mutable value_type pointer_deref_value; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// OLD /////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OLD CIRCULATORS +// deprecated circulators, will be removed soon +// if you remove these circulators and go to the old ones, PLEASE ENABLE FOLLOWING UNITTESTS: +// +// OpenMeshTrimeshCirculatorVertexIHalfEdge.VertexIHalfEdgeIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorVertexEdge.VertexEdgeIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorVertexVertex.VertexVertexIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorVertexOHalfEdge.VertexOHalfEdgeIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorVertexFace.VertexFaceIterWithoutHolesDecrement +// OpenMeshTrimeshCirculatorFaceEdge.FaceEdgeIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorFaceFace.FaceFaceIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterWithoutHolesIncrement +// OpenMeshTrimeshCirculatorFaceVertex.FaceVertexIterCheckInvalidationAtEnds +// OpenMeshTrimeshCirculatorFaceHalfEdge.FaceHalfedgeIterCheckInvalidationAtEnds +// + +template +class GenericCirculator_ValueHandleFnsT_DEPRECATED { + public: + inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh,const typename Mesh::HalfedgeHandle &start, const int lap_counter) { + return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 )) ); + } + inline static void init(const Mesh*, typename Mesh::HalfedgeHandle&, typename Mesh::HalfedgeHandle&, int&) {}; + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + GenericCirculator_CenterEntityFnsT::increment(mesh, heh, start, lap_counter); + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + GenericCirculator_CenterEntityFnsT::decrement(mesh, heh, start, lap_counter); + } +}; + +template +class GenericCirculator_ValueHandleFnsT_DEPRECATED { + public: + typedef GenericCirculator_DereferenciabilityCheckT GenericCirculator_DereferenciabilityCheck; + + inline static bool is_valid(const typename Mesh::HalfedgeHandle &heh, const typename Mesh::HalfedgeHandle &start, const int lap_counter) { + return ( heh.is_valid() && ((start != heh) || (lap_counter == 0 ))); + } + inline static void init(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + if (heh.is_valid() && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh) && lap_counter == 0 ) + increment(mesh, heh, start, lap_counter); + }; + inline static void increment(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + do { + GenericCirculator_CenterEntityFnsT::increment(mesh, heh, start, lap_counter); + } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh)); + } + inline static void decrement(const Mesh *mesh, typename Mesh::HalfedgeHandle &heh, typename Mesh::HalfedgeHandle &start, int &lap_counter) { + do { + GenericCirculator_CenterEntityFnsT::decrement(mesh, heh, start, lap_counter); + } while (is_valid(heh, start, lap_counter) && !GenericCirculator_DereferenciabilityCheck::isDereferenciable(mesh, heh)); + } +}; + +template::*Handle2Value)() const> +class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { + public: + typedef std::ptrdiff_t difference_type; + typedef ValueHandle value_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename GenericCirculatorBaseT::mesh_ptr mesh_ptr; + typedef typename GenericCirculatorBaseT::mesh_ref mesh_ref; + typedef GenericCirculator_ValueHandleFnsT_DEPRECATED GenericCirculator_ValueHandleFns; + + public: + GenericCirculatorT_DEPRECATED() {} + GenericCirculatorT_DEPRECATED(mesh_ref mesh, CenterEntityHandle start, bool end = false) : + GenericCirculatorBaseT(mesh, mesh.halfedge_handle(start), end) { + + GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); + } + GenericCirculatorT_DEPRECATED(mesh_ref mesh, HalfedgeHandle heh, bool end = false) : + GenericCirculatorBaseT(mesh, heh, end) { + + GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_); + } + GenericCirculatorT_DEPRECATED(const GenericCirculatorT_DEPRECATED &rhs) : GenericCirculatorBaseT(rhs) {} + + GenericCirculatorT_DEPRECATED& operator++() { + assert(this->mesh_); + GenericCirculator_ValueHandleFns::increment(this->mesh_, this->heh_, this->start_, this->lap_counter_); + return *this; + } +#ifndef NO_DECREMENT_DEPRECATED_WARNINGS +#define DECREMENT_DEPRECATED_WARNINGS_TEXT "The current decrement operator has the unintended behavior that it stays\ + valid when iterating below the start and will visit the first entity\ + twice before getting invalid. Furthermore it gets valid again, if you\ + increment at the end.\ + When you are sure that you don't iterate below the start anywhere in\ + your code or rely on this behaviour, you can disable this warning by\ + setting the define NO_DECREMENT_DEPRECATED_WARNINGS at the command line (or enable it via the\ + cmake flags).\ + To be save, you can use the CW/CCW circulator definitions, which behave\ + the same as the original ones, without the previously mentioned issues." + + DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) +#endif // NO_DECREMENT_DEPRECATED_WARNINGS + GenericCirculatorT_DEPRECATED& operator--() { + assert(this->mesh_); + GenericCirculator_ValueHandleFns::decrement(this->mesh_, this->heh_, this->start_, this->lap_counter_); + return *this; + } + + /// Post-increment + GenericCirculatorT_DEPRECATED operator++(int) { + assert(this->mesh_); + GenericCirculatorT_DEPRECATED cpy(*this); + ++(*this); + return cpy; + } + + /// Post-decrement +#ifndef NO_DECREMENT_DEPRECATED_WARNINGS + DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT ) +#undef DECREMENT_DEPRECATED_WARNINGS_TEXT +#endif //NO_DECREMENT_DEPRECATED_WARNINGS + GenericCirculatorT_DEPRECATED operator--(int) { + assert(this->mesh_); + GenericCirculatorT_DEPRECATED cpy(*this); + --(*this); + return cpy; + } + + /// Standard dereferencing operator. + value_type operator*() const { + // We can't use this due to a GCC6 compiler bug + const GenericCirculatorBaseT* self = this; +#ifndef NDEBUG + assert(this->heh_.is_valid()); + value_type res = (self->*Handle2Value)(); + assert(res.is_valid()); + return res; +#else + return (self->*Handle2Value)(); +#endif + } + + /** + * @brief Pointer dereferentiation. + * + * This returns a pointer which points to a handle + * that loses its validity once this dereferentiation is + * invoked again. Thus, do not store the result of + * this operation. + */ + pointer operator->() const { + pointer_deref_value = **this; + return &pointer_deref_value; + } + + GenericCirculatorT_DEPRECATED &operator=(const GenericCirculatorT_DEPRECATED &rhs) { + GenericCirculatorBaseT::operator=(rhs); + return *this; + }; + + bool operator==(const GenericCirculatorT_DEPRECATED &rhs) const { + return GenericCirculatorBaseT::operator==(rhs); + } + + bool operator!=(const GenericCirculatorT_DEPRECATED &rhs) const { + return GenericCirculatorBaseT::operator!=(rhs); + } + + bool is_valid() const { + 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.") + /** + * \deprecated + * current_halfedge_handle() is an implementation detail and should not + * be accessed from outside the iterator class. + */ + const HalfedgeHandle ¤t_halfedge_handle() const { + return this->heh_; + } + + DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.") + /** + * \deprecated + * Do not use this error prone implicit cast. Compare to the + * end-iterator or use is_valid() instead. + */ + operator bool() const { + return is_valid(); + } + + /** + * \brief Return the handle of the current target. + * \deprecated + * This function clutters your code. Use dereferencing operators -> and * instead. + */ + DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") + value_type handle() const { + return **this; + } + + /** + * \brief Cast to the handle of the current target. + * \deprecated + * Implicit casts of iterators are unsafe. Use dereferencing operators + * -> and * instead. + */ + DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") + operator value_type() const { + return **this; + } + + template + friend STREAM &operator<< (STREAM &s, const GenericCirculatorT_DEPRECATED &self) { + return s << self.mesh_ << ", " << self.start_.idx() << ", " << self.heh_.idx() << ", " << self.lap_counter_; + } + + private: + mutable value_type pointer_deref_value; +}; + +} // namespace Iterators +} // namespace OpenMesh + +#endif diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/FinalMeshItemsT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/FinalMeshItemsT.hh new file mode 100644 index 0000000..cbed2e5 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/FinalMeshItemsT.hh @@ -0,0 +1,227 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_MESH_ITEMS_HH +#define OPENMESH_MESH_ITEMS_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + +/// Definition of the mesh entities (items). +template +struct FinalMeshItemsT +{ + //--- build Refs structure --- +#ifndef DOXY_IGNORE_THIS + struct Refs + { + typedef typename Traits::Point Point; + typedef typename vector_traits::value_type Scalar; + + typedef typename Traits::Normal Normal; + typedef typename Traits::Color Color; + typedef typename Traits::TexCoord1D TexCoord1D; + typedef typename Traits::TexCoord2D TexCoord2D; + typedef typename Traits::TexCoord3D TexCoord3D; + typedef typename Traits::TextureIndex TextureIndex; + typedef OpenMesh::VertexHandle VertexHandle; + typedef OpenMesh::FaceHandle FaceHandle; + typedef OpenMesh::EdgeHandle EdgeHandle; + typedef OpenMesh::HalfedgeHandle HalfedgeHandle; + }; +#endif + //--- export Refs types --- + typedef typename Refs::Point Point; + typedef typename Refs::Scalar Scalar; + typedef typename Refs::Normal Normal; + typedef typename Refs::Color Color; + typedef typename Refs::TexCoord1D TexCoord1D; + typedef typename Refs::TexCoord2D TexCoord2D; + typedef typename Refs::TexCoord3D TexCoord3D; + typedef typename Refs::TextureIndex TextureIndex; + + //--- get attribute bits from Traits --- + enum Attribs + { + VAttribs = Traits::VertexAttributes, + HAttribs = Traits::HalfedgeAttributes, + EAttribs = Traits::EdgeAttributes, + FAttribs = Traits::FaceAttributes + }; + //--- merge internal items with traits items --- + + +/* + typedef typename GenProg::IF< + (bool)(HAttribs & Attributes::PrevHalfedge), + typename InternalItems::Halfedge_with_prev, + typename InternalItems::Halfedge_without_prev + >::Result InternalHalfedge; +*/ + //typedef typename InternalItems::Vertex InternalVertex; + //typedef typename InternalItems::template Edge InternalEdge; + //typedef typename InternalItems::template Face InternalFace; + class ITraits + {}; + + typedef typename Traits::template VertexT VertexData; + typedef typename Traits::template HalfedgeT HalfedgeData; + typedef typename Traits::template EdgeT EdgeData; + typedef typename Traits::template FaceT FaceData; +}; + + +#ifndef DOXY_IGNORE_THIS +namespace { +namespace TM { +template struct TypeEquality; +template struct TypeEquality {}; + +template struct ItemsEquality { + TypeEquality te1; + TypeEquality te2; + TypeEquality te3; + TypeEquality te4; + TypeEquality te5; + TypeEquality te6; + TypeEquality te7; + TypeEquality te8; +}; + +} /* namespace TM */ +} /* anonymous namespace */ +#endif + +/** + * @brief Cast a mesh with different but identical traits into each other. + * + * Note that there exists a syntactically more convenient global method + * mesh_cast(). + * + * Example: + * @code{.cpp} + * struct TriTraits1 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * }; + * struct TriTraits2 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * }; + * struct TriTraits3 : public OpenMesh::DefaultTraits { + * typedef Vec3f Point; + * }; + * + * TriMesh_ArrayKernelT a; + * TriMesh_ArrayKernelT &b = MeshCast&, TriMesh_ArrayKernelT&>::cast(a); // OK + * TriMesh_ArrayKernelT &c = MeshCast&, TriMesh_ArrayKernelT&>::cast(a); // ERROR + * @endcode + * + * @see mesh_cast() + * + * @param rhs + * @return + */ +template struct MeshCast; + +template +struct MeshCast { + static LhsMeshT &cast(RhsMeshT &rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + +template +struct MeshCast { + static const LhsMeshT &cast(const RhsMeshT &rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + +template +struct MeshCast { + static LhsMeshT *cast(RhsMeshT *rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + +template +struct MeshCast { + static const LhsMeshT *cast(const RhsMeshT *rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESH_ITEMS_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/Handles.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Handles.hh new file mode 100644 index 0000000..68ac1d7 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Handles.hh @@ -0,0 +1,238 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_HANDLES_HH +#define OPENMESH_HANDLES_HH + + +//== INCLUDES ================================================================= + +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== CLASS DEFINITION ========================================================= + + +/// Base class for all handle types +class BaseHandle +{ +public: + + explicit BaseHandle(int _idx=-1) : idx_(_idx) {} + + /// Get the underlying index of this handle + int idx() const { return idx_; } + + /// The handle is valid iff the index is not negative. + bool is_valid() const { return idx_ >= 0; } + + /// reset handle to be invalid + void reset() { idx_=-1; } + /// reset handle to be invalid + void invalidate() { idx_ = -1; } + + bool operator==(const BaseHandle& _rhs) const { + return (this->idx_ == _rhs.idx_); + } + + bool operator!=(const BaseHandle& _rhs) const { + return (this->idx_ != _rhs.idx_); + } + + bool operator<(const BaseHandle& _rhs) const { + return (this->idx_ < _rhs.idx_); + } + + + // this is to be used only by the iterators + void __increment() { ++idx_; } + void __decrement() { --idx_; } + + void __increment(int amount) { idx_ += amount; } + void __decrement(int amount) { idx_ -= amount; } + +private: + + int idx_; +}; + +// this is used by boost::unordered_set/map +inline size_t hash_value(const BaseHandle& h) { return h.idx(); } + +//----------------------------------------------------------------------------- + +/// Write handle \c _hnd to stream \c _os +inline std::ostream& operator<<(std::ostream& _os, const BaseHandle& _hnd) +{ + return (_os << _hnd.idx()); +} + + +//----------------------------------------------------------------------------- + + +/// Handle for a vertex entity +struct VertexHandle : public BaseHandle +{ + explicit VertexHandle(int _idx=-1) : BaseHandle(_idx) {} +}; + + +/// Handle for a halfedge entity +struct HalfedgeHandle : public BaseHandle +{ + explicit HalfedgeHandle(int _idx=-1) : BaseHandle(_idx) {} +}; + + +/// Handle for a edge entity +struct EdgeHandle : public BaseHandle +{ + explicit EdgeHandle(int _idx=-1) : BaseHandle(_idx) {} +}; + + +/// Handle for a face entity +struct FaceHandle : public BaseHandle +{ + explicit FaceHandle(int _idx=-1) : BaseHandle(_idx) {} +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +#ifdef OM_HAS_HASH +#include +namespace std { + +#if defined(_MSVC_VER) +# pragma warning(push) +# pragma warning(disable:4099) // For VC++ it is class hash +#endif + + +template <> +struct hash +{ + typedef OpenMesh::BaseHandle argument_type; + typedef std::size_t result_type; + + std::size_t operator()(const OpenMesh::BaseHandle& h) const + { + return h.idx(); + } +}; + +template <> +struct hash +{ + typedef OpenMesh::VertexHandle argument_type; + typedef std::size_t result_type; + + std::size_t operator()(const OpenMesh::VertexHandle& h) const + { + return h.idx(); + } +}; + +template <> +struct hash +{ + + typedef OpenMesh::HalfedgeHandle argument_type; + typedef std::size_t result_type; + + std::size_t operator()(const OpenMesh::HalfedgeHandle& h) const + { + return h.idx(); + } +}; + +template <> +struct hash +{ + + typedef OpenMesh::EdgeHandle argument_type; + typedef std::size_t result_type; + + std::size_t operator()(const OpenMesh::EdgeHandle& h) const + { + return h.idx(); + } +}; + +template <> +struct hash +{ + + typedef OpenMesh::FaceHandle argument_type; + typedef std::size_t result_type; + + std::size_t operator()(const OpenMesh::FaceHandle& h) const + { + return h.idx(); + } +}; + +#if defined(_MSVC_VER) +# pragma warning(pop) +#endif + +} +#endif // OM_HAS_HASH + + +#endif // OPENMESH_HANDLES_HH +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/IteratorsT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/IteratorsT.hh new file mode 100644 index 0000000..6d2c92b --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/IteratorsT.hh @@ -0,0 +1,259 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_ITERATORS_HH +#define OPENMESH_ITERATORS_HH + +//============================================================================= +// +// Iterators for PolyMesh/TriMesh +// +//============================================================================= + + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace Iterators { + + +//== FORWARD DECLARATIONS ===================================================== + + +template class ConstVertexIterT; +template class VertexIterT; +template class ConstHalfedgeIterT; +template class HalfedgeIterT; +template class ConstEdgeIterT; +template class EdgeIterT; +template class ConstFaceIterT; +template class FaceIterT; + + +template +class GenericIteratorT { + public: + //--- Typedefs --- + + typedef ValueHandle value_handle; + typedef value_handle value_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + typedef const value_type& reference; + typedef const value_type* pointer; + typedef const Mesh* mesh_ptr; + typedef const Mesh& mesh_ref; + + /// Default constructor. + GenericIteratorT() + : mesh_(0), skip_bits_(0) + {} + + /// Construct with mesh and a target handle. + GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) + : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) + { + if (_skip) enable_skipping(); + } + + /// Standard dereferencing operator. + reference operator*() const { + return hnd_; + } + + /// Standard pointer operator. + pointer operator->() const { + return &hnd_; + } + + /** + * \brief Get the handle of the item the iterator refers to. + * \deprecated + * This function clutters your code. Use dereferencing operators -> and * instead. + */ + DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") + value_handle handle() const { + return hnd_; + } + + /** + * \brief Cast to the handle of the item the iterator refers to. + * \deprecated + * Implicit casts of iterators are unsafe. Use dereferencing operators + * -> and * instead. + */ + DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.") + operator value_handle() const { + return hnd_; + } + + /// Are two iterators equal? Only valid if they refer to the same mesh! + bool operator==(const GenericIteratorT& _rhs) const { + return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); + } + + /// Not equal? + bool operator!=(const GenericIteratorT& _rhs) const { + return !operator==(_rhs); + } + + /// Standard pre-increment operator + GenericIteratorT& operator++() { + hnd_.__increment(); + if (skip_bits_) + skip_fwd(); + return *this; + } + + /// Standard post-increment operator + GenericIteratorT operator++(int) { + GenericIteratorT cpy(*this); + ++(*this); + return cpy; + } + +#if ((defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY) + template + auto operator+=(int amount) -> + typename std::enable_if< + sizeof(decltype(std::declval().__increment(amount))) >= 0, + GenericIteratorT&>::type { + static_assert(std::is_same::value, + "Template parameter must not deviate from default."); + if (skip_bits_) + throw std::logic_error("Skipping iterators do not support " + "random access."); + hnd_.__increment(amount); + return *this; + } + + template + auto operator+(int rhs) -> + typename std::enable_if< + sizeof(decltype(std::declval().__increment(rhs), void (), int {})) >= 0, + GenericIteratorT>::type { + static_assert(std::is_same::value, + "Template parameter must not deviate from default."); + if (skip_bits_) + throw std::logic_error("Skipping iterators do not support " + "random access."); + GenericIteratorT result = *this; + result.hnd_.__increment(rhs); + return result; + } +#endif + + /// Standard pre-decrement operator + GenericIteratorT& operator--() { + hnd_.__decrement(); + if (skip_bits_) + skip_bwd(); + return *this; + } + + /// Standard post-decrement operator + GenericIteratorT operator--(int) { + GenericIteratorT cpy(*this); + --(*this); + return cpy; + } + + /// Turn on skipping: automatically skip deleted/hidden elements + void enable_skipping() { + if (mesh_ && (mesh_->*PrimitiveStatusMember)()) { + Attributes::StatusInfo status; + status.set_deleted(true); + status.set_hidden(true); + skip_bits_ = status.bits(); + skip_fwd(); + } else + skip_bits_ = 0; + } + + /// Turn on skipping: automatically skip deleted/hidden elements + void disable_skipping() { + skip_bits_ = 0; + } + + private: + + void skip_fwd() { + assert(mesh_ && skip_bits_); + while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)()) + && (mesh_->status(hnd_).bits() & skip_bits_)) + hnd_.__increment(); + } + + void skip_bwd() { + assert(mesh_ && skip_bits_); + while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) + hnd_.__decrement(); + } + + protected: + mesh_ptr mesh_; + value_handle hnd_; + unsigned int skip_bits_; +}; + +//============================================================================= +} // namespace Iterators +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyConnectivity.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyConnectivity.hh new file mode 100644 index 0000000..d2ce667 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -0,0 +1,1635 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_POLYCONNECTIVITY_HH +#define OPENMESH_POLYCONNECTIVITY_HH + +#include +#include +#include + +namespace OpenMesh +{ + +/** \brief Connectivity Class for polygonal meshes +*/ +class OPENMESHDLLEXPORT PolyConnectivity : public ArrayKernel +{ +public: + /// \name Mesh Handles + //@{ + /// Invalid handle + static const VertexHandle InvalidVertexHandle; + /// Invalid handle + static const HalfedgeHandle InvalidHalfedgeHandle; + /// Invalid handle + static const EdgeHandle InvalidEdgeHandle; + /// Invalid handle + static const FaceHandle InvalidFaceHandle; + //@} + + typedef PolyConnectivity This; + + //--- iterators --- + + /** \name Mesh Iterators + Refer to OpenMesh::Mesh::Iterators or \ref mesh_iterators for + documentation. + */ + //@{ + /// Linear iterator + typedef Iterators::GenericIteratorT VertexIter; + typedef Iterators::GenericIteratorT HalfedgeIter; + typedef Iterators::GenericIteratorT EdgeIter; + typedef Iterators::GenericIteratorT FaceIter; + + typedef VertexIter ConstVertexIter; + typedef HalfedgeIter ConstHalfedgeIter; + typedef EdgeIter ConstEdgeIter; + typedef FaceIter ConstFaceIter; + //@} + + //--- circulators --- + + /** \name Mesh Circulators + Refer to OpenMesh::Mesh::Iterators or \ref mesh_iterators + for documentation. + */ + //@{ + + /* + * Vertex-centered circulators + */ + + /** + * Enumerates 1-ring vertices in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toVertexHandle> + VertexVertexIter; + typedef Iterators::GenericCirculatorT::toVertexHandle> VertexVertexCWIter; + + /** + * Enumerates 1-ring vertices in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toVertexHandle, false> + VertexVertexCCWIter; + + /** + * Enumerates outgoing half edges in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> + VertexOHalfedgeIter; + typedef Iterators::GenericCirculatorT::toHalfedgeHandle> VertexOHalfedgeCWIter; + + /** + * Enumerates outgoing half edges in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> + VertexOHalfedgeCCWIter; + + /** + * Enumerates incoming half edges in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toOppositeHalfedgeHandle> + VertexIHalfedgeIter; + typedef Iterators::GenericCirculatorT::toOppositeHalfedgeHandle> VertexIHalfedgeCWIter; + + /** + * Enumerates incoming half edges in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toOppositeHalfedgeHandle, false> + VertexIHalfedgeCCWIter; + + /** + * Enumerates incident faces in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toFaceHandle> + VertexFaceIter; + typedef Iterators::GenericCirculatorT::toFaceHandle> VertexFaceCWIter; + + /** + * Enumerates incident faces in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toFaceHandle, false> + VertexFaceCCWIter; + + /** + * Enumerates incident edges in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toEdgeHandle> + VertexEdgeIter; + typedef Iterators::GenericCirculatorT::toEdgeHandle> VertexEdgeCWIter; + /** + * Enumerates incident edges in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toEdgeHandle, false> + VertexEdgeCCWIter; + + /** + * Identical to #FaceHalfedgeIter. God knows why this typedef exists. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> + HalfedgeLoopIter; + typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> HalfedgeLoopCWIter; + /** + * Identical to #FaceHalfedgeIter. God knows why this typedef exists. + */ + typedef Iterators::GenericCirculatorT::toHalfedgeHandle> + HalfedgeLoopCCWIter; + + typedef VertexVertexIter ConstVertexVertexIter; + typedef VertexVertexCWIter ConstVertexVertexCWIter; + typedef VertexVertexCCWIter ConstVertexVertexCCWIter; + typedef VertexOHalfedgeIter ConstVertexOHalfedgeIter; + typedef VertexOHalfedgeCWIter ConstVertexOHalfedgeCWIter; + typedef VertexOHalfedgeCCWIter ConstVertexOHalfedgeCCWIter; + typedef VertexIHalfedgeIter ConstVertexIHalfedgeIter; + typedef VertexIHalfedgeCWIter ConstVertexIHalfedgeCWIter; + typedef VertexIHalfedgeCCWIter ConstVertexIHalfedgeCCWIter; + typedef VertexFaceIter ConstVertexFaceIter; + typedef VertexFaceCWIter ConstVertexFaceCWIter; + typedef VertexFaceCCWIter ConstVertexFaceCCWIter; + typedef VertexEdgeIter ConstVertexEdgeIter; + typedef VertexEdgeCWIter ConstVertexEdgeCWIter; + typedef VertexEdgeCCWIter ConstVertexEdgeCCWIter; + + /* + * Face-centered circulators + */ + + /** + * Enumerate incident vertices in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toVertexHandle> + FaceVertexIter; + typedef Iterators::GenericCirculatorT::toVertexHandle> FaceVertexCCWIter; + + /** + * Enumerate incident vertices in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toVertexHandle, false> + FaceVertexCWIter; + + /** + * Enumerate incident half edges in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> + FaceHalfedgeIter; + typedef Iterators::GenericCirculatorT::toHalfedgeHandle> FaceHalfedgeCCWIter; + + /** + * Enumerate incident half edges in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> + FaceHalfedgeCWIter; + + /** + * Enumerate incident edges in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toEdgeHandle> + FaceEdgeIter; + typedef Iterators::GenericCirculatorT::toEdgeHandle> FaceEdgeCCWIter; + + /** + * Enumerate incident edges in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toEdgeHandle, false> + FaceEdgeCWIter; + + /** + * Enumerate adjacent faces in a counter clockwise fashion. + */ + typedef Iterators::GenericCirculatorT_DEPRECATED::toOppositeFaceHandle> + FaceFaceIter; + typedef Iterators::GenericCirculatorT::toOppositeFaceHandle> FaceFaceCCWIter; + + /** + * Enumerate adjacent faces in a clockwise fashion. + */ + typedef Iterators::GenericCirculatorT::toOppositeFaceHandle, false> + FaceFaceCWIter; + + typedef FaceVertexIter ConstFaceVertexIter; + typedef FaceVertexCWIter ConstFaceVertexCWIter; + typedef FaceVertexCCWIter ConstFaceVertexCCWIter; + typedef FaceHalfedgeIter ConstFaceHalfedgeIter; + typedef FaceHalfedgeCWIter ConstFaceHalfedgeCWIter; + typedef FaceHalfedgeCCWIter ConstFaceHalfedgeCCWIter; + typedef FaceEdgeIter ConstFaceEdgeIter; + typedef FaceEdgeCWIter ConstFaceEdgeCWIter; + typedef FaceEdgeCCWIter ConstFaceEdgeCCWIter; + typedef FaceFaceIter ConstFaceFaceIter; + typedef FaceFaceCWIter ConstFaceFaceCWIter; + typedef FaceFaceCCWIter ConstFaceFaceCCWIter; + + /* + * Halfedge circulator + */ + typedef HalfedgeLoopIter ConstHalfedgeLoopIter; + typedef HalfedgeLoopCWIter ConstHalfedgeLoopCWIter; + typedef HalfedgeLoopCCWIter ConstHalfedgeLoopCCWIter; + + //@} + + // --- shortcuts + + /** \name Typedef Shortcuts + Provided for convenience only + */ + //@{ + /// Alias typedef + typedef VertexHandle VHandle; + typedef HalfedgeHandle HHandle; + typedef EdgeHandle EHandle; + typedef FaceHandle FHandle; + + typedef VertexIter VIter; + typedef HalfedgeIter HIter; + typedef EdgeIter EIter; + typedef FaceIter FIter; + + typedef ConstVertexIter CVIter; + typedef ConstHalfedgeIter CHIter; + typedef ConstEdgeIter CEIter; + typedef ConstFaceIter CFIter; + + typedef VertexVertexIter VVIter; + typedef VertexVertexCWIter VVCWIter; + typedef VertexVertexCCWIter VVCCWIter; + typedef VertexOHalfedgeIter VOHIter; + typedef VertexOHalfedgeCWIter VOHCWIter; + typedef VertexOHalfedgeCCWIter VOHCCWIter; + typedef VertexIHalfedgeIter VIHIter; + typedef VertexIHalfedgeCWIter VIHICWter; + typedef VertexIHalfedgeCCWIter VIHICCWter; + typedef VertexEdgeIter VEIter; + typedef VertexEdgeCWIter VECWIter; + typedef VertexEdgeCCWIter VECCWIter; + typedef VertexFaceIter VFIter; + typedef VertexFaceCWIter VFCWIter; + typedef VertexFaceCCWIter VFCCWIter; + typedef FaceVertexIter FVIter; + typedef FaceVertexCWIter FVCWIter; + typedef FaceVertexCCWIter FVCCWIter; + typedef FaceHalfedgeIter FHIter; + typedef FaceHalfedgeCWIter FHCWIter; + typedef FaceHalfedgeCCWIter FHCWWIter; + typedef FaceEdgeIter FEIter; + typedef FaceEdgeCWIter FECWIter; + typedef FaceEdgeCCWIter FECWWIter; + typedef FaceFaceIter FFIter; + + typedef ConstVertexVertexIter CVVIter; + typedef ConstVertexVertexCWIter CVVCWIter; + typedef ConstVertexVertexCCWIter CVVCCWIter; + typedef ConstVertexOHalfedgeIter CVOHIter; + typedef ConstVertexOHalfedgeCWIter CVOHCWIter; + typedef ConstVertexOHalfedgeCCWIter CVOHCCWIter; + typedef ConstVertexIHalfedgeIter CVIHIter; + typedef ConstVertexIHalfedgeCWIter CVIHCWIter; + typedef ConstVertexIHalfedgeCCWIter CVIHCCWIter; + typedef ConstVertexEdgeIter CVEIter; + typedef ConstVertexEdgeCWIter CVECWIter; + typedef ConstVertexEdgeCCWIter CVECCWIter; + typedef ConstVertexFaceIter CVFIter; + typedef ConstVertexFaceCWIter CVFCWIter; + typedef ConstVertexFaceCCWIter CVFCCWIter; + typedef ConstFaceVertexIter CFVIter; + typedef ConstFaceVertexCWIter CFVCWIter; + typedef ConstFaceVertexCCWIter CFVCCWIter; + typedef ConstFaceHalfedgeIter CFHIter; + typedef ConstFaceHalfedgeCWIter CFHCWIter; + typedef ConstFaceHalfedgeCCWIter CFHCCWIter; + typedef ConstFaceEdgeIter CFEIter; + typedef ConstFaceEdgeCWIter CFECWIter; + typedef ConstFaceEdgeCCWIter CFECCWIter; + typedef ConstFaceFaceIter CFFIter; + typedef ConstFaceFaceCWIter CFFCWIter; + typedef ConstFaceFaceCCWIter CFFCCWIter; + //@} + +public: + + PolyConnectivity() {} + virtual ~PolyConnectivity() {} + + inline static bool is_triangles() + { return false; } + + /** assign_connectivity() method. See ArrayKernel::assign_connectivity() + for more details. */ + inline void assign_connectivity(const PolyConnectivity& _other) + { ArrayKernel::assign_connectivity(_other); } + + /** \name Adding items to a mesh + */ + //@{ + + /// Add a new vertex + inline VertexHandle add_vertex() + { return new_vertex(); } + + /** \brief Add and connect a new face + * + * Create a new face consisting of the vertices provided by the vertex handle vector. + * (The vertices have to be already added to the mesh by add_vertex) + * + * @param _vhandles sorted list of vertex handles (also defines order in which the vertices are added to the face) + */ + FaceHandle add_face(const std::vector& _vhandles); + + + /** \brief Add and connect a new face + * + * Create a new face consisting of three vertices provided by the handles. + * (The vertices have to be already added to the mesh by add_vertex) + * + * @param _vh0 First vertex handle + * @param _vh1 Second vertex handle + * @param _vh2 Third vertex handle + */ + FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); + + /** \brief Add and connect a new face + * + * Create a new face consisting of four vertices provided by the handles. + * (The vertices have to be already added to the mesh by add_vertex) + * + * @param _vh0 First vertex handle + * @param _vh1 Second vertex handle + * @param _vh2 Third vertex handle + * @param _vh3 Fourth vertex handle + */ + FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3); + + /** \brief Add and connect a new face + * + * Create a new face consisting of vertices provided by a handle array. + * (The vertices have to be already added to the mesh by add_vertex) + * + * @param _vhandles pointer to a sorted list of vertex handles (also defines order in which the vertices are added to the face) + * @param _vhs_size number of vertex handles in the array + */ + FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); + + //@} + + /// \name Deleting mesh items and other connectivity/topology modifications + //@{ + + /** Returns whether collapsing halfedge _heh is ok or would lead to + topological inconsistencies. + \attention This method need the Attributes::Status attribute and + changes the \em tagged bit. */ + bool is_collapse_ok(HalfedgeHandle _he); + + + /** Mark vertex and all incident edges and faces deleted. + Items marked deleted will be removed by garbageCollection(). + \attention Needs the Attributes::Status attribute for vertices, + edges and faces. + */ + void delete_vertex(VertexHandle _vh, bool _delete_isolated_vertices = true); + + /** Mark edge (two opposite halfedges) and incident faces deleted. + Resulting isolated vertices are marked deleted if + _delete_isolated_vertices is true. Items marked deleted will be + removed by garbageCollection(). + + \attention Needs the Attributes::Status attribute for vertices, + edges and faces. + */ + void delete_edge(EdgeHandle _eh, bool _delete_isolated_vertices=true); + + /** Delete face _fh and resulting degenerated empty halfedges as + well. Resulting isolated vertices will be deleted if + _delete_isolated_vertices is true. + + \attention All item will only be marked to be deleted. They will + actually be removed by calling garbage_collection(). + + \attention Needs the Attributes::Status attribute for vertices, + edges and faces. + */ + void delete_face(FaceHandle _fh, bool _delete_isolated_vertices=true); + + //@} + + /** \name Begin and end iterators + */ + //@{ + + /// Begin iterator for vertices + VertexIter vertices_begin(); + /// Const begin iterator for vertices + ConstVertexIter vertices_begin() const; + /// End iterator for vertices + VertexIter vertices_end(); + /// Const end iterator for vertices + ConstVertexIter vertices_end() const; + + /// Begin iterator for halfedges + HalfedgeIter halfedges_begin(); + /// Const begin iterator for halfedges + ConstHalfedgeIter halfedges_begin() const; + /// End iterator for halfedges + HalfedgeIter halfedges_end(); + /// Const end iterator for halfedges + ConstHalfedgeIter halfedges_end() const; + + /// Begin iterator for edges + EdgeIter edges_begin(); + /// Const begin iterator for edges + ConstEdgeIter edges_begin() const; + /// End iterator for edges + EdgeIter edges_end(); + /// Const end iterator for edges + ConstEdgeIter edges_end() const; + + /// Begin iterator for faces + FaceIter faces_begin(); + /// Const begin iterator for faces + ConstFaceIter faces_begin() const; + /// End iterator for faces + FaceIter faces_end(); + /// Const end iterator for faces + ConstFaceIter faces_end() const; + //@} + + + /** \name Begin for skipping iterators + */ + //@{ + + /// Begin iterator for vertices + VertexIter vertices_sbegin() + { return VertexIter(*this, VertexHandle(0), true); } + /// Const begin iterator for vertices + ConstVertexIter vertices_sbegin() const + { return ConstVertexIter(*this, VertexHandle(0), true); } + + /// Begin iterator for halfedges + HalfedgeIter halfedges_sbegin() + { return HalfedgeIter(*this, HalfedgeHandle(0), true); } + /// Const begin iterator for halfedges + ConstHalfedgeIter halfedges_sbegin() const + { return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + + /// Begin iterator for edges + EdgeIter edges_sbegin() + { return EdgeIter(*this, EdgeHandle(0), true); } + /// Const begin iterator for edges + ConstEdgeIter edges_sbegin() const + { return ConstEdgeIter(*this, EdgeHandle(0), true); } + + /// Begin iterator for faces + FaceIter faces_sbegin() + { return FaceIter(*this, FaceHandle(0), true); } + /// Const begin iterator for faces + ConstFaceIter faces_sbegin() const + { return ConstFaceIter(*this, FaceHandle(0), true); } + + //@} + + //--- circulators --- + + /** \name Vertex and Face circulators + */ + //@{ + + /// vertex - vertex circulator + VertexVertexIter vv_iter(VertexHandle _vh) + { return VertexVertexIter(*this, _vh); } + /// vertex - vertex circulator cw + VertexVertexCWIter vv_cwiter(VertexHandle _vh) + { return VertexVertexCWIter(*this, _vh); } + /// vertex - vertex circulator ccw + VertexVertexCCWIter vv_ccwiter(VertexHandle _vh) + { return VertexVertexCCWIter(*this, _vh); } + /// vertex - incoming halfedge circulator + VertexIHalfedgeIter vih_iter(VertexHandle _vh) + { return VertexIHalfedgeIter(*this, _vh); } + /// vertex - incoming halfedge circulator cw + VertexIHalfedgeCWIter vih_cwiter(VertexHandle _vh) + { return VertexIHalfedgeCWIter(*this, _vh); } + /// vertex - incoming halfedge circulator ccw + VertexIHalfedgeCCWIter vih_ccwiter(VertexHandle _vh) + { return VertexIHalfedgeCCWIter(*this, _vh); } + /// vertex - outgoing halfedge circulator + VertexOHalfedgeIter voh_iter(VertexHandle _vh) + { return VertexOHalfedgeIter(*this, _vh); } + /// vertex - outgoing halfedge circulator cw + VertexOHalfedgeCWIter voh_cwiter(VertexHandle _vh) + { return VertexOHalfedgeCWIter(*this, _vh); } + /// vertex - outgoing halfedge circulator ccw + VertexOHalfedgeCCWIter voh_ccwiter(VertexHandle _vh) + { return VertexOHalfedgeCCWIter(*this, _vh); } + /// vertex - edge circulator + VertexEdgeIter ve_iter(VertexHandle _vh) + { return VertexEdgeIter(*this, _vh); } + /// vertex - edge circulator cw + VertexEdgeCWIter ve_cwiter(VertexHandle _vh) + { return VertexEdgeCWIter(*this, _vh); } + /// vertex - edge circulator ccw + VertexEdgeCCWIter ve_ccwiter(VertexHandle _vh) + { return VertexEdgeCCWIter(*this, _vh); } + /// vertex - face circulator + VertexFaceIter vf_iter(VertexHandle _vh) + { return VertexFaceIter(*this, _vh); } + /// vertex - face circulator cw + VertexFaceCWIter vf_cwiter(VertexHandle _vh) + { return VertexFaceCWIter(*this, _vh); } + /// vertex - face circulator ccw + VertexFaceCCWIter vf_ccwiter(VertexHandle _vh) + { return VertexFaceCCWIter(*this, _vh); } + + /// const vertex circulator + ConstVertexVertexIter cvv_iter(VertexHandle _vh) const + { return ConstVertexVertexIter(*this, _vh); } + /// const vertex circulator cw + ConstVertexVertexCWIter cvv_cwiter(VertexHandle _vh) const + { return ConstVertexVertexCWIter(*this, _vh); } + /// const vertex circulator ccw + ConstVertexVertexCCWIter cvv_ccwiter(VertexHandle _vh) const + { return ConstVertexVertexCCWIter(*this, _vh); } + /// const vertex - incoming halfedge circulator + ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const + { return ConstVertexIHalfedgeIter(*this, _vh); } + /// const vertex - incoming halfedge circulator cw + ConstVertexIHalfedgeCWIter cvih_cwiter(VertexHandle _vh) const + { return ConstVertexIHalfedgeCWIter(*this, _vh); } + /// const vertex - incoming halfedge circulator ccw + ConstVertexIHalfedgeCCWIter cvih_ccwiter(VertexHandle _vh) const + { return ConstVertexIHalfedgeCCWIter(*this, _vh); } + /// const vertex - outgoing halfedge circulator + ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const + { return ConstVertexOHalfedgeIter(*this, _vh); } + /// const vertex - outgoing halfedge circulator cw + ConstVertexOHalfedgeCWIter cvoh_cwiter(VertexHandle _vh) const + { return ConstVertexOHalfedgeCWIter(*this, _vh); } + /// const vertex - outgoing halfedge circulator ccw + ConstVertexOHalfedgeCCWIter cvoh_ccwiter(VertexHandle _vh) const + { return ConstVertexOHalfedgeCCWIter(*this, _vh); } + /// const vertex - edge circulator + ConstVertexEdgeIter cve_iter(VertexHandle _vh) const + { return ConstVertexEdgeIter(*this, _vh); } + /// const vertex - edge circulator cw + ConstVertexEdgeCWIter cve_cwiter(VertexHandle _vh) const + { return ConstVertexEdgeCWIter(*this, _vh); } + /// const vertex - edge circulator ccw + ConstVertexEdgeCCWIter cve_ccwiter(VertexHandle _vh) const + { return ConstVertexEdgeCCWIter(*this, _vh); } + /// const vertex - face circulator + ConstVertexFaceIter cvf_iter(VertexHandle _vh) const + { return ConstVertexFaceIter(*this, _vh); } + /// const vertex - face circulator cw + ConstVertexFaceCWIter cvf_cwiter(VertexHandle _vh) const + { return ConstVertexFaceCWIter(*this, _vh); } + /// const vertex - face circulator ccw + ConstVertexFaceCCWIter cvf_ccwiter(VertexHandle _vh) const + { return ConstVertexFaceCCWIter(*this, _vh); } + + /// face - vertex circulator + FaceVertexIter fv_iter(FaceHandle _fh) + { return FaceVertexIter(*this, _fh); } + /// face - vertex circulator cw + FaceVertexCWIter fv_cwiter(FaceHandle _fh) + { return FaceVertexCWIter(*this, _fh); } + /// face - vertex circulator ccw + FaceVertexCCWIter fv_ccwiter(FaceHandle _fh) + { return FaceVertexCCWIter(*this, _fh); } + /// face - halfedge circulator + FaceHalfedgeIter fh_iter(FaceHandle _fh) + { return FaceHalfedgeIter(*this, _fh); } + /// face - halfedge circulator cw + FaceHalfedgeCWIter fh_cwiter(FaceHandle _fh) + { return FaceHalfedgeCWIter(*this, _fh); } + /// face - halfedge circulator ccw + FaceHalfedgeCCWIter fh_ccwiter(FaceHandle _fh) + { return FaceHalfedgeCCWIter(*this, _fh); } + /// face - edge circulator + FaceEdgeIter fe_iter(FaceHandle _fh) + { return FaceEdgeIter(*this, _fh); } + /// face - edge circulator cw + FaceEdgeCWIter fe_cwiter(FaceHandle _fh) + { return FaceEdgeCWIter(*this, _fh); } + /// face - edge circulator ccw + FaceEdgeCCWIter fe_ccwiter(FaceHandle _fh) + { return FaceEdgeCCWIter(*this, _fh); } + /// face - face circulator + FaceFaceIter ff_iter(FaceHandle _fh) + { return FaceFaceIter(*this, _fh); } + /// face - face circulator cw + FaceFaceCWIter ff_cwiter(FaceHandle _fh) + { return FaceFaceCWIter(*this, _fh); } + /// face - face circulator ccw + FaceFaceCCWIter ff_ccwiter(FaceHandle _fh) + { return FaceFaceCCWIter(*this, _fh); } + + /// const face - vertex circulator + ConstFaceVertexIter cfv_iter(FaceHandle _fh) const + { return ConstFaceVertexIter(*this, _fh); } + /// const face - vertex circulator cw + ConstFaceVertexCWIter cfv_cwiter(FaceHandle _fh) const + { return ConstFaceVertexCWIter(*this, _fh); } + /// const face - vertex circulator ccw + ConstFaceVertexCCWIter cfv_ccwiter(FaceHandle _fh) const + { return ConstFaceVertexCCWIter(*this, _fh); } + /// const face - halfedge circulator + ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const + { return ConstFaceHalfedgeIter(*this, _fh); } + /// const face - halfedge circulator cw + ConstFaceHalfedgeCWIter cfh_cwiter(FaceHandle _fh) const + { return ConstFaceHalfedgeCWIter(*this, _fh); } + /// const face - halfedge circulator ccw + ConstFaceHalfedgeCCWIter cfh_ccwiter(FaceHandle _fh) const + { return ConstFaceHalfedgeCCWIter(*this, _fh); } + /// const face - edge circulator + ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const + { return ConstFaceEdgeIter(*this, _fh); } + /// const face - edge circulator cw + ConstFaceEdgeCWIter cfe_cwiter(FaceHandle _fh) const + { return ConstFaceEdgeCWIter(*this, _fh); } + /// const face - edge circulator ccw + ConstFaceEdgeCCWIter cfe_ccwiter(FaceHandle _fh) const + { return ConstFaceEdgeCCWIter(*this, _fh); } + /// const face - face circulator + ConstFaceFaceIter cff_iter(FaceHandle _fh) const + { return ConstFaceFaceIter(*this, _fh); } + /// const face - face circulator cw + ConstFaceFaceCWIter cff_cwiter(FaceHandle _fh) const + { return ConstFaceFaceCWIter(*this, _fh); } + /// const face - face circulator + ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const + { return ConstFaceFaceCCWIter(*this, _fh); } + + // 'begin' circulators + + /// vertex - vertex circulator + VertexVertexIter vv_begin(VertexHandle _vh) + { return VertexVertexIter(*this, _vh); } + /// vertex - vertex circulator cw + VertexVertexCWIter vv_cwbegin(VertexHandle _vh) + { return VertexVertexCWIter(*this, _vh); } + /// vertex - vertex circulator ccw + VertexVertexCCWIter vv_ccwbegin(VertexHandle _vh) + { return VertexVertexCCWIter(*this, _vh); } + /// vertex - incoming halfedge circulator + VertexIHalfedgeIter vih_begin(VertexHandle _vh) + { return VertexIHalfedgeIter(*this, _vh); } + /// vertex - incoming halfedge circulator cw + VertexIHalfedgeCWIter vih_cwbegin(VertexHandle _vh) + { return VertexIHalfedgeCWIter(*this, _vh); } + /// vertex - incoming halfedge circulator ccw + VertexIHalfedgeCCWIter vih_ccwbegin(VertexHandle _vh) + { return VertexIHalfedgeCCWIter(*this, _vh); } + /// vertex - outgoing halfedge circulator + VertexOHalfedgeIter voh_begin(VertexHandle _vh) + { return VertexOHalfedgeIter(*this, _vh); } + /// vertex - outgoing halfedge circulator cw + VertexOHalfedgeCWIter voh_cwbegin(VertexHandle _vh) + { return VertexOHalfedgeCWIter(*this, _vh); } + /// vertex - outgoing halfedge circulator ccw + VertexOHalfedgeCCWIter voh_ccwbegin(VertexHandle _vh) + { return VertexOHalfedgeCCWIter(*this, _vh); } + /// vertex - edge circulator + VertexEdgeIter ve_begin(VertexHandle _vh) + { return VertexEdgeIter(*this, _vh); } + /// vertex - edge circulator cw + VertexEdgeCWIter ve_cwbegin(VertexHandle _vh) + { return VertexEdgeCWIter(*this, _vh); } + /// vertex - edge circulator ccw + VertexEdgeCCWIter ve_ccwbegin(VertexHandle _vh) + { return VertexEdgeCCWIter(*this, _vh); } + /// vertex - face circulator + VertexFaceIter vf_begin(VertexHandle _vh) + { return VertexFaceIter(*this, _vh); } + /// vertex - face circulator cw + VertexFaceCWIter vf_cwbegin(VertexHandle _vh) + { return VertexFaceCWIter(*this, _vh); } + /// vertex - face circulator ccw + VertexFaceCCWIter vf_ccwbegin(VertexHandle _vh) + { return VertexFaceCCWIter(*this, _vh); } + + + /// const vertex circulator + ConstVertexVertexIter cvv_begin(VertexHandle _vh) const + { return ConstVertexVertexIter(*this, _vh); } + /// const vertex circulator cw + ConstVertexVertexCWIter cvv_cwbegin(VertexHandle _vh) const + { return ConstVertexVertexCWIter(*this, _vh); } + /// const vertex circulator ccw + ConstVertexVertexCCWIter cvv_ccwbegin(VertexHandle _vh) const + { return ConstVertexVertexCCWIter(*this, _vh); } + /// const vertex - incoming halfedge circulator + ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const + { return ConstVertexIHalfedgeIter(*this, _vh); } + /// const vertex - incoming halfedge circulator cw + ConstVertexIHalfedgeCWIter cvih_cwbegin(VertexHandle _vh) const + { return ConstVertexIHalfedgeCWIter(*this, _vh); } + /// const vertex - incoming halfedge circulator ccw + ConstVertexIHalfedgeCCWIter cvih_ccwbegin(VertexHandle _vh) const + { return ConstVertexIHalfedgeCCWIter(*this, _vh); } + /// const vertex - outgoing halfedge circulator + ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const + { return ConstVertexOHalfedgeIter(*this, _vh); } + /// const vertex - outgoing halfedge circulator cw + ConstVertexOHalfedgeCWIter cvoh_cwbegin(VertexHandle _vh) const + { return ConstVertexOHalfedgeCWIter(*this, _vh); } + /// const vertex - outgoing halfedge circulator ccw + ConstVertexOHalfedgeCCWIter cvoh_ccwbegin(VertexHandle _vh) const + { return ConstVertexOHalfedgeCCWIter(*this, _vh); } + /// const vertex - edge circulator + ConstVertexEdgeIter cve_begin(VertexHandle _vh) const + { return ConstVertexEdgeIter(*this, _vh); } + /// const vertex - edge circulator cw + ConstVertexEdgeCWIter cve_cwbegin(VertexHandle _vh) const + { return ConstVertexEdgeCWIter(*this, _vh); } + /// const vertex - edge circulator ccw + ConstVertexEdgeCCWIter cve_ccwbegin(VertexHandle _vh) const + { return ConstVertexEdgeCCWIter(*this, _vh); } + /// const vertex - face circulator + ConstVertexFaceIter cvf_begin(VertexHandle _vh) const + { return ConstVertexFaceIter(*this, _vh); } + /// const vertex - face circulator cw + ConstVertexFaceCWIter cvf_cwbegin(VertexHandle _vh) const + { return ConstVertexFaceCWIter(*this, _vh); } + /// const vertex - face circulator ccw + ConstVertexFaceCCWIter cvf_ccwbegin(VertexHandle _vh) const + { return ConstVertexFaceCCWIter(*this, _vh); } + + /// face - vertex circulator + FaceVertexIter fv_begin(FaceHandle _fh) + { return FaceVertexIter(*this, _fh); } + /// face - vertex circulator cw + FaceVertexCWIter fv_cwbegin(FaceHandle _fh) + { return FaceVertexCWIter(*this, _fh); } + /// face - vertex circulator ccw + FaceVertexCCWIter fv_ccwbegin(FaceHandle _fh) + { return FaceVertexCCWIter(*this, _fh); } + /// face - halfedge circulator + FaceHalfedgeIter fh_begin(FaceHandle _fh) + { return FaceHalfedgeIter(*this, _fh); } + /// face - halfedge circulator cw + FaceHalfedgeCWIter fh_cwbegin(FaceHandle _fh) + { return FaceHalfedgeCWIter(*this, _fh); } + /// face - halfedge circulator ccw + FaceHalfedgeCCWIter fh_ccwbegin(FaceHandle _fh) + { return FaceHalfedgeCCWIter(*this, _fh); } + /// face - edge circulator + FaceEdgeIter fe_begin(FaceHandle _fh) + { return FaceEdgeIter(*this, _fh); } + /// face - edge circulator cw + FaceEdgeCWIter fe_cwbegin(FaceHandle _fh) + { return FaceEdgeCWIter(*this, _fh); } + /// face - edge circulator ccw + FaceEdgeCCWIter fe_ccwbegin(FaceHandle _fh) + { return FaceEdgeCCWIter(*this, _fh); } + /// face - face circulator + FaceFaceIter ff_begin(FaceHandle _fh) + { return FaceFaceIter(*this, _fh); } + /// face - face circulator cw + FaceFaceCWIter ff_cwbegin(FaceHandle _fh) + { return FaceFaceCWIter(*this, _fh); } + /// face - face circulator ccw + FaceFaceCCWIter ff_ccwbegin(FaceHandle _fh) + { return FaceFaceCCWIter(*this, _fh); } + /// halfedge circulator + HalfedgeLoopIter hl_begin(HalfedgeHandle _heh) + { return HalfedgeLoopIter(*this, _heh); } + /// halfedge circulator + HalfedgeLoopCWIter hl_cwbegin(HalfedgeHandle _heh) + { return HalfedgeLoopCWIter(*this, _heh); } + /// halfedge circulator ccw + HalfedgeLoopCCWIter hl_ccwbegin(HalfedgeHandle _heh) + { return HalfedgeLoopCCWIter(*this, _heh); } + + /// const face - vertex circulator + ConstFaceVertexIter cfv_begin(FaceHandle _fh) const + { return ConstFaceVertexIter(*this, _fh); } + /// const face - vertex circulator cw + ConstFaceVertexCWIter cfv_cwbegin(FaceHandle _fh) const + { return ConstFaceVertexCWIter(*this, _fh); } + /// const face - vertex circulator ccw + ConstFaceVertexCCWIter cfv_ccwbegin(FaceHandle _fh) const + { return ConstFaceVertexCCWIter(*this, _fh); } + /// const face - halfedge circulator + ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const + { return ConstFaceHalfedgeIter(*this, _fh); } + /// const face - halfedge circulator cw + ConstFaceHalfedgeCWIter cfh_cwbegin(FaceHandle _fh) const + { return ConstFaceHalfedgeCWIter(*this, _fh); } + /// const face - halfedge circulator ccw + ConstFaceHalfedgeCCWIter cfh_ccwbegin(FaceHandle _fh) const + { return ConstFaceHalfedgeCCWIter(*this, _fh); } + /// const face - edge circulator + ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const + { return ConstFaceEdgeIter(*this, _fh); } + /// const face - edge circulator cw + ConstFaceEdgeCWIter cfe_cwbegin(FaceHandle _fh) const + { return ConstFaceEdgeCWIter(*this, _fh); } + /// const face - edge circulator ccw + ConstFaceEdgeCCWIter cfe_ccwbegin(FaceHandle _fh) const + { return ConstFaceEdgeCCWIter(*this, _fh); } + /// const face - face circulator + ConstFaceFaceIter cff_begin(FaceHandle _fh) const + { return ConstFaceFaceIter(*this, _fh); } + /// const face - face circulator cw + ConstFaceFaceCWIter cff_cwbegin(FaceHandle _fh) const + { return ConstFaceFaceCWIter(*this, _fh); } + /// const face - face circulator ccw + ConstFaceFaceCCWIter cff_ccwbegin(FaceHandle _fh) const + { return ConstFaceFaceCCWIter(*this, _fh); } + /// const halfedge circulator + ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const + { return ConstHalfedgeLoopIter(*this, _heh); } + /// const halfedge circulator cw + ConstHalfedgeLoopCWIter chl_cwbegin(HalfedgeHandle _heh) const + { return ConstHalfedgeLoopCWIter(*this, _heh); } + /// const halfedge circulator ccw + ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const + { return ConstHalfedgeLoopCCWIter(*this, _heh); } + + // 'end' circulators + + /// vertex - vertex circulator + VertexVertexIter vv_end(VertexHandle _vh) + { return VertexVertexIter(*this, _vh, true); } + /// vertex - vertex circulator cw + VertexVertexCWIter vv_cwend(VertexHandle _vh) + { return VertexVertexCWIter(*this, _vh, true); } + /// vertex - vertex circulator ccw + VertexVertexCCWIter vv_ccwend(VertexHandle _vh) + { return VertexVertexCCWIter(*this, _vh, true); } + /// vertex - incoming halfedge circulator + VertexIHalfedgeIter vih_end(VertexHandle _vh) + { return VertexIHalfedgeIter(*this, _vh, true); } + /// vertex - incoming halfedge circulator cw + VertexIHalfedgeCWIter vih_cwend(VertexHandle _vh) + { return VertexIHalfedgeCWIter(*this, _vh, true); } + /// vertex - incoming halfedge circulator ccw + VertexIHalfedgeCCWIter vih_ccwend(VertexHandle _vh) + { return VertexIHalfedgeCCWIter(*this, _vh, true); } + /// vertex - outgoing halfedge circulator + VertexOHalfedgeIter voh_end(VertexHandle _vh) + { return VertexOHalfedgeIter(*this, _vh, true); } + /// vertex - outgoing halfedge circulator cw + VertexOHalfedgeCWIter voh_cwend(VertexHandle _vh) + { return VertexOHalfedgeCWIter(*this, _vh, true); } + /// vertex - outgoing halfedge circulator ccw + VertexOHalfedgeCCWIter voh_ccwend(VertexHandle _vh) + { return VertexOHalfedgeCCWIter(*this, _vh, true); } + /// vertex - edge circulator + VertexEdgeIter ve_end(VertexHandle _vh) + { return VertexEdgeIter(*this, _vh, true); } + /// vertex - edge circulator cw + VertexEdgeCWIter ve_cwend(VertexHandle _vh) + { return VertexEdgeCWIter(*this, _vh, true); } + /// vertex - edge circulator ccw + VertexEdgeCCWIter ve_ccwend(VertexHandle _vh) + { return VertexEdgeCCWIter(*this, _vh, true); } + /// vertex - face circulator + VertexFaceIter vf_end(VertexHandle _vh) + { return VertexFaceIter(*this, _vh, true); } + /// vertex - face circulator cw + VertexFaceCWIter vf_cwend(VertexHandle _vh) + { return VertexFaceCWIter(*this, _vh, true); } + /// vertex - face circulator ccw + VertexFaceCCWIter vf_ccwend(VertexHandle _vh) + { return VertexFaceCCWIter(*this, _vh, true); } + + /// const vertex circulator + ConstVertexVertexIter cvv_end(VertexHandle _vh) const + { return ConstVertexVertexIter(*this, _vh, true); } + /// const vertex circulator cw + ConstVertexVertexCWIter cvv_cwend(VertexHandle _vh) const + { return ConstVertexVertexCWIter(*this, _vh, true); } + /// const vertex circulator ccw + ConstVertexVertexCCWIter cvv_ccwend(VertexHandle _vh) const + { return ConstVertexVertexCCWIter(*this, _vh, true); } + /// const vertex - incoming halfedge circulator + ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const + { return ConstVertexIHalfedgeIter(*this, _vh, true); } + /// const vertex - incoming halfedge circulator cw + ConstVertexIHalfedgeCWIter cvih_cwend(VertexHandle _vh) const + { return ConstVertexIHalfedgeCWIter(*this, _vh, true); } + /// const vertex - incoming halfedge circulator ccw + ConstVertexIHalfedgeCCWIter cvih_ccwend(VertexHandle _vh) const + { return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } + /// const vertex - outgoing halfedge circulator + ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const + { return ConstVertexOHalfedgeIter(*this, _vh, true); } + /// const vertex - outgoing halfedge circulator cw + ConstVertexOHalfedgeCWIter cvoh_cwend(VertexHandle _vh) const + { return ConstVertexOHalfedgeCWIter(*this, _vh, true); } + /// const vertex - outgoing halfedge circulator ccw + ConstVertexOHalfedgeCCWIter cvoh_ccwend(VertexHandle _vh) const + { return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } + /// const vertex - edge circulator + ConstVertexEdgeIter cve_end(VertexHandle _vh) const + { return ConstVertexEdgeIter(*this, _vh, true); } + /// const vertex - edge circulator cw + ConstVertexEdgeCWIter cve_cwend(VertexHandle _vh) const + { return ConstVertexEdgeCWIter(*this, _vh, true); } + /// const vertex - edge circulator ccw + ConstVertexEdgeCCWIter cve_ccwend(VertexHandle _vh) const + { return ConstVertexEdgeCCWIter(*this, _vh, true); } + /// const vertex - face circulator + ConstVertexFaceIter cvf_end(VertexHandle _vh) const + { return ConstVertexFaceIter(*this, _vh, true); } + /// const vertex - face circulator cw + ConstVertexFaceCWIter cvf_cwend(VertexHandle _vh) const + { return ConstVertexFaceCWIter(*this, _vh, true); } + /// const vertex - face circulator ccw + ConstVertexFaceCCWIter cvf_ccwend(VertexHandle _vh) const + { return ConstVertexFaceCCWIter(*this, _vh, true); } + + /// face - vertex circulator + FaceVertexIter fv_end(FaceHandle _fh) + { return FaceVertexIter(*this, _fh, true); } + /// face - vertex circulator cw + FaceVertexCWIter fv_cwend(FaceHandle _fh) + { return FaceVertexCWIter(*this, _fh, true); } + /// face - vertex circulator ccw + FaceVertexCCWIter fv_ccwend(FaceHandle _fh) + { return FaceVertexCCWIter(*this, _fh, true); } + /// face - halfedge circulator + FaceHalfedgeIter fh_end(FaceHandle _fh) + { return FaceHalfedgeIter(*this, _fh, true); } + /// face - halfedge circulator cw + FaceHalfedgeCWIter fh_cwend(FaceHandle _fh) + { return FaceHalfedgeCWIter(*this, _fh, true); } + /// face - halfedge circulator ccw + FaceHalfedgeCCWIter fh_ccwend(FaceHandle _fh) + { return FaceHalfedgeCCWIter(*this, _fh, true); } + /// face - edge circulator + FaceEdgeIter fe_end(FaceHandle _fh) + { return FaceEdgeIter(*this, _fh, true); } + /// face - edge circulator cw + FaceEdgeCWIter fe_cwend(FaceHandle _fh) + { return FaceEdgeCWIter(*this, _fh, true); } + /// face - edge circulator ccw + FaceEdgeCCWIter fe_ccwend(FaceHandle _fh) + { return FaceEdgeCCWIter(*this, _fh, true); } + /// face - face circulator + FaceFaceIter ff_end(FaceHandle _fh) + { return FaceFaceIter(*this, _fh, true); } + /// face - face circulator cw + FaceFaceCWIter ff_cwend(FaceHandle _fh) + { return FaceFaceCWIter(*this, _fh, true); } + /// face - face circulator ccw + FaceFaceCCWIter ff_ccwend(FaceHandle _fh) + { return FaceFaceCCWIter(*this, _fh, true); } + /// face - face circulator + HalfedgeLoopIter hl_end(HalfedgeHandle _heh) + { return HalfedgeLoopIter(*this, _heh, true); } + /// face - face circulator cw + HalfedgeLoopCWIter hl_cwend(HalfedgeHandle _heh) + { return HalfedgeLoopCWIter(*this, _heh, true); } + /// face - face circulator ccw + HalfedgeLoopCCWIter hl_ccwend(HalfedgeHandle _heh) + { return HalfedgeLoopCCWIter(*this, _heh, true); } + + /// const face - vertex circulator + ConstFaceVertexIter cfv_end(FaceHandle _fh) const + { return ConstFaceVertexIter(*this, _fh, true); } + /// const face - vertex circulator cw + ConstFaceVertexCWIter cfv_cwend(FaceHandle _fh) const + { return ConstFaceVertexCWIter(*this, _fh, true); } + /// const face - vertex circulator ccw + ConstFaceVertexCCWIter cfv_ccwend(FaceHandle _fh) const + { return ConstFaceVertexCCWIter(*this, _fh, true); } + /// const face - halfedge circulator + ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const + { return ConstFaceHalfedgeIter(*this, _fh, true); } + /// const face - halfedge circulator cw + ConstFaceHalfedgeCWIter cfh_cwend(FaceHandle _fh) const + { return ConstFaceHalfedgeCWIter(*this, _fh, true); } + /// const face - halfedge circulator ccw + ConstFaceHalfedgeCCWIter cfh_ccwend(FaceHandle _fh) const + { return ConstFaceHalfedgeCCWIter(*this, _fh, true); } + /// const face - edge circulator + ConstFaceEdgeIter cfe_end(FaceHandle _fh) const + { return ConstFaceEdgeIter(*this, _fh, true); } + /// const face - edge circulator cw + ConstFaceEdgeCWIter cfe_cwend(FaceHandle _fh) const + { return ConstFaceEdgeCWIter(*this, _fh, true); } + /// const face - edge circulator ccw + ConstFaceEdgeCCWIter cfe_ccwend(FaceHandle _fh) const + { return ConstFaceEdgeCCWIter(*this, _fh, true); } + /// const face - face circulator + ConstFaceFaceIter cff_end(FaceHandle _fh) const + { return ConstFaceFaceIter(*this, _fh, true); } + /// const face - face circulator + ConstFaceFaceCWIter cff_cwend(FaceHandle _fh) const + { return ConstFaceFaceCWIter(*this, _fh, true); } + /// const face - face circulator + ConstFaceFaceCCWIter cff_ccwend(FaceHandle _fh) const + { return ConstFaceFaceCCWIter(*this, _fh, true); } + /// const face - face circulator + ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const + { return ConstHalfedgeLoopIter(*this, _heh, true); } + /// const face - face circulator cw + ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const + { return ConstHalfedgeLoopCWIter(*this, _heh, true); } + /// const face - face circulator ccw + ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const + { return ConstHalfedgeLoopCCWIter(*this, _heh, true); } + //@} + + /** @name Range based iterators and circulators */ + //@{ + + /// Generic class for vertex/halfedge/edge/face ranges. + template< + typename CONTAINER_TYPE, + typename ITER_TYPE, + ITER_TYPE (CONTAINER_TYPE::*begin_fn)() const, + ITER_TYPE (CONTAINER_TYPE::*end_fn)() const> + class EntityRange { + public: + typedef ITER_TYPE iterator; + typedef ITER_TYPE const_iterator; + + EntityRange(CONTAINER_TYPE &container) : container_(container) {} + ITER_TYPE begin() const { return (container_.*begin_fn)(); } + ITER_TYPE end() const { return (container_.*end_fn)(); } + + private: + CONTAINER_TYPE &container_; + }; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstVertexIter, + &PolyConnectivity::vertices_begin, + &PolyConnectivity::vertices_end> ConstVertexRange; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstVertexIter, + &PolyConnectivity::vertices_sbegin, + &PolyConnectivity::vertices_end> ConstVertexRangeSkipping; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstHalfedgeIter, + &PolyConnectivity::halfedges_begin, + &PolyConnectivity::halfedges_end> ConstHalfedgeRange; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstHalfedgeIter, + &PolyConnectivity::halfedges_sbegin, + &PolyConnectivity::halfedges_end> ConstHalfedgeRangeSkipping; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstEdgeIter, + &PolyConnectivity::edges_begin, + &PolyConnectivity::edges_end> ConstEdgeRange; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstEdgeIter, + &PolyConnectivity::edges_sbegin, + &PolyConnectivity::edges_end> ConstEdgeRangeSkipping; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstFaceIter, + &PolyConnectivity::faces_begin, + &PolyConnectivity::faces_end> ConstFaceRange; + typedef EntityRange< + const PolyConnectivity, + PolyConnectivity::ConstFaceIter, + &PolyConnectivity::faces_sbegin, + &PolyConnectivity::faces_end> ConstFaceRangeSkipping; + + /** + * @return The vertices as a range object suitable + * for C++11 range based for loops. Will skip deleted vertices. + */ + ConstVertexRangeSkipping vertices() const { return ConstVertexRangeSkipping(*this); } + + /** + * @return The vertices as a range object suitable + * for C++11 range based for loops. Will include deleted vertices. + */ + ConstVertexRange all_vertices() const { return ConstVertexRange(*this); } + + /** + * @return The halfedges as a range object suitable + * for C++11 range based for loops. Will skip deleted halfedges. + */ + ConstHalfedgeRangeSkipping halfedges() const { return ConstHalfedgeRangeSkipping(*this); } + + /** + * @return The halfedges as a range object suitable + * for C++11 range based for loops. Will include deleted halfedges. + */ + ConstHalfedgeRange all_halfedges() const { return ConstHalfedgeRange(*this); } + + /** + * @return The edges as a range object suitable + * for C++11 range based for loops. Will skip deleted edges. + */ + ConstEdgeRangeSkipping edges() const { return ConstEdgeRangeSkipping(*this); } + + /** + * @return The edges as a range object suitable + * for C++11 range based for loops. Will include deleted edges. + */ + ConstEdgeRange all_edges() const { return ConstEdgeRange(*this); } + + /** + * @return The faces as a range object suitable + * for C++11 range based for loops. Will skip deleted faces. + */ + ConstFaceRangeSkipping faces() const { return ConstFaceRangeSkipping(*this); } + + /** + * @return The faces as a range object suitable + * for C++11 range based for loops. Will include deleted faces. + */ + ConstFaceRange all_faces() const { return ConstFaceRange(*this); } + + /// Generic class for iterator ranges. + template< + typename CONTAINER_TYPE, + typename ITER_TYPE, + typename CENTER_ENTITY_TYPE, + ITER_TYPE (CONTAINER_TYPE::*begin_fn)(CENTER_ENTITY_TYPE) const, + ITER_TYPE (CONTAINER_TYPE::*end_fn)(CENTER_ENTITY_TYPE) const> + class CirculatorRange { + public: + typedef ITER_TYPE iterator; + typedef ITER_TYPE const_iterator; + + CirculatorRange( + const CONTAINER_TYPE &container, + CENTER_ENTITY_TYPE center) : + container_(container), center_(center) {} + ITER_TYPE begin() const { return (container_.*begin_fn)(center_); } + ITER_TYPE end() const { return (container_.*end_fn)(center_); } + + private: + const CONTAINER_TYPE &container_; + CENTER_ENTITY_TYPE center_; + }; + + typedef CirculatorRange< + PolyConnectivity, + ConstVertexVertexCWIter, + VertexHandle, + &PolyConnectivity::cvv_cwbegin, + &PolyConnectivity::cvv_cwend> ConstVertexVertexRange; + typedef CirculatorRange< + PolyConnectivity, + ConstVertexIHalfedgeIter, + VertexHandle, + &PolyConnectivity::cvih_begin, + &PolyConnectivity::cvih_end> ConstVertexIHalfedgeRange; + typedef CirculatorRange< + PolyConnectivity, + ConstVertexOHalfedgeIter, VertexHandle, + &PolyConnectivity::cvoh_begin, + &PolyConnectivity::cvoh_end> ConstVertexOHalfedgeRange; + typedef CirculatorRange< + PolyConnectivity, + ConstVertexEdgeIter, + VertexHandle, + &PolyConnectivity::cve_begin, + &PolyConnectivity::cve_end> ConstVertexEdgeRange; + typedef CirculatorRange< + PolyConnectivity, + ConstVertexFaceIter, + VertexHandle, + &PolyConnectivity::cvf_begin, + &PolyConnectivity::cvf_end> ConstVertexFaceRange; + typedef CirculatorRange< + PolyConnectivity, + ConstFaceVertexIter, + FaceHandle, + &PolyConnectivity::cfv_begin, + &PolyConnectivity::cfv_end> ConstFaceVertexRange; + typedef CirculatorRange< + PolyConnectivity, + ConstFaceHalfedgeIter, + FaceHandle, + &PolyConnectivity::cfh_begin, + &PolyConnectivity::cfh_end> ConstFaceHalfedgeRange; + typedef CirculatorRange< + PolyConnectivity, + ConstFaceEdgeIter, + FaceHandle, + &PolyConnectivity::cfe_begin, + &PolyConnectivity::cfe_end> ConstFaceEdgeRange; + typedef CirculatorRange< + PolyConnectivity, + ConstFaceFaceIter, + FaceHandle, + &PolyConnectivity::cff_begin, + &PolyConnectivity::cff_end> ConstFaceFaceRange; + + /** + * @return The vertices adjacent to the specified vertex + * as a range object suitable for C++11 range based for loops. + */ + ConstVertexVertexRange vv_range(VertexHandle _vh) const { + return ConstVertexVertexRange(*this, _vh); + } + + /** + * @return The incoming halfedges incident to the specified vertex + * as a range object suitable for C++11 range based for loops. + */ + ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const { + return ConstVertexIHalfedgeRange(*this, _vh); + } + + /** + * @return The outgoing halfedges incident to the specified vertex + * as a range object suitable for C++11 range based for loops. + */ + ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const { + return ConstVertexOHalfedgeRange(*this, _vh); + } + + /** + * @return The edges incident to the specified vertex + * as a range object suitable for C++11 range based for loops. + */ + ConstVertexEdgeRange ve_range(VertexHandle _vh) const { + return ConstVertexEdgeRange(*this, _vh); + } + + /** + * @return The faces incident to the specified vertex + * as a range object suitable for C++11 range based for loops. + */ + ConstVertexFaceRange vf_range(VertexHandle _vh) const { + return ConstVertexFaceRange(*this, _vh); + } + + /** + * @return The vertices incident to the specified face + * as a range object suitable for C++11 range based for loops. + */ + ConstFaceVertexRange fv_range(FaceHandle _fh) const { + return ConstFaceVertexRange(*this, _fh); + } + + /** + * @return The halfedges incident to the specified face + * as a range object suitable for C++11 range based for loops. + */ + ConstFaceHalfedgeRange fh_range(FaceHandle _fh) const { + return ConstFaceHalfedgeRange(*this, _fh); + } + + /** + * @return The edges incident to the specified face + * as a range object suitable for C++11 range based for loops. + */ + ConstFaceEdgeRange fe_range(FaceHandle _fh) const { + return ConstFaceEdgeRange(*this, _fh); + } + + /** + * @return The faces adjacent to the specified face + * as a range object suitable for C++11 range based for loops. + */ + ConstFaceFaceRange ff_range(FaceHandle _fh) const { + return ConstFaceFaceRange(*this, _fh); + } + + //@} + + //=========================================================================== + /** @name Boundary and manifold tests + * @{ */ + //=========================================================================== + + /** \brief Check if the halfedge is at the boundary + * + * The halfedge is at the boundary, if no face is incident to it. + * + * @param _heh HalfedgeHandle to test + * @return boundary? + */ + bool is_boundary(HalfedgeHandle _heh) const + { return ArrayKernel::is_boundary(_heh); } + + /** \brief Is the edge a boundary edge? + * + * Checks it the edge _eh is a boundary edge, i.e. is one of its halfedges + * a boundary halfedge. + * + * @param _eh Edge handle to test + * @return boundary? + */ + bool is_boundary(EdgeHandle _eh) const + { + return (is_boundary(halfedge_handle(_eh, 0)) || + is_boundary(halfedge_handle(_eh, 1))); + } + + /** \brief Is vertex _vh a boundary vertex ? + * + * Checks if the associated halfedge (which would on a boundary be the outside + * halfedge), is connected to a face. Which is equivalent, if the vertex is + * at the boundary of the mesh, as OpenMesh will make sure, that if there is a + * boundary halfedge at the vertex, the halfedge will be the one which is associated + * to the vertex. + * + * @param _vh VertexHandle to test + * @return boundary? + */ + bool is_boundary(VertexHandle _vh) const + { + HalfedgeHandle heh(halfedge_handle(_vh)); + return (!(heh.is_valid() && face_handle(heh).is_valid())); + } + + /** \brief Check if face is at the boundary + * + * Is face _fh at boundary, i.e. is one of its edges (or vertices) + * a boundary edge? + * + * @param _fh Check this face + * @param _check_vertex If \c true, check the corner vertices of the face, too. + * @return boundary? + */ + bool is_boundary(FaceHandle _fh, bool _check_vertex=false) const; + + /** \brief Is (the mesh at) vertex _vh two-manifold ? + * + * The vertex is non-manifold if more than one gap exists, i.e. + * more than one outgoing boundary halfedge. If (at least) one + * boundary halfedge exists, the vertex' halfedge must be a + * boundary halfedge. + * + * @param _vh VertexHandle to test + * @return manifold? + */ + bool is_manifold(VertexHandle _vh) const; + + /** @} */ + + // --- shortcuts --- + + /// returns the face handle of the opposite halfedge + inline FaceHandle opposite_face_handle(HalfedgeHandle _heh) const + { return face_handle(opposite_halfedge_handle(_heh)); } + + // --- misc --- + + /** Adjust outgoing halfedge handle for vertices, so that it is a + boundary halfedge whenever possible. + */ + void adjust_outgoing_halfedge(VertexHandle _vh); + + /// Find halfedge from _vh0 to _vh1. Returns invalid handle if not found. + HalfedgeHandle find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh) const; + /// Vertex valence + uint valence(VertexHandle _vh) const; + /// Face valence + uint valence(FaceHandle _fh) const; + + // --- connectivity operattions + + /** Halfedge collapse: collapse the from-vertex of halfedge _heh + into its to-vertex. + + \attention Needs vertex/edge/face status attribute in order to + delete the items that degenerate. + + \note The from vertex is marked as deleted while the to vertex will still exist. + + \note This function does not perform a garbage collection. It + only marks degenerate items as deleted. + + \attention A halfedge collapse may lead to topological inconsistencies. + Therefore you should check this using is_collapse_ok(). + */ + void collapse(HalfedgeHandle _heh); + /** return true if the this the only link between the faces adjacent to _eh. + _eh is allowed to be boundary, in which case true is returned iff _eh is + the only boundary edge of its ajdacent face. + */ + bool is_simple_link(EdgeHandle _eh) const; + /** return true if _fh shares only one edge with all of its adjacent faces. + Boundary is treated as one face, i.e., the function false if _fh has more + than one boundary edge. + */ + bool is_simply_connected(FaceHandle _fh) const; + /** Removes the edge _eh. Its adjacent faces are merged. _eh and one of the + adjacent faces are set deleted. The handle of the remaining face is + returned (InvalidFaceHandle is returned if _eh is a boundary edge). + + \pre is_simple_link(_eh). This ensures that there are no hole faces + or isolated vertices appearing in result of the operation. + + \attention Needs the Attributes::Status attribute for edges and faces. + + \note This function does not perform a garbage collection. It + only marks items as deleted. + */ + FaceHandle remove_edge(EdgeHandle _eh); + /** Inverse of remove_edge. _eh should be the handle of the edge and the + vertex and halfedge handles pointed by edge(_eh) should be valid. + */ + void reinsert_edge(EdgeHandle _eh); + /** Inserts an edge between to_vh(_prev_heh) and from_vh(_next_heh). + A new face is created started at heh0 of the inserted edge and + its halfedges loop includes both _prev_heh and _next_heh. If an + old face existed which includes the argument halfedges, it is + split at the new edge. heh0 is returned. + + \note assumes _prev_heh and _next_heh are either boundary or pointed + to the same face + */ + HalfedgeHandle insert_edge(HalfedgeHandle _prev_heh, HalfedgeHandle _next_heh); + + /** \brief Face split (= 1-to-n split). + * + * Split an arbitrary face into triangles by connecting each vertex of fh to vh. + * + * \note fh will remain valid (it will become one of the triangles) + * \note the halfedge handles of the new triangles will point to the old halfeges + * + * \note The properties of the new faces and all other new primitives will be undefined! + * + * @param _fh Face handle that should be splitted + * @param _vh Vertex handle of the new vertex that will be inserted in the face + */ + void split(FaceHandle _fh, VertexHandle _vh); + + /** \brief Face split (= 1-to-n split). + * + * Split an arbitrary face into triangles by connecting each vertex of fh to vh. + * + * \note fh will remain valid (it will become one of the triangles) + * \note the halfedge handles of the new triangles will point to the old halfeges + * + * \note The properties of the new faces will be adjusted to the properties of the original faces + * \note Properties of the new edges and halfedges will be undefined + * + * @param _fh Face handle that should be splitted + * @param _vh Vertex handle of the new vertex that will be inserted in the face + */ + void split_copy(FaceHandle _fh, VertexHandle _vh); + + /** \brief Triangulate the face _fh + + Split an arbitrary face into triangles by connecting + each vertex of fh after its second to vh. + + \note _fh will remain valid (it will become one of the + triangles) + + \note The halfedge handles of the new triangles will + point to the old halfedges + + @param _fh Handle of the face that should be triangulated + */ + void triangulate(FaceHandle _fh); + + /** \brief triangulate the entire mesh + */ + void triangulate(); + + /** Edge split (inserts a vertex on the edge only) + * + * This edge split only splits the edge without introducing new faces! + * As this is for polygonal meshes, we can have valence 2 vertices here. + * + * \note The properties of the new edges and halfedges will be undefined! + * + * @param _eh Handle of the edge, that will be splitted + * @param _vh Handle of the vertex that will be inserted at the edge + */ + void split_edge(EdgeHandle _eh, VertexHandle _vh); + + /** Edge split (inserts a vertex on the edge only) + * + * This edge split only splits the edge without introducing new faces! + * As this is for polygonal meshes, we can have valence 2 vertices here. + * + * \note The properties of the new edge will be copied from the splitted edge + * \note Properties of the new halfedges will be undefined + * + * @param _eh Handle of the edge, that will be splitted + * @param _vh Handle of the vertex that will be inserted at the edge + */ + void split_edge_copy(EdgeHandle _eh, VertexHandle _vh); + + + /** \name Generic handle derefertiation. + Calls the respective vertex(), halfedge(), edge(), face() + method of the mesh kernel. + */ + //@{ + /// Get item from handle + const Vertex& deref(VertexHandle _h) const { return vertex(_h); } + Vertex& deref(VertexHandle _h) { return vertex(_h); } + const Halfedge& deref(HalfedgeHandle _h) const { return halfedge(_h); } + Halfedge& deref(HalfedgeHandle _h) { return halfedge(_h); } + const Edge& deref(EdgeHandle _h) const { return edge(_h); } + Edge& deref(EdgeHandle _h) { return edge(_h); } + const Face& deref(FaceHandle _h) const { return face(_h); } + Face& deref(FaceHandle _h) { return face(_h); } + //@} + +protected: + /// Helper for halfedge collapse + void collapse_edge(HalfedgeHandle _hh); + /// Helper for halfedge collapse + void collapse_loop(HalfedgeHandle _hh); + + + +private: // Working storage for add_face() + struct AddFaceEdgeInfo + { + HalfedgeHandle halfedge_handle; + bool is_new; + bool needs_adjust; + }; + std::vector edgeData_; // + std::vector > next_cache_; // cache for set_next_halfedge and vertex' set_halfedge + +}; + +}//namespace OpenMesh + +#endif//OPENMESH_POLYCONNECTIVITY_HH diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.hh new file mode 100644 index 0000000..31796fb --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.hh @@ -0,0 +1,638 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS PolyMeshT +// +//============================================================================= + + +#ifndef OPENMESH_POLYMESHT_HH +#define OPENMESH_POLYMESHT_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + +//== CLASS DEFINITION ========================================================= + + +/** \class PolyMeshT PolyMeshT.hh + + Base type for a polygonal mesh. + + This is the base class for a polygonal mesh. It is parameterized + by a mesh kernel that is given as a template argument. This class + inherits all methods from its mesh kernel. + + \param Kernel: template argument for the mesh kernel + \note You should use the predefined mesh-kernel combinations in + \ref mesh_types_group + \see \ref mesh_type +*/ + +template +class PolyMeshT : public Kernel +{ +public: + + /// Self type. Used to specify iterators/circulators. + typedef PolyMeshT This; + //--- item types --- + + //@{ + /// Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT ) + enum { IsPolyMesh = 1 }; + enum { IsTriMesh = 0 }; + static bool is_polymesh() { return true; } + static bool is_trimesh() { return false; } + //@} + + /// \name Mesh Items + //@{ + /// Scalar type + typedef typename Kernel::Scalar Scalar; + /// Coordinate type + typedef typename Kernel::Point Point; + /// Normal type + typedef typename Kernel::Normal Normal; + /// Color type + typedef typename Kernel::Color Color; + /// TexCoord1D type + typedef typename Kernel::TexCoord1D TexCoord1D; + /// TexCoord2D type + typedef typename Kernel::TexCoord2D TexCoord2D; + /// TexCoord3D type + typedef typename Kernel::TexCoord3D TexCoord3D; + /// Vertex type + typedef typename Kernel::Vertex Vertex; + /// Halfedge type + typedef typename Kernel::Halfedge Halfedge; + /// Edge type + typedef typename Kernel::Edge Edge; + /// Face type + typedef typename Kernel::Face Face; + //@} + + //--- handle types --- + + /// Handle for referencing the corresponding item + typedef typename Kernel::VertexHandle VertexHandle; + typedef typename Kernel::HalfedgeHandle HalfedgeHandle; + typedef typename Kernel::EdgeHandle EdgeHandle; + typedef typename Kernel::FaceHandle FaceHandle; + + + + typedef typename Kernel::VertexIter VertexIter; + typedef typename Kernel::HalfedgeIter HalfedgeIter; + typedef typename Kernel::EdgeIter EdgeIter; + typedef typename Kernel::FaceIter FaceIter; + + typedef typename Kernel::ConstVertexIter ConstVertexIter; + typedef typename Kernel::ConstHalfedgeIter ConstHalfedgeIter; + typedef typename Kernel::ConstEdgeIter ConstEdgeIter; + typedef typename Kernel::ConstFaceIter ConstFaceIter; + //@} + + //--- circulators --- + + /** \name Mesh Circulators + Refer to OpenMesh::Mesh::Iterators or \ref mesh_iterators + for documentation. + */ + //@{ + /// Circulator + typedef typename Kernel::VertexVertexIter VertexVertexIter; + typedef typename Kernel::VertexOHalfedgeIter VertexOHalfedgeIter; + typedef typename Kernel::VertexIHalfedgeIter VertexIHalfedgeIter; + typedef typename Kernel::VertexEdgeIter VertexEdgeIter; + typedef typename Kernel::VertexFaceIter VertexFaceIter; + typedef typename Kernel::FaceVertexIter FaceVertexIter; + typedef typename Kernel::FaceHalfedgeIter FaceHalfedgeIter; + typedef typename Kernel::FaceEdgeIter FaceEdgeIter; + typedef typename Kernel::FaceFaceIter FaceFaceIter; + + typedef typename Kernel::ConstVertexVertexIter ConstVertexVertexIter; + typedef typename Kernel::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter; + typedef typename Kernel::ConstVertexIHalfedgeIter ConstVertexIHalfedgeIter; + typedef typename Kernel::ConstVertexEdgeIter ConstVertexEdgeIter; + typedef typename Kernel::ConstVertexFaceIter ConstVertexFaceIter; + typedef typename Kernel::ConstFaceVertexIter ConstFaceVertexIter; + typedef typename Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter; + typedef typename Kernel::ConstFaceEdgeIter ConstFaceEdgeIter; + typedef typename Kernel::ConstFaceFaceIter ConstFaceFaceIter; + //@} + + + // --- constructor/destructor + PolyMeshT() {} + template + explicit PolyMeshT(const T& t) : Kernel(t) {} + virtual ~PolyMeshT() {} + + /** Uses default copy and assignment operator. + Use them to assign two meshes of \b equal type. + If the mesh types vary, use PolyMeshT::assign() instead. */ + + // --- creation --- + + /** + * \brief Adds a new default-initialized vertex. + * + * \sa new_vertex(const Point&), new_vertex_dirty() + */ + inline VertexHandle new_vertex() + { return Kernel::new_vertex(); } + + /** + * \brief Adds a new vertex initialized to a custom position. + * + * \sa new_vertex(), new_vertex_dirty() + */ + inline VertexHandle new_vertex(const Point& _p) + { + VertexHandle vh(Kernel::new_vertex()); + this->set_point(vh, _p); + return vh; + } + + /** + * Same as new_vertex(const Point&) but never shrinks, only enlarges the + * vertex property vectors. + * + * If you are rebuilding a mesh that you erased with ArrayKernel::clean() or + * ArrayKernel::clean_keep_reservation() using this method instead of + * new_vertex(const Point &) saves reallocation and reinitialization of + * property memory. + * + * \sa new_vertex(const Point &) + */ + inline VertexHandle new_vertex_dirty(const Point& _p) + { + VertexHandle vh(Kernel::new_vertex_dirty()); + this->set_point(vh, _p); + return vh; + } + + /// Alias for new_vertex(const Point&). + inline VertexHandle add_vertex(const Point& _p) + { return new_vertex(_p); } + + /// Alias for new_vertex_dirty(). + inline VertexHandle add_vertex_dirty(const Point& _p) + { return new_vertex_dirty(_p); } + + // --- normal vectors --- + + /** \name Normal vector computation + */ + //@{ + + /** \brief Compute normals for all primitives + * + * Calls update_face_normals() , update_halfedge_normals() and update_vertex_normals() if + * the normals (i.e. the properties) exist. + * + * \note Face normals are required to compute vertex and halfedge normals! + */ + void update_normals(); + + /// Update normal for face _fh + void update_normal(FaceHandle _fh) + { this->set_normal(_fh, calc_face_normal(_fh)); } + + /** \brief Update normal vectors for all faces. + * + * \attention Needs the Attributes::Normal attribute for faces. + * Call request_face_normals() before using it! + */ + void update_face_normals(); + + /** Calculate normal vector for face _fh. */ + virtual Normal calc_face_normal(FaceHandle _fh) const; + + /** Calculate normal vector for face (_p0, _p1, _p2). */ + Normal calc_face_normal(const Point& _p0, const Point& _p1, + const Point& _p2) const; + /// calculates the average of the vertices defining _fh + void calc_face_centroid(FaceHandle _fh, Point& _pt) const { + _pt = calc_face_centroid(_fh); + } + + /// Computes and returns the average of the vertices defining _gh + Point calc_face_centroid(FaceHandle _fh) const; + + /// Update normal for halfedge _heh + void update_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) + { this->set_normal(_heh, calc_halfedge_normal(_heh,_feature_angle)); } + + /** \brief Update normal vectors for all halfedges. + * + * Uses the existing face normals to compute halfedge normals + * + * \note Face normals have to be computed first! + * + * \attention Needs the Attributes::Normal attribute for faces and halfedges. + * Call request_face_normals() and request_halfedge_normals() before using it! + */ + void update_halfedge_normals(const double _feature_angle = 0.8); + + /** \brief Calculate halfedge normal for one specific halfedge + * + * Calculate normal vector for halfedge _heh. + * + * \note Face normals have to be computed first! + * + * \attention Needs the Attributes::Normal attribute for faces and vertices. + * Call request_face_normals() and request_halfedge_normals() before using it! + * + * @param _heh Handle of the halfedge + * @param _feature_angle If the dihedral angle across this edge is greater than this value, the edge is considered as a feature edge (angle in radians) + */ + virtual Normal calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) const; + + + /** identifies feature edges w.r.t. the minimal dihedral angle for feature edges (in radians) */ + /** and the status feature tag */ + bool is_estimated_feature_edge(HalfedgeHandle _heh, const double _feature_angle) const; + + /// Update normal for vertex _vh + void update_normal(VertexHandle _vh) + { this->set_normal(_vh, calc_vertex_normal(_vh)); } + + /** \brief Update normal vectors for all vertices. + * + * Uses existing face normals to calculate new vertex normals. + * + * \note Face normals have to be computed first! + * + * \attention Needs the Attributes::Normal attribute for faces and vertices. + * Call request_face_normals() and request_vertex_normals() before using it! + */ + void update_vertex_normals(); + + /** \brief Calculate vertex normal for one specific vertex + * + * Calculate normal vector for vertex _vh by averaging normals + * of adjacent faces. + * + * \note Face normals have to be computed first! + * + * \attention Needs the Attributes::Normal attribute for faces and vertices. + * Call request_face_normals() and request_vertex_normals() before using it! + * + * @param _vh Handle of the vertex + */ + Normal calc_vertex_normal(VertexHandle _vh) const; + + /** Different methods for calculation of the normal at _vh: + - ..._fast - the default one - the same as calc vertex_normal() + - needs the Attributes::Normal attribute for faces + - ..._correct - works properly for non-triangular meshes + - does not need any attributes + - ..._loop - calculates loop surface normals + - does not need any attributes */ + void calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const; + void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const; + void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const; + + + //@} + + // --- Geometry API - still in development --- + + /** Calculates the edge vector as the vector defined by + the halfedge with id #0 (see below) */ + void calc_edge_vector(EdgeHandle _eh, Normal& _edge_vec) const + { + _edge_vec = calc_edge_vector(_eh); + } + + /** Calculates the edge vector as the vector defined by + the halfedge with id #0 (see below) */ + Normal calc_edge_vector(EdgeHandle _eh) const + { + return calc_edge_vector(this->halfedge_handle(_eh,0)); + } + + /** Calculates the edge vector as the difference of the + the points defined by to_vertex_handle() and from_vertex_handle() */ + void calc_edge_vector(HalfedgeHandle _heh, Normal& _edge_vec) const + { + _edge_vec = calc_edge_vector(_heh); + } + + /** Calculates the edge vector as the difference of the + the points defined by to_vertex_handle() and from_vertex_handle() */ + Normal calc_edge_vector(HalfedgeHandle _heh) const + { + return this->point(this->to_vertex_handle(_heh)) - + this->point(this->from_vertex_handle(_heh)); + } + + // Calculates the length of the edge _eh + Scalar calc_edge_length(EdgeHandle _eh) const + { return calc_edge_length(this->halfedge_handle(_eh,0)); } + + /** Calculates the length of the edge _heh + */ + Scalar calc_edge_length(HalfedgeHandle _heh) const + { return (Scalar)sqrt(calc_edge_sqr_length(_heh)); } + + Scalar calc_edge_sqr_length(EdgeHandle _eh) const + { return calc_edge_sqr_length(this->halfedge_handle(_eh,0)); } + + Scalar calc_edge_sqr_length(HalfedgeHandle _heh) const + { + Normal edge_vec; + calc_edge_vector(_heh, edge_vec); + return sqrnorm(edge_vec); + } + + /** Calculates the midpoint of the halfedge _heh, defined by the positions of + the two incident vertices */ + Point calc_edge_midpoint(HalfedgeHandle _heh) const + { + VertexHandle vh0 = this->from_vertex_handle(_heh); + VertexHandle vh1 = this->to_vertex_handle(_heh); + return 0.5 * (this->point(vh0) + this->point(vh1)); + } + + /** Calculates the midpoint of the edge _eh, defined by the positions of the + two incident vertices */ + Point calc_edge_midpoint(EdgeHandle _eh) const + { + return calc_edge_midpoint(this->halfedge_handle(_eh, 0)); + } + + /** defines a consistent representation of a sector geometry: + the halfedge _in_heh defines the sector orientation + the vertex pointed by _in_heh defines the sector center + _vec0 and _vec1 are resp. the first and the second vectors defining the sector */ + void calc_sector_vectors(HalfedgeHandle _in_heh, Normal& _vec0, Normal& _vec1) const + { + calc_edge_vector(this->next_halfedge_handle(_in_heh), _vec0);//p2 - p1 + calc_edge_vector(this->opposite_halfedge_handle(_in_heh), _vec1);//p0 - p1 + } + + /** calculates the sector angle.\n + * The vertex pointed by _in_heh defines the sector center + * The angle will be calculated between the given halfedge and the next halfedge.\n + * Seen from the center vertex this will be the next halfedge in clockwise direction.\n + NOTE: only boundary concave sectors are treated correctly */ + Scalar calc_sector_angle(HalfedgeHandle _in_heh) const + { + Normal v0, v1; + calc_sector_vectors(_in_heh, v0, v1); + Scalar denom = norm(v0)*norm(v1); + if ( denom == Scalar(0)) + { + return 0; + } + Scalar cos_a = dot(v0 , v1) / denom; + if (this->is_boundary(_in_heh)) + {//determine if the boundary sector is concave or convex + FaceHandle fh(this->face_handle(this->opposite_halfedge_handle(_in_heh))); + Normal f_n(calc_face_normal(fh));//this normal is (for convex fh) OK + Scalar sign_a = dot(cross(v0, v1), f_n); + return angle(cos_a, sign_a); + } + else + { + return acos(sane_aarg(cos_a)); + } + } + + // calculate the cos and the sin of angle <(_in_heh,next_halfedge(_in_heh)) + /* + void calc_sector_angle_cos_sin(HalfedgeHandle _in_heh, Scalar& _cos_a, Scalar& _sin_a) const + { + Normal in_vec, out_vec; + calc_edge_vector(_in_heh, in_vec); + calc_edge_vector(next_halfedge_handle(_in_heh), out_vec); + Scalar denom = norm(in_vec)*norm(out_vec); + if (is_zero(denom)) + { + _cos_a = 1; + _sin_a = 0; + } + else + { + _cos_a = dot(in_vec, out_vec)/denom; + _sin_a = norm(cross(in_vec, out_vec))/denom; + } + } + */ + /** calculates the normal (non-normalized) of the face sector defined by + the angle <(_in_heh,next_halfedge(_in_heh)) */ + void calc_sector_normal(HalfedgeHandle _in_heh, Normal& _sector_normal) const + { + Normal vec0, vec1; + calc_sector_vectors(_in_heh, vec0, vec1); + _sector_normal = cross(vec0, vec1);//(p2-p1)^(p0-p1) + } + + /** calculates the area of the face sector defined by + the angle <(_in_heh,next_halfedge(_in_heh)) + NOTE: special cases (e.g. concave sectors) are not handled correctly */ + Scalar calc_sector_area(HalfedgeHandle _in_heh) const + { + Normal sector_normal; + calc_sector_normal(_in_heh, sector_normal); + return norm(sector_normal)/2; + } + + /** calculates the dihedral angle on the halfedge _heh + \attention Needs the Attributes::Normal attribute for faces */ + Scalar calc_dihedral_angle_fast(HalfedgeHandle _heh) const + { + // Make sure that we have face normals on the mesh + assert(Kernel::has_face_normals()); + + if (this->is_boundary(this->edge_handle(_heh))) + {//the dihedral angle at a boundary edge is 0 + return 0; + } + const Normal& n0 = this->normal(this->face_handle(_heh)); + const Normal& n1 = this->normal(this->face_handle(this->opposite_halfedge_handle(_heh))); + Normal he; + calc_edge_vector(_heh, he); + Scalar da_cos = dot(n0, n1); + //should be normalized, but we need only the sign + Scalar da_sin_sign = dot(cross(n0, n1), he); + return angle(da_cos, da_sin_sign); + } + + /** calculates the dihedral angle on the edge _eh + \attention Needs the Attributes::Normal attribute for faces */ + Scalar calc_dihedral_angle_fast(EdgeHandle _eh) const + { return calc_dihedral_angle_fast(this->halfedge_handle(_eh,0)); } + + // calculates the dihedral angle on the halfedge _heh + Scalar calc_dihedral_angle(HalfedgeHandle _heh) const + { + if (this->is_boundary(this->edge_handle(_heh))) + {//the dihedral angle at a boundary edge is 0 + return 0; + } + Normal n0, n1, he; + calc_sector_normal(_heh, n0); + calc_sector_normal(this->opposite_halfedge_handle(_heh), n1); + calc_edge_vector(_heh, he); + Scalar denom = norm(n0)*norm(n1); + if (denom == Scalar(0)) + { + return 0; + } + Scalar da_cos = dot(n0, n1)/denom; + //should be normalized, but we need only the sign + Scalar da_sin_sign = dot(cross(n0, n1), he); + return angle(da_cos, da_sin_sign); + } + + // calculates the dihedral angle on the edge _eh + Scalar calc_dihedral_angle(EdgeHandle _eh) const + { return calc_dihedral_angle(this->halfedge_handle(_eh,0)); } + + /** tags an edge as a feature if its dihedral angle is larger than _angle_tresh + returns the number of the found feature edges, requires edge_status property*/ + unsigned int find_feature_edges(Scalar _angle_tresh = OpenMesh::deg_to_rad(44.0)); + // --- misc --- + + /// Face split (= 1-to-n split) + inline void split(FaceHandle _fh, const Point& _p) + { Kernel::split(_fh, add_vertex(_p)); } + + inline void split(FaceHandle _fh, VertexHandle _vh) + { Kernel::split(_fh, _vh); } + + inline void split(EdgeHandle _eh, const Point& _p) + { Kernel::split_edge(_eh, add_vertex(_p)); } + + inline void split(EdgeHandle _eh, VertexHandle _vh) + { Kernel::split_edge(_eh, _vh); } + +private: + struct PointIs3DTag {}; + struct PointIsNot3DTag {}; + Normal calc_face_normal_impl(FaceHandle, PointIs3DTag) const; + Normal calc_face_normal_impl(FaceHandle, PointIsNot3DTag) const; + Normal calc_face_normal_impl(const Point&, const Point&, const Point&, PointIs3DTag) const; + Normal calc_face_normal_impl(const Point&, const Point&, const Point&, PointIsNot3DTag) const; +}; + +/** + * @brief Cast a mesh with different but identical traits into each other. + * + * Example: + * @code{.cpp} + * struct TriTraits1 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * }; + * struct TriTraits2 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * }; + * struct TriTraits3 : public OpenMesh::DefaultTraits { + * typedef Vec3f Point; + * }; + * + * TriMesh_ArrayKernelT a; + * TriMesh_ArrayKernelT &b = mesh_cast&>(a); // OK + * TriMesh_ArrayKernelT &c = mesh_cast&>(a); // ERROR + * @endcode + * + * @see MeshCast + * + * @param rhs + * @return + */ +template +LHS mesh_cast(PolyMeshT &rhs) { + return MeshCast&>::cast(rhs); +} + +template +LHS mesh_cast(PolyMeshT *rhs) { + return MeshCast*>::cast(rhs); +} + +template +const LHS mesh_cast(const PolyMeshT &rhs) { + return MeshCast&>::cast(rhs); +} + +template +const LHS mesh_cast(const PolyMeshT *rhs) { + return MeshCast*>::cast(rhs); +} + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C) +# define OPENMESH_POLYMESH_TEMPLATES +# include "PolyMeshT.cc" +#endif +//============================================================================= +#endif // OPENMESH_POLYMESHT_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh new file mode 100644 index 0000000..d884ae0 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh @@ -0,0 +1,118 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS PolyMesh_ArrayKernelT +// +//============================================================================= + + +#ifndef OPENMESH_POLY_MESH_ARRAY_KERNEL_HH +#define OPENMESH_POLY_MESH_ARRAY_KERNEL_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + +template +class TriMesh_ArrayKernelT; +//== CLASS DEFINITION ========================================================= + +/// Helper class to build a PolyMesh-type +template +struct PolyMesh_ArrayKernel_GeneratorT +{ + typedef FinalMeshItemsT MeshItems; + typedef AttribKernelT AttribKernel; + typedef PolyMeshT Mesh; +}; + + +/** \class PolyMesh_ArrayKernelT PolyMesh_ArrayKernelT.hh + + \ingroup mesh_types_group + Polygonal mesh based on the ArrayKernel. + \see OpenMesh::PolyMeshT + \see OpenMesh::ArrayKernel +*/ +template +class PolyMesh_ArrayKernelT + : public PolyMesh_ArrayKernel_GeneratorT::Mesh +{ +public: + PolyMesh_ArrayKernelT() {} + template + PolyMesh_ArrayKernelT( const TriMesh_ArrayKernelT & t) + { + //assign the connectivity and standard properties + this->assign(t, true); + + } +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_POLY_MESH_ARRAY_KERNEL_HH +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/Status.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Status.hh new file mode 100644 index 0000000..19e474d --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Status.hh @@ -0,0 +1,183 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS Status +// +//============================================================================= + + +#ifndef OPENMESH_ATTRIBUTE_STATUS_HH +#define OPENMESH_ATTRIBUTE_STATUS_HH + + +//== INCLUDES ================================================================= + +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { +namespace Attributes { + + +//== CLASS DEFINITION ======================================================== + + +/** Status bits used by the Status class. + * \see OpenMesh::Attributes::StatusInfo + */ +enum StatusBits { + + DELETED = 1, ///< Item has been deleted + LOCKED = 2, ///< Item is locked. + SELECTED = 4, ///< Item is selected. + HIDDEN = 8, ///< Item is hidden. + FEATURE = 16, ///< Item is a feature or belongs to a feature. + TAGGED = 32, ///< Item is tagged. + TAGGED2 = 64, ///< Alternate bit for tagging an item. + FIXEDNONMANIFOLD = 128, ///< Item was non-two-manifold and had to be fixed + UNUSED = 256 ///< Unused +}; + + +/** \class StatusInfo Status.hh + * + * Add status information to a base class. + * + * \see StatusBits + */ +class StatusInfo +{ +public: + + typedef unsigned int value_type; + + StatusInfo() : status_(0) {} + + /// is deleted ? + bool deleted() const { return is_bit_set(DELETED); } + /// set deleted + void set_deleted(bool _b) { change_bit(DELETED, _b); } + + + /// is locked ? + bool locked() const { return is_bit_set(LOCKED); } + /// set locked + void set_locked(bool _b) { change_bit(LOCKED, _b); } + + + /// is selected ? + bool selected() const { return is_bit_set(SELECTED); } + /// set selected + void set_selected(bool _b) { change_bit(SELECTED, _b); } + + + /// is hidden ? + bool hidden() const { return is_bit_set(HIDDEN); } + /// set hidden + void set_hidden(bool _b) { change_bit(HIDDEN, _b); } + + + /// is feature ? + bool feature() const { return is_bit_set(FEATURE); } + /// set feature + void set_feature(bool _b) { change_bit(FEATURE, _b); } + + + /// is tagged ? + bool tagged() const { return is_bit_set(TAGGED); } + /// set tagged + void set_tagged(bool _b) { change_bit(TAGGED, _b); } + + + /// is tagged2 ? This is just one more tag info. + bool tagged2() const { return is_bit_set(TAGGED2); } + /// set tagged + void set_tagged2(bool _b) { change_bit(TAGGED2, _b); } + + + /// is fixed non-manifold ? + bool fixed_nonmanifold() const { return is_bit_set(FIXEDNONMANIFOLD); } + /// set fixed non-manifold + void set_fixed_nonmanifold(bool _b) { change_bit(FIXEDNONMANIFOLD, _b); } + + + /// return whole status + unsigned int bits() const { return status_; } + /// set whole status at once + void set_bits(unsigned int _bits) { status_ = _bits; } + + + /// is a certain bit set ? + bool is_bit_set(unsigned int _s) const { return (status_ & _s) > 0; } + /// set a certain bit + void set_bit(unsigned int _s) { status_ |= _s; } + /// unset a certain bit + void unset_bit(unsigned int _s) { status_ &= ~_s; } + /// set or unset a certain bit + void change_bit(unsigned int _s, bool _b) { + if (_b) status_ |= _s; else status_ &= ~_s; } + + +private: + + value_type status_; +}; + + +//============================================================================= +} // namespace Attributes +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_ATTRIBUTE_STATUS_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/Traits.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Traits.hh new file mode 100644 index 0000000..a0fbe01 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/Traits.hh @@ -0,0 +1,245 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +/** \file Core/Mesh/Traits.hh + This file defines the default traits and some convenience macros. +*/ + + +//============================================================================= +// +// CLASS Traits +// +//============================================================================= + +#ifndef OPENMESH_TRAITS_HH +#define OPENMESH_TRAITS_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/// Macro for defining the vertex attributes. See \ref mesh_type. +#define VertexAttributes(_i) enum { VertexAttributes = _i } + +/// Macro for defining the halfedge attributes. See \ref mesh_type. +#define HalfedgeAttributes(_i) enum { HalfedgeAttributes = _i } + +/// Macro for defining the edge attributes. See \ref mesh_type. +#define EdgeAttributes(_i) enum { EdgeAttributes = _i } + +/// Macro for defining the face attributes. See \ref mesh_type. +#define FaceAttributes(_i) enum { FaceAttributes = _i } + +/// Macro for defining the vertex traits. See \ref mesh_type. +#define VertexTraits \ + template struct VertexT : public Base + +/// Macro for defining the halfedge traits. See \ref mesh_type. +#define HalfedgeTraits \ + template struct HalfedgeT : public Base + +/// Macro for defining the edge traits. See \ref mesh_type. +#define EdgeTraits \ + template struct EdgeT : public Base + +/// Macro for defining the face traits. See \ref mesh_type. +#define FaceTraits \ + template struct FaceT : public Base + + + +//== CLASS DEFINITION ========================================================= + + +/** \class DefaultTraits Traits.hh + + Base class for all traits. All user traits should be derived from + this class. You may enrich all basic items by additional + properties or define one or more of the types \c Point, \c Normal, + \c TexCoord, or \c Color. + + \see The Mesh docu section on \ref mesh_type. + \see Traits.hh for a list of macros for traits classes. +*/ +struct DefaultTraits +{ + /// The default coordinate type is OpenMesh::Vec3f. + typedef Vec3f Point; + + /// The default normal type is OpenMesh::Vec3f. + typedef Vec3f Normal; + + /// The default 1D texture coordinate type is float. + typedef float TexCoord1D; + /// The default 2D texture coordinate type is OpenMesh::Vec2f. + typedef Vec2f TexCoord2D; + /// The default 3D texture coordinate type is OpenMesh::Vec3f. + typedef Vec3f TexCoord3D; + + /// The default texture index type + typedef int TextureIndex; + + /// The default color type is OpenMesh::Vec3uc. + typedef Vec3uc Color; + +#ifndef DOXY_IGNORE_THIS + VertexTraits {}; + HalfedgeTraits {}; + EdgeTraits {}; + FaceTraits {}; +#endif + + VertexAttributes(0); + HalfedgeAttributes(Attributes::PrevHalfedge); + EdgeAttributes(0); + FaceAttributes(0); +}; + + +//== CLASS DEFINITION ========================================================= + + +/** Helper class to merge two mesh traits. + * \internal + * + * With the help of this class it's possible to merge two mesh traits. + * Whereby \c _Traits1 overrides equally named symbols of \c _Traits2. + * + * For your convenience use the provided defines \c OM_Merge_Traits + * and \c OM_Merge_Traits_In_Template instead. + * + * \see OM_Merge_Traits, OM_Merge_Traits_In_Template + */ +template struct MergeTraits +{ +#ifndef DOXY_IGNORE_THIS + struct Result + { + // Mipspro needs this (strange) typedef + typedef _Traits1 T1; + typedef _Traits2 T2; + + + VertexAttributes ( T1::VertexAttributes | T2::VertexAttributes ); + HalfedgeAttributes ( T1::HalfedgeAttributes | T2::HalfedgeAttributes ); + EdgeAttributes ( T1::EdgeAttributes | T2::EdgeAttributes ); + FaceAttributes ( T1::FaceAttributes | T2::FaceAttributes ); + + + typedef typename T1::Point Point; + typedef typename T1::Normal Normal; + typedef typename T1::Color Color; + typedef typename T1::TexCoord TexCoord; + + template class VertexT : + public T1::template VertexT< + typename T2::template VertexT, Refs> + {}; + + template class HalfedgeT : + public T1::template HalfedgeT< + typename T2::template HalfedgeT, Refs> + {}; + + + template class EdgeT : + public T1::template EdgeT< + typename T2::template EdgeT, Refs> + {}; + + + template class FaceT : + public T1::template FaceT< + typename T2::template FaceT, Refs> + {}; + }; +#endif +}; + + +/** + Macro for merging two traits classes _S1 and _S2 into one traits class _D. + Note that in case of ambiguities class _S1 overrides _S2, especially + the point/normal/color/texcoord type to be used is taken from _S1::Point / + _S1::Normal / _S1::Color / _S1::TexCoord +*/ +#define OM_Merge_Traits(_S1, _S2, _D) \ + typedef OpenMesh::MergeTraits<_S1, _S2>::Result _D; + + +/** + Macro for merging two traits classes _S1 and _S2 into one traits class _D. + Same as OM_Merge_Traits, but this can be used inside template classes. +*/ +#define OM_Merge_Traits_In_Template(_S1, _S2, _D) \ + typedef typename OpenMesh::MergeTraits<_S1, _S2>::Result _D; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_TRAITS_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriConnectivity.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriConnectivity.hh new file mode 100644 index 0000000..197420d --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriConnectivity.hh @@ -0,0 +1,211 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_TRICONNECTIVITY_HH +#define OPENMESH_TRICONNECTIVITY_HH + +#include + +namespace OpenMesh { + +/** \brief Connectivity Class for Triangle Meshes +*/ +class OPENMESHDLLEXPORT TriConnectivity : public PolyConnectivity +{ +public: + + TriConnectivity() {} + virtual ~TriConnectivity() {} + + inline static bool is_triangles() + { return true; } + + /** assign_connectivity() methods. See ArrayKernel::assign_connectivity() + for more details. When the source connectivity is not triangles, in + addition "fan" connectivity triangulation is performed*/ + inline void assign_connectivity(const TriConnectivity& _other) + { PolyConnectivity::assign_connectivity(_other); } + + inline void assign_connectivity(const PolyConnectivity& _other) + { + PolyConnectivity::assign_connectivity(_other); + triangulate(); + } + + /** \name Addding items to a mesh + */ + + //@{ + + /** \brief Add a face with arbitrary valence to the triangle mesh + * + * Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't + * triangles will be triangulated and added. In this case an + * invalid face handle will be returned. + * + * + * */ + FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); + + /** \brief Add a face with arbitrary valence to the triangle mesh + * + * Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't + * triangles will be triangulated and added. In this case an + * invalid face handle will be returned. + * + * + * */ + FaceHandle add_face(const std::vector& _vhandles); + + /** \brief Add a face to the mesh (triangle) + * + * This function adds a triangle to the mesh. The triangle is passed directly + * to the underlying PolyConnectivity as we don't explicitly need to triangulate something. + * + * @param _vh0 VertexHandle 1 + * @param _vh1 VertexHandle 2 + * @param _vh2 VertexHandle 3 + * @return FaceHandle of the added face (invalid, if the operation failed) + */ + FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); + + //@} + + /** Returns the opposite vertex to the halfedge _heh in the face + referenced by _heh returns InvalidVertexHandle if the _heh is + boundary */ + inline VertexHandle opposite_vh(HalfedgeHandle _heh) const + { + return is_boundary(_heh) ? InvalidVertexHandle : + to_vertex_handle(next_halfedge_handle(_heh)); + } + + /** Returns the opposite vertex to the opposite halfedge of _heh in + the face referenced by it returns InvalidVertexHandle if the + opposite halfedge is boundary */ + VertexHandle opposite_he_opposite_vh(HalfedgeHandle _heh) const + { return opposite_vh(opposite_halfedge_handle(_heh)); } + + /** \name Topology modifying operators + */ + //@{ + + + /** Returns whether collapsing halfedge _heh is ok or would lead to + topological inconsistencies. + \attention This method need the Attributes::Status attribute and + changes the \em tagged bit. */ + bool is_collapse_ok(HalfedgeHandle _heh); + + /// Vertex Split: inverse operation to collapse(). + HalfedgeHandle vertex_split(VertexHandle v0, VertexHandle v1, + VertexHandle vl, VertexHandle vr); + + /// Check whether flipping _eh is topologically correct. + bool is_flip_ok(EdgeHandle _eh) const; + + /** Flip edge _eh. + Check for topological correctness first using is_flip_ok(). */ + void flip(EdgeHandle _eh); + + + /** \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, halfedges, and faces will be undefined! + * + * @param _eh Edge handle that should be splitted + * @param _vh Vertex handle that will be inserted at the edge + */ + void split(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 will be adjusted to the properties of the original edge + * \note The properties of the new faces and halfedges will be undefined + * + * @param _eh Edge handle that should be splitted + * @param _vh Vertex handle that will be inserted at the edge + */ + void split_copy(EdgeHandle _eh, VertexHandle _vh); + + /** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function). + * + * @param _fh Face handle that should be splitted + * @param _vh Vertex handle that will be inserted at the face + */ + inline void split(FaceHandle _fh, VertexHandle _vh) + { PolyConnectivity::split(_fh, _vh); } + + /** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function). + * + * @param _fh Face handle that should be splitted + * @param _vh Vertex handle that will be inserted at the face + */ + inline void split_copy(FaceHandle _fh, VertexHandle _vh) + { PolyConnectivity::split_copy(_fh, _vh); } + + //@} + +private: + /// Helper for vertex split + HalfedgeHandle insert_loop(HalfedgeHandle _hh); + /// Helper for vertex split + HalfedgeHandle insert_edge(VertexHandle _vh, + HalfedgeHandle _h0, HalfedgeHandle _h1); +}; + +} + +#endif//OPENMESH_TRICONNECTIVITY_HH diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.hh new file mode 100644 index 0000000..1865f30 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.hh @@ -0,0 +1,438 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS TriMeshT +// +//============================================================================= + + +#ifndef OPENMESH_TRIMESH_HH +#define OPENMESH_TRIMESH_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/** \class TriMeshT TriMeshT.hh + + Base type for a triangle mesh. + + Base type for a triangle mesh, parameterized by a mesh kernel. The + mesh inherits all methods from the kernel class and the + more general polygonal mesh PolyMeshT. Therefore it provides + the same types for items, handles, iterators and so on. + + \param Kernel: template argument for the mesh kernel + \note You should use the predefined mesh-kernel combinations in + \ref mesh_types_group + \see \ref mesh_type + \see OpenMesh::PolyMeshT +*/ + +template +class TriMeshT : public PolyMeshT +{ + +public: + + + // self + typedef TriMeshT This; + typedef PolyMeshT PolyMesh; + + //@{ + /// Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT ) + enum { IsPolyMesh = 0 }; + enum { IsTriMesh = 1 }; + static bool is_polymesh() { return false; } + static bool is_trimesh() { return true; } + //@} + + //--- items --- + + typedef typename PolyMesh::Scalar Scalar; + typedef typename PolyMesh::Point Point; + typedef typename PolyMesh::Normal Normal; + typedef typename PolyMesh::Color Color; + typedef typename PolyMesh::TexCoord1D TexCoord1D; + typedef typename PolyMesh::TexCoord2D TexCoord2D; + typedef typename PolyMesh::TexCoord3D TexCoord3D; + typedef typename PolyMesh::Vertex Vertex; + typedef typename PolyMesh::Halfedge Halfedge; + typedef typename PolyMesh::Edge Edge; + typedef typename PolyMesh::Face Face; + + + //--- handles --- + + typedef typename PolyMesh::VertexHandle VertexHandle; + typedef typename PolyMesh::HalfedgeHandle HalfedgeHandle; + typedef typename PolyMesh::EdgeHandle EdgeHandle; + typedef typename PolyMesh::FaceHandle FaceHandle; + + + //--- iterators --- + + typedef typename PolyMesh::VertexIter VertexIter; + typedef typename PolyMesh::ConstVertexIter ConstVertexIter; + typedef typename PolyMesh::EdgeIter EdgeIter; + typedef typename PolyMesh::ConstEdgeIter ConstEdgeIter; + typedef typename PolyMesh::FaceIter FaceIter; + typedef typename PolyMesh::ConstFaceIter ConstFaceIter; + + + + //--- circulators --- + + typedef typename PolyMesh::VertexVertexIter VertexVertexIter; + typedef typename PolyMesh::VertexOHalfedgeIter VertexOHalfedgeIter; + typedef typename PolyMesh::VertexIHalfedgeIter VertexIHalfedgeIter; + typedef typename PolyMesh::VertexEdgeIter VertexEdgeIter; + typedef typename PolyMesh::VertexFaceIter VertexFaceIter; + typedef typename PolyMesh::FaceVertexIter FaceVertexIter; + typedef typename PolyMesh::FaceHalfedgeIter FaceHalfedgeIter; + typedef typename PolyMesh::FaceEdgeIter FaceEdgeIter; + typedef typename PolyMesh::FaceFaceIter FaceFaceIter; + typedef typename PolyMesh::ConstVertexVertexIter ConstVertexVertexIter; + typedef typename PolyMesh::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter; + typedef typename PolyMesh::ConstVertexIHalfedgeIter ConstVertexIHalfedgeIter; + typedef typename PolyMesh::ConstVertexEdgeIter ConstVertexEdgeIter; + typedef typename PolyMesh::ConstVertexFaceIter ConstVertexFaceIter; + typedef typename PolyMesh::ConstFaceVertexIter ConstFaceVertexIter; + typedef typename PolyMesh::ConstFaceHalfedgeIter ConstFaceHalfedgeIter; + typedef typename PolyMesh::ConstFaceEdgeIter ConstFaceEdgeIter; + typedef typename PolyMesh::ConstFaceFaceIter ConstFaceFaceIter; + + // --- constructor/destructor + + /// Default constructor + TriMeshT() : PolyMesh() {} + explicit TriMeshT(PolyMesh rhs) : PolyMesh((rhs.triangulate(), rhs)) + { + } + + /// Destructor + virtual ~TriMeshT() {} + + //--- halfedge collapse / vertex split --- + + /** \brief Vertex Split: inverse operation to collapse(). + * + * Insert the new vertex at position v0. The vertex will be added + * as the inverse of the vertex split. The faces above the split + * will be correctly attached to the two new edges + * + * Before: + * v_l v0 v_r + * x x x + * \ / + * \ / + * \ / + * \ / + * \ / + * \ / + * x + * v1 + * + * After: + * v_l v0 v_r + * x------x------x + * \ | / + * \ | / + * \ | / + * \ | / + * \ | / + * \|/ + * x + * v1 + * + * @param _v0_point Point position for the new point + * @param _v1 Vertex that will be split + * @param _vl Left vertex handle + * @param _vr Right vertex handle + * @return Newly inserted halfedge + */ + inline HalfedgeHandle vertex_split(Point _v0_point, VertexHandle _v1, + VertexHandle _vl, VertexHandle _vr) + { return PolyMesh::vertex_split(this->add_vertex(_v0_point), _v1, _vl, _vr); } + + /** \brief Vertex Split: inverse operation to collapse(). + * + * Insert the new vertex at position v0. The vertex will be added + * as the inverse of the vertex split. The faces above the split + * will be correctly attached to the two new edges + * + * Before: + * v_l v0 v_r + * x x x + * \ / + * \ / + * \ / + * \ / + * \ / + * \ / + * x + * v1 + * + * After: + * v_l v0 v_r + * x------x------x + * \ | / + * \ | / + * \ | / + * \ | / + * \ | / + * \|/ + * x + * v1 + * + * @param _v0 Vertex handle for the newly inserted point (Input has to be unconnected!) + * @param _v1 Vertex that will be split + * @param _vl Left vertex handle + * @param _vr Right vertex handle + * @return Newly inserted halfedge + */ + inline HalfedgeHandle vertex_split(VertexHandle _v0, VertexHandle _v1, + VertexHandle _vl, VertexHandle _vr) + { return PolyMesh::vertex_split(_v0, _v1, _vl, _vr); } + + /** \brief Edge split (= 2-to-4 split) + * + * The properties of the new edges will be undefined! + * + * + * @param _eh Edge handle that should be splitted + * @param _p New point position that will be inserted at the edge + * @return Vertex handle of the newly added vertex + */ + inline VertexHandle split(EdgeHandle _eh, const Point& _p) + { + //Do not call PolyMeshT function below as this does the wrong operation + const VertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh; + } + + /** \brief Edge split (= 2-to-4 split) + * + * The properties of the new edges will be adjusted to the properties of the original edge + * + * @param _eh Edge handle that should be splitted + * @param _p New point position that will be inserted at the edge + * @return Vertex handle of the newly added vertex + */ + inline VertexHandle split_copy(EdgeHandle _eh, const Point& _p) + { + //Do not call PolyMeshT function below as this does the wrong operation + const VertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh; + } + + /** \brief Edge split (= 2-to-4 split) + * + * The properties of the new edges will be undefined! + * + * @param _eh Edge handle that should be splitted + * @param _vh Vertex handle that will be inserted at the edge + */ + inline void split(EdgeHandle _eh, VertexHandle _vh) + { + //Do not call PolyMeshT function below as this does the wrong operation + Kernel::split(_eh, _vh); + } + + /** \brief Edge split (= 2-to-4 split) + * + * The properties of the new edges will be adjusted to the properties of the original edge + * + * @param _eh Edge handle that should be splitted + * @param _vh Vertex handle that will be inserted at the edge + */ + inline void split_copy(EdgeHandle _eh, VertexHandle _vh) + { + //Do not call PolyMeshT function below as this does the wrong operation + Kernel::split_copy(_eh, _vh); + } + + /** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function). + * + * The properties of the new faces will be undefined! + * + * @param _fh Face handle that should be splitted + * @param _p New point position that will be inserted in the face + * + * @return Vertex handle of the new vertex + */ + inline VertexHandle split(FaceHandle _fh, const Point& _p) + { const VertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; } + + /** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function). + * + * The properties of the new faces will be adjusted to the properties of the original face + * + * @param _fh Face handle that should be splitted + * @param _p New point position that will be inserted in the face + * + * @return Vertex handle of the new vertex + */ + inline VertexHandle split_copy(FaceHandle _fh, const Point& _p) + { const VertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; } + + + /** \brief Face split (= 1-to-4) split, splits edges at midpoints and adds 4 new faces in the interior). + * + * @param _fh Face handle that should be splitted + */ + inline void split(FaceHandle _fh) + { + // Collect halfedges of face + HalfedgeHandle he0 = this->halfedge_handle(_fh); + HalfedgeHandle he1 = this->next_halfedge_handle(he0); + HalfedgeHandle he2 = this->next_halfedge_handle(he1); + + EdgeHandle eh0 = this->edge_handle(he0); + EdgeHandle eh1 = this->edge_handle(he1); + EdgeHandle eh2 = this->edge_handle(he2); + + // Collect points of face + VertexHandle p0 = this->to_vertex_handle(he0); + VertexHandle p1 = this->to_vertex_handle(he1); + VertexHandle p2 = this->to_vertex_handle(he2); + + // Calculate midpoint coordinates + const Point new0 = (this->point(p0) + this->point(p2)) * static_cast::value_type >(0.5); + const Point new1 = (this->point(p0) + this->point(p1)) * static_cast::value_type >(0.5); + const Point new2 = (this->point(p1) + this->point(p2)) * static_cast::value_type >(0.5); + + // Add vertices at midpoint coordinates + VertexHandle v0 = this->add_vertex(new0); + VertexHandle v1 = this->add_vertex(new1); + VertexHandle v2 = this->add_vertex(new2); + + const bool split0 = !this->is_boundary(eh0); + const bool split1 = !this->is_boundary(eh1); + const bool split2 = !this->is_boundary(eh2); + + // delete original face + this->delete_face(_fh); + + // split boundary edges of deleted face ( if not boundary ) + if ( split0 ) { + this->split(eh0,v0); + } + + if ( split1 ) { + this->split(eh1,v1); + } + + if ( split2 ) { + this->split(eh2,v2); + } + + // Retriangulate + this->add_face(v0 , p0, v1); + this->add_face(p2, v0 , v2); + this->add_face(v2,v1,p1); + this->add_face(v2 , v0, v1); + } + + /** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function). + * + * The properties of the new faces will be undefined! + * + * @param _fh Face handle that should be splitted + * @param _vh Vertex handle that will be inserted at the face + */ + inline void split(FaceHandle _fh, VertexHandle _vh) + { PolyMesh::split(_fh, _vh); } + + /** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function). + * + * The properties of the new faces will be adjusted to the properties of the original face + * + * @param _fh Face handle that should be splitted + * @param _vh Vertex handle that will be inserted at the face + */ + inline void split_copy(FaceHandle _fh, VertexHandle _vh) + { PolyMesh::split_copy(_fh, _vh); } + + /** \name Normal vector computation + */ + //@{ + + /** Calculate normal vector for face _fh (specialized for TriMesh). */ + Normal calc_face_normal(FaceHandle _fh) const; + + //@} +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_TRIMESH_C) +#define OPENMESH_TRIMESH_TEMPLATES +#include "TriMeshT.cc" +#endif +//============================================================================= +#endif // OPENMESH_TRIMESH_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh new file mode 100644 index 0000000..0c648bf --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh @@ -0,0 +1,117 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// CLASS TriMesh_ArrayKernelT +// +//============================================================================= + + +#ifndef OPENMESH_TRIMESH_ARRAY_KERNEL_HH +#define OPENMESH_TRIMESH_ARRAY_KERNEL_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + +template +class PolyMesh_ArrayKernelT; +//== CLASS DEFINITION ========================================================= + + +/// Helper class to create a TriMesh-type based on ArrayKernelT +template +struct TriMesh_ArrayKernel_GeneratorT +{ + typedef FinalMeshItemsT MeshItems; + typedef AttribKernelT AttribKernel; + typedef TriMeshT Mesh; +}; + + + +/** \ingroup mesh_types_group + Triangle mesh based on the ArrayKernel. + \see OpenMesh::TriMeshT + \see OpenMesh::ArrayKernelT +*/ +template +class TriMesh_ArrayKernelT + : public TriMesh_ArrayKernel_GeneratorT::Mesh +{ +public: + TriMesh_ArrayKernelT() {} + template + TriMesh_ArrayKernelT( const PolyMesh_ArrayKernelT & t) + { + //assign the connectivity and standard properties + this->assign(t,true); + } +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_TRIMESH_ARRAY_KERNEL_HH +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/circulators_header.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/circulators_header.hh new file mode 100644 index 0000000..72bab07 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/circulators_header.hh @@ -0,0 +1,98 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_CIRCULATORS_HH +#define OPENMESH_CIRCULATORS_HH + +//============================================================================= +// +// Vertex and Face circulators for PolyMesh/TriMesh +// +//============================================================================= + + + +//== INCLUDES ================================================================= + +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace Iterators { + + +//== FORWARD DECLARATIONS ===================================================== + + +template class VertexVertexIterT; +template class VertexIHalfedgeIterT; +template class VertexOHalfedgeIterT; +template class VertexEdgeIterT; +template class VertexFaceIterT; + +template class ConstVertexVertexIterT; +template class ConstVertexIHalfedgeIterT; +template class ConstVertexOHalfedgeIterT; +template class ConstVertexEdgeIterT; +template class ConstVertexFaceIterT; + +template class FaceVertexIterT; +template class FaceHalfedgeIterT; +template class FaceEdgeIterT; +template class FaceFaceIterT; + +template class ConstFaceVertexIterT; +template class ConstFaceHalfedgeIterT; +template class ConstFaceEdgeIterT; +template class ConstFaceFaceIterT; + + + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/circulators_template.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/circulators_template.hh new file mode 100644 index 0000000..97a2171 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/circulators_template.hh @@ -0,0 +1,190 @@ +//== CLASS DEFINITION ========================================================= + + +/** \class CirculatorT CirculatorsT.hh + Circulator. +*/ + +template +class CirculatorT +{ + public: + + + //--- Typedefs --- + + typedef typename Mesh::HalfedgeHandle HalfedgeHandle; + + typedef TargetType value_type; + typedef TargetHandle value_handle; + +#if IsConst + typedef const Mesh& mesh_ref; + typedef const Mesh* mesh_ptr; + typedef const TargetType& reference; + typedef const TargetType* pointer; +#else + typedef Mesh& mesh_ref; + typedef Mesh* mesh_ptr; + typedef TargetType& reference; + typedef TargetType* pointer; +#endif + + + + /// Default constructor + CirculatorT() : mesh_(0), active_(false) {} + + + /// Construct with mesh and a SourceHandle + CirculatorT(mesh_ref _mesh, SourceHandle _start) : + mesh_(&_mesh), + start_(_mesh.halfedge_handle(_start)), + heh_(start_), + active_(false) + { post_init; } + + + /// Construct with mesh and start halfedge + CirculatorT(mesh_ref _mesh, HalfedgeHandle _heh) : + mesh_(&_mesh), + start_(_heh), + heh_(_heh), + active_(false) + { post_init; } + + + /// Copy constructor + CirculatorT(const CirculatorT& _rhs) : + mesh_(_rhs.mesh_), + start_(_rhs.start_), + heh_(_rhs.heh_), + active_(_rhs.active_) + { post_init; } + + + /// Assignment operator + CirculatorT& operator=(const CirculatorT& _rhs) + { + mesh_ = _rhs.mesh_; + start_ = _rhs.start_; + heh_ = _rhs.heh_; + active_ = _rhs.active_; + return *this; + } + + +#if IsConst + /// construct from non-const circulator type + CirculatorT(const NonConstCircT& _rhs) : + mesh_(_rhs.mesh_), + start_(_rhs.start_), + heh_(_rhs.heh_), + active_(_rhs.active_) + { post_init; } + + + /// assign from non-const circulator + CirculatorT& operator=(const NonConstCircT& _rhs) + { + mesh_ = _rhs.mesh_; + start_ = _rhs.start_; + heh_ = _rhs.heh_; + active_ = _rhs.active_; + return *this; + } +#else + friend class ConstCircT; +#endif + + + /// Equal ? + bool operator==(const CirculatorT& _rhs) const { + return ((mesh_ == _rhs.mesh_) && + (start_ == _rhs.start_) && + (heh_ == _rhs.heh_) && + (active_ == _rhs.active_)); + } + + + /// Not equal ? + bool operator!=(const CirculatorT& _rhs) const { + return !operator==(_rhs); + } + + + /// Pre-Increment (next cw target) + CirculatorT& operator++() { + assert(mesh_); + active_ = true; + increment; + return *this; + } + + + /// Pre-Decrement (next ccw target) + CirculatorT& operator--() { + assert(mesh_); + active_ = true; + decrement; + return *this; + } + + + /** Get the current halfedge. There are \c Vertex*Iters and \c + Face*Iters. For both the current state is defined by the + current halfedge. This is what this method returns. + */ + HalfedgeHandle current_halfedge_handle() const { + return heh_; + } + + + /// Return the handle of the current target. + TargetHandle handle() const { + assert(mesh_); + return get_handle; + } + + + /// Cast to the handle of the current target. + operator TargetHandle() const { + assert(mesh_); + return get_handle; + } + + + /// Return a reference to the current target. + reference operator*() const { + assert(mesh_); + return mesh_->deref(handle()); + } + + + /// Return a pointer to the current target. + pointer operator->() const { + assert(mesh_); + return &mesh_->deref(handle()); + } + + + /** Returns whether the circulator is still valid. + After one complete round around a vertex/face the circulator becomes + invalid, i.e. this function will return \c false. Nevertheless you + can continue circulating. This method just tells you whether you + have completed the first round. + */ + operator bool() const { + return heh_.is_valid() && ((start_ != heh_) || (!active_)); + } + + +private: + + mesh_ptr mesh_; + HalfedgeHandle start_, heh_; + bool active_; +}; + + + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/footer.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/footer.hh new file mode 100644 index 0000000..8e2a9c1 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/footer.hh @@ -0,0 +1,6 @@ +//============================================================================= +} // namespace Iterators +} // namespace OpenMesh +//============================================================================= +#endif +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/generate.sh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/generate.sh new file mode 100644 index 0000000..3bcaffd --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/generate.sh @@ -0,0 +1,175 @@ +#!/bin/bash + +#------------------------------------------------------------------------------ + + +# generate_iterator( TargetType, n_elements, has_element_status ) +function generate_iterator +{ + NonConstIter=$1"IterT" + ConstIter="Const"$NonConstIter + TargetType="typename Mesh::"$1 + TargetHandle="typename Mesh::"$1"Handle" + + + cat iterators_template.hh \ + | sed -e "s/IteratorT/$NonConstIter/; s/IteratorT/$NonConstIter/; + s/NonConstIterT/$NonConstIter/; + s/ConstIterT/$ConstIter/; + s/TargetType/$TargetType/; + s/TargetHandle/$TargetHandle/; + s/IsConst/0/; + s/n_elements/$2/; + s/has_element_status/$3/;" + + + cat iterators_template.hh \ + | sed -e "s/IteratorT/$ConstIter/; s/IteratorT/$ConstIter/; + s/NonConstIterT/$NonConstIter/; + s/ConstIterT/$ConstIter/; + s/TargetType/$TargetType/; + s/TargetHandle/$TargetHandle/; + s/IsConst/1/; + s/n_elements/$2/; + s/has_element_status/$3/;" +} + + +#------------------------------------------------------------------------------ + + +# generate_circulator( NonConstName, SourceType, TargetType, +# post_init, +# increment, decrement, +# get_handle, +# [Name] ) +function generate_circulator +{ + NonConstCirc=$1 + ConstCirc="Const"$NonConstCirc + SourceHandle="typename Mesh::"$2"Handle" + TargetHandle="typename Mesh::"$3"Handle" + TargetType="typename Mesh::"$3 + + + cat circulators_template.hh \ + | sed -e "s/CirculatorT/$NonConstCirc/; s/CirculatorT/$NonConstCirc/; + s/NonConstCircT/$NonConstCirc/; + s/ConstCircT/$ConstCirc/; + s/SourceHandle/$SourceHandle/; + s/TargetHandle/$TargetHandle/; + s/TargetType/$TargetType/; + s/IsConst/0/; + s/post_init/$4/; + s/increment/$5/; + s/decrement/$6/; + s/get_handle/$7/;" + + + cat circulators_template.hh \ + | sed -e "s/CirculatorT/$ConstCirc/; s/CirculatorT/$ConstCirc/; + s/NonConstCircT/$NonConstCirc/; + s/ConstCircT/$ConstCirc/; + s/SourceHandle/$SourceHandle/; + s/TargetHandle/$TargetHandle/; + s/TargetType/$TargetType/; + s/IsConst/1/; + s/post_init/$4/; + s/increment/$5/; + s/decrement/$6/; + s/get_handle/$7/;" +} + + +#------------------------------------------------------------------------------ + + +### Generate IteratorsT.hh + +cat iterators_header.hh > IteratorsT.hh + +generate_iterator Vertex n_vertices has_vertex_status >> IteratorsT.hh +generate_iterator Halfedge n_halfedges has_halfedge_status >> IteratorsT.hh +generate_iterator Edge n_edges has_edge_status >> IteratorsT.hh +generate_iterator Face n_faces has_face_status >> IteratorsT.hh + +cat footer.hh >> IteratorsT.hh + + +#------------------------------------------------------------------------------ + + +### Generate CirculatorsT.hh + +cat circulators_header.hh > CirculatorsT.hh + + +generate_circulator VertexVertexIterT Vertex Vertex \ + " " \ + "heh_=mesh_->cw_rotated_halfedge_handle(heh_);" \ + "heh_=mesh_->ccw_rotated_halfedge_handle(heh_);" \ + "mesh_->to_vertex_handle(heh_);" \ + >> CirculatorsT.hh + +generate_circulator VertexOHalfedgeIterT Vertex Halfedge \ + " " \ + "heh_=mesh_->cw_rotated_halfedge_handle(heh_);" \ + "heh_=mesh_->ccw_rotated_halfedge_handle(heh_);" \ + "heh_" \ + >> CirculatorsT.hh + +generate_circulator VertexIHalfedgeIterT Vertex Halfedge \ + " " \ + "heh_=mesh_->cw_rotated_halfedge_handle(heh_);" \ + "heh_=mesh_->ccw_rotated_halfedge_handle(heh_);" \ + "mesh_->opposite_halfedge_handle(heh_)" \ + >> CirculatorsT.hh + +generate_circulator VertexEdgeIterT Vertex Edge \ + " " \ + "heh_=mesh_->cw_rotated_halfedge_handle(heh_);" \ + "heh_=mesh_->ccw_rotated_halfedge_handle(heh_);" \ + "mesh_->edge_handle(heh_)" \ + >> CirculatorsT.hh + +generate_circulator VertexFaceIterT Vertex Face \ + "if (heh_.is_valid() \&\& !handle().is_valid()) operator++();" \ + "do heh_=mesh_->cw_rotated_halfedge_handle(heh_); while ((*this) \&\& (!handle().is_valid()));" \ + "do heh_=mesh_->ccw_rotated_halfedge_handle(heh_); while ((*this) \&\& (!handle().is_valid()));" \ + "mesh_->face_handle(heh_)" \ + >> CirculatorsT.hh + + +generate_circulator FaceVertexIterT Face Vertex \ + " " \ + "heh_=mesh_->next_halfedge_handle(heh_);" \ + "heh_=mesh_->prev_halfedge_handle(heh_);" \ + "mesh_->to_vertex_handle(heh_)" \ + >> CirculatorsT.hh + +generate_circulator FaceHalfedgeIterT Face Halfedge \ + " " \ + "heh_=mesh_->next_halfedge_handle(heh_);" \ + "heh_=mesh_->prev_halfedge_handle(heh_);" \ + "heh_" \ + >> CirculatorsT.hh + +generate_circulator FaceEdgeIterT Face Edge \ + " " \ + "heh_=mesh_->next_halfedge_handle(heh_);" \ + "heh_=mesh_->prev_halfedge_handle(heh_);" \ + "mesh_->edge_handle(heh_)" \ + >> CirculatorsT.hh + +generate_circulator FaceFaceIterT Face Face \ + "if (heh_.is_valid() \&\& !handle().is_valid()) operator++();" \ + "do heh_=mesh_->next_halfedge_handle(heh_); while ((*this) \&\& (!handle().is_valid()));" \ + "do heh_=mesh_->prev_halfedge_handle(heh_); while ((*this) \&\& (!handle().is_valid()));" \ + "mesh_->face_handle(mesh_->opposite_halfedge_handle(heh_))" \ + >> CirculatorsT.hh + + +cat footer.hh >> CirculatorsT.hh + + +#------------------------------------------------------------------------------ diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/iterators_header.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/iterators_header.hh new file mode 100644 index 0000000..22f6d8b --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/iterators_header.hh @@ -0,0 +1,87 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_ITERATORS_HH +#define OPENMESH_ITERATORS_HH + +//============================================================================= +// +// Iterators for PolyMesh/TriMesh +// +//============================================================================= + + + +//== INCLUDES ================================================================= + +#include +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace Iterators { + + +//== FORWARD DECLARATIONS ===================================================== + + +template class VertexIterT; +template class ConstVertexIterT; +template class HalfedgeIterT; +template class ConstHalfedgeIterT; +template class EdgeIterT; +template class ConstEdgeIterT; +template class FaceIterT; +template class ConstFaceIterT; + + + + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/iterators_template.hh b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/iterators_template.hh new file mode 100644 index 0000000..99f54e0 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/gen/iterators_template.hh @@ -0,0 +1,162 @@ +//== CLASS DEFINITION ========================================================= + + +/** \class IteratorT IteratorsT.hh + Linear iterator. +*/ + +template +class IteratorT +{ +public: + + + //--- Typedefs --- + + typedef TargetType value_type; + typedef TargetHandle value_handle; + +#if IsConst + typedef const value_type& reference; + typedef const value_type* pointer; + typedef const Mesh* mesh_ptr; + typedef const Mesh& mesh_ref; +#else + typedef value_type& reference; + typedef value_type* pointer; + typedef Mesh* mesh_ptr; + typedef Mesh& mesh_ref; +#endif + + + + + /// Default constructor. + IteratorT() + : mesh_(0), skip_bits_(0) + {} + + + /// Construct with mesh and a target handle. + IteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) + : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) + { + if (_skip) enable_skipping(); + } + + + /// Copy constructor + IteratorT(const IteratorT& _rhs) + : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) + {} + + + /// Assignment operator + IteratorT& operator=(const IteratorT& _rhs) + { + mesh_ = _rhs.mesh_; + hnd_ = _rhs.hnd_; + skip_bits_ = _rhs.skip_bits_; + return *this; + } + + +#if IsConst + + /// Construct from a non-const iterator + IteratorT(const NonConstIterT& _rhs) + : mesh_(_rhs.mesh_), hnd_(_rhs.hnd_), skip_bits_(_rhs.skip_bits_) + {} + + + /// Assignment from non-const iterator + IteratorT& operator=(const NonConstIterT& _rhs) + { + mesh_ = _rhs.mesh_; + hnd_ = _rhs.hnd_; + skip_bits_ = _rhs.skip_bits_; + return *this; + } + +#else + friend class ConstIterT; +#endif + + + /// Standard dereferencing operator. + reference operator*() const { return mesh_->deref(hnd_); } + + /// Standard pointer operator. + pointer operator->() const { return &(mesh_->deref(hnd_)); } + + /// Get the handle of the item the iterator refers to. + value_handle handle() const { return hnd_; } + + /// Cast to the handle of the item the iterator refers to. + operator value_handle() const { return hnd_; } + + /// Are two iterators equal? Only valid if they refer to the same mesh! + bool operator==(const IteratorT& _rhs) const + { return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); } + + /// Not equal? + bool operator!=(const IteratorT& _rhs) const + { return !operator==(_rhs); } + + /// Standard pre-increment operator + IteratorT& operator++() + { hnd_.__increment(); if (skip_bits_) skip_fwd(); return *this; } + + /// Standard pre-decrement operator + IteratorT& operator--() + { hnd_.__decrement(); if (skip_bits_) skip_bwd(); return *this; } + + + /// Turn on skipping: automatically skip deleted/hidden elements + void enable_skipping() + { + if (mesh_ && mesh_->has_element_status()) + { + Attributes::StatusInfo status; + status.set_deleted(true); + status.set_hidden(true); + skip_bits_ = status.bits(); + skip_fwd(); + } + else skip_bits_ = 0; + } + + + /// Turn on skipping: automatically skip deleted/hidden elements + void disable_skipping() { skip_bits_ = 0; } + + + +private: + + void skip_fwd() + { + assert(mesh_ && skip_bits_); + while ((hnd_.idx() < (signed) mesh_->n_elements()) && + (mesh_->status(hnd_).bits() & skip_bits_)) + hnd_.__increment(); + } + + + void skip_bwd() + { + assert(mesh_ && skip_bits_); + while ((hnd_.idx() >= 0) && + (mesh_->status(hnd_).bits() & skip_bits_)) + hnd_.__decrement(); + } + + + +private: + mesh_ptr mesh_; + value_handle hnd_; + unsigned int skip_bits_; +}; + + diff --git a/libs/OpenMesh/include/OpenMesh/Core/System/OpenMeshDLLMacros.hh b/libs/OpenMesh/include/OpenMesh/Core/System/OpenMeshDLLMacros.hh new file mode 100644 index 0000000..c4d6a29 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/System/OpenMeshDLLMacros.hh @@ -0,0 +1,72 @@ +/* ========================================================================= * + * * + * 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: 566 $ * + * $Date: 2012-03-23 18:00:57 +0100 (Fr, 23 Mär 2012) $ * + * * +\*===========================================================================*/ + +// Disable the warnings about needs to have DLL interface as we have tons of vector templates +#ifdef _MSC_VER + #pragma warning( disable: 4251 ) +#endif + +#ifndef OPENMESHDLLEXPORT + #ifdef WIN32 + #ifdef OPENMESHDLL + #ifdef BUILDOPENMESHDLL + #define OPENMESHDLLEXPORT __declspec(dllexport) + #define OPENMESHDLLEXPORTONLY __declspec(dllexport) + #else + #define OPENMESHDLLEXPORT __declspec(dllimport) + #define OPENMESHDLLEXPORTONLY + #endif + #else + #define OPENMESHDLLEXPORT + #define OPENMESHDLLEXPORTONLY + #endif + #else + #define OPENMESHDLLEXPORT + #define OPENMESHDLLEXPORTONLY + #endif +#endif diff --git a/libs/OpenMesh/include/OpenMesh/Core/System/compiler.hh b/libs/OpenMesh/include/OpenMesh/Core/System/compiler.hh new file mode 100644 index 0000000..412b090 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/System/compiler.hh @@ -0,0 +1,178 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +#ifndef OPENMESH_COMPILER_H +#define OPENMESH_COMPILER_H + +//============================================================================= + +#if defined(ACGMAKE_STATIC_BUILD) +# define OM_STATIC_BUILD 1 +#endif + +//============================================================================= + +#if defined(_DEBUG) || defined(DEBUG) +# define OM_DEBUG +#endif + +//============================================================================= + +// Workaround for Intel Compiler with MS VC++ 6 +#if defined(_MSC_VER) && \ + ( defined(__ICL) || defined(__INTEL_COMPILER) || defined(__ICC) ) +# if !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +# endif +# define OM_USE_INTEL_COMPILER 1 +#endif + +// --------------------------------------------------------- MS Visual C++ ---- +// Compiler _MSC_VER +// .NET 2002 1300 +// .NET 2003 1310 +// .NET 2005 1400 +#if defined(_MSC_VER) && !defined(OM_USE_INTEL_COMPILER) +# if (_MSC_VER == 1300) +# define OM_CC_MSVC +# define OM_TYPENAME +# define OM_OUT_OF_CLASS_TEMPLATE 0 +# define OM_PARTIAL_SPECIALIZATION 0 +# define OM_INCLUDE_TEMPLATES 1 +# elif (_MSC_VER == 1310) +# define OM_CC_MSVC +# define OM_TYPENAME +# define OM_OUT_OF_CLASS_TEMPLATE 1 +# define OM_PARTIAL_SPECIALIZATION 1 +# define OM_INCLUDE_TEMPLATES 1 +# elif (_MSC_VER >= 1400) // settings for .NET 2005 (NOTE: not fully tested) +# define OM_TYPENAME +# define OM_OUT_OF_CLASS_TEMPLATE 1 +# define OM_PARTIAL_SPECIALIZATION 1 +# define OM_INCLUDE_TEMPLATES 1 +# else +# error "Version 7 (.NET 2002) or higher of the MS VC++ is required!" +# endif +// currently no windows dll supported +# define OM_STATIC_BUILD 1 +# if defined(_MT) +# define OM_REENTRANT 1 +# endif +# define OM_CC "MSVC++" +# define OM_CC_VERSION _MSC_VER +// Does not work stable because the define _CPPRTTI sometimes does not exist, +// though the option /GR is set!? +# if defined(__cplusplus) && !defined(_CPPRTTI) +# error "Enable Runtime Type Information (Compiler Option /GR)!" +# endif +# if !defined(_USE_MATH_DEFINES) +# error "You have to define _USE_MATH_DEFINES in the compiler settings!" +# endif +// ------------------------------------------------------------- Borland C ---- +#elif defined(__BORLANDC__) +# error "Borland Compiler are not supported yet!" +// ------------------------------------------------------------- GNU C/C++ ---- +#elif defined(__GNUC__) && !defined(__ICC) +# define OM_CC_GCC +# define OM_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 ) +# define OM_GCC_MAJOR __GNUC__ +# define OM_GCC_MINOR __GNUC_MINOR__ +# if (OM_GCC_VERSION >= 30200) +# define OM_TYPENAME typename +# define OM_OUT_OF_CLASS_TEMPLATE 1 +# define OM_PARTIAL_SPECIALIZATION 1 +# define OM_INCLUDE_TEMPLATES 1 +# else +# error "Version 3.2.0 or better of the GNU Compiler is required!" +# endif +# if defined(_REENTRANT) +# define OM_REENTRANT 1 +# endif +# define OM_CC "GCC" +# define OM_CC_VERSION OM_GCC_VERSION +// ------------------------------------------------------------- Intel icc ---- +#elif defined(__ICC) || defined(__INTEL_COMPILER) +# define OM_CC_ICC +# define OM_TYPENAME typename +# define OM_OUT_OF_CLASS_TEMPLATE 1 +# define OM_PARTIAL_SPECIALIZATION 1 +# define OM_INCLUDE_TEMPLATES 1 +# if defined(_REENTRANT) || defined(_MT) +# define OM_REENTRANT 1 +# endif +# define OM_CC "ICC" +# define OM_CC_VERSION __INTEL_COMPILER +// currently no windows dll supported +# if defined(_MSC_VER) || defined(WIN32) +# define OM_STATIC_BUILD 1 +# endif +// ------------------------------------------------------ MIPSpro Compiler ---- +#elif defined(__MIPS_ISA) || defined(__mips) +// _MIPS_ISA +// _COMPILER_VERSION e.g. 730, 7 major, 3 minor +// _MIPS_FPSET 32|64 +// _MIPS_SZINT 32|64 +// _MIPS_SZLONG 32|64 +// _MIPS_SZPTR 32|64 +# define OM_CC_MIPS +# define OM_TYPENAME typename +# define OM_OUT_OF_CLASS_TEMPLATE 1 +# define OM_PARTIAL_SPECIALIZATION 1 +# define OM_INCLUDE_TEMPLATES 0 +# define OM_CC "MIPS" +# define OM_CC_VERSION _COMPILER_VERSION +// ------------------------------------------------------------------ ???? ---- +#else +# error "You're using an unsupported compiler!" +#endif + +//============================================================================= +#endif // OPENMESH_COMPILER_H defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/System/config.h b/libs/OpenMesh/include/OpenMesh/Core/System/config.h new file mode 100644 index 0000000..65c0b3e --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/System/config.h @@ -0,0 +1,107 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +/** \file config.h + * \todo Move content to config.hh and include it to be compatible with old + * source. + */ + +//============================================================================= + +#ifndef OPENMESH_CONFIG_H +#define OPENMESH_CONFIG_H + +//============================================================================= + +#include +#include +#include + +// ---------------------------------------------------------------------------- + + +#define OM_VERSION 0x70100 + +#define OM_GET_VER ((OM_VERSION & 0xf0000) >> 16) +#define OM_GET_MAJ ((OM_VERSION & 0x0ff00) >> 8) +#define OM_GET_MIN (OM_VERSION & 0x000ff) + +#ifdef WIN32 +# ifdef min +# pragma message("Detected min macro! OpenMesh does not compile with min/max macros active! Please add a define NOMINMAX to your compiler flags or add #undef min before including OpenMesh headers !") +# error min macro active +# endif +# ifdef max +# pragma message("Detected max macro! OpenMesh does not compile with min/max macros active! Please add a define NOMINMAX to your compiler flags or add #undef max before including OpenMesh headers !") +# error max macro active +# endif +#endif + +#if defined(_MSC_VER) +# define DEPRECATED(msg) __declspec(deprecated(msg)) +#elif defined(__GNUC__) +# if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40500 /* Test for GCC >= 4.5.0 */ +# define DEPRECATED(msg) __attribute__ ((deprecated(msg))) +# else +# define DEPRECATED(msg) __attribute__ ((deprecated)) +# endif +#elif defined(__clang__) +# define DEPRECATED(msg) __attribute__ ((deprecated(msg))) +#else +# define DEPRECATED(msg) +#endif + +typedef unsigned int uint; + +#if ((defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define OM_HAS_HASH +#endif + +//============================================================================= +#endif // OPENMESH_CONFIG_H defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/System/config.hh b/libs/OpenMesh/include/OpenMesh/Core/System/config.hh new file mode 100644 index 0000000..6c23e27 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/System/config.hh @@ -0,0 +1,49 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#include diff --git a/libs/OpenMesh/include/OpenMesh/Core/System/mostream.hh b/libs/OpenMesh/include/OpenMesh/Core/System/mostream.hh new file mode 100644 index 0000000..4dabf51 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/System/mostream.hh @@ -0,0 +1,330 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +//============================================================================= +// +// multiplex streams & ultilities +// +//============================================================================= + +#ifndef OPENMESH_MOSTREAM_HH +#define OPENMESH_MOSTREAM_HH + + +//== INCLUDES ================================================================= + +#include +#include +#if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000 +# include +#else +# include +#endif +#include +#include +#include +#include + +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ ) + #include +#endif + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +#ifndef DOXY_IGNORE_THIS + + +//== CLASS DEFINITION ========================================================= + + +class basic_multiplex_target +{ +public: + virtual ~basic_multiplex_target() {} + virtual void operator<<(const std::string& _s) = 0; +}; + + +template +class multiplex_target : public basic_multiplex_target +{ +public: + explicit multiplex_target(T& _t) : target_(_t) {} + virtual void operator<<(const std::string& _s) { target_ << _s; } +private: + T& target_; +}; + + + +//== CLASS DEFINITION ========================================================= + + +#if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000 +# define STREAMBUF streambuf +# define INT_TYPE int +# define TRAITS_TYPE +#else +# define STREAMBUF std::basic_streambuf +#endif + +class multiplex_streambuf : public STREAMBUF +{ +public: + + typedef STREAMBUF base_type; +#if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000 + typedef int int_type; + struct traits_type + { + static int_type eof() { return -1; } + static char to_char_type(int_type c) { return char(c); } + }; +#else + typedef base_type::int_type int_type; + typedef base_type::traits_type traits_type; +#endif + + // Constructor + multiplex_streambuf() : enabled_(true) { buffer_.reserve(100); } + + // Destructor + ~multiplex_streambuf() + { + tmap_iter t_it(target_map_.begin()), t_end(target_map_.end()); + for (; t_it!=t_end; ++t_it) + delete t_it->second; + } + + + // buffer enable/disable + bool is_enabled() const { return enabled_; } + void enable() { enabled_ = true; } + void disable() { enabled_ = false; } + + + // construct multiplex_target and add it to targets + template bool connect(T& _target) + { + void* key = (void*) &_target; + + if (target_map_.find(key) != target_map_.end()) + return false; + + target_type* mtarget = new multiplex_target(_target); + target_map_[key] = mtarget; + + __connect(mtarget); + return true; + } + + + // disconnect target from multiplexer + template bool disconnect(T& _target) + { + void* key = (void*) &_target; + tmap_iter t_it = target_map_.find(key); + + if (t_it != target_map_.end()) + { + __disconnect(t_it->second); + target_map_.erase(t_it); + return true; + } + + return false; + } + + +protected: + + // output what's in buffer_ + virtual int sync() + { + // If working on multiple threads, we need to serialize the output correctly (requires c++11 headers) + #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ ) + std::lock_guard lck (serializer_); + #endif + + if (!buffer_.empty()) + { + if (enabled_) multiplex(); +#if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000 + buffer_ = ""; // member clear() not available! +#else + buffer_.clear(); +#endif + } + return base_type::sync(); + } + + + // take on char and add it to buffer_ + // if '\n' is encountered, trigger a sync() + virtual + int_type overflow(int_type _c = multiplex_streambuf::traits_type::eof()) + { + 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 (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ ) + { + std::lock_guard lck (serializer_); + buffer_.push_back(c); + } + #else + buffer_.push_back(c); + #endif + + if (c == '\n') sync(); + return 0; + } + + +private: + + typedef basic_multiplex_target target_type; + typedef std::vector target_list; + typedef target_list::iterator tlist_iter; + typedef std::map target_map; + typedef target_map::iterator tmap_iter; + + + // add _target to list of multiplex targets + void __connect(target_type* _target) { targets_.push_back(_target); } + + + // remove _target from list of multiplex targets + void __disconnect(target_type* _target) { + targets_.erase(std::find(targets_.begin(), targets_.end(), _target)); + } + + + // multiplex output of buffer_ to all targets + void multiplex() + { + tlist_iter t_it(targets_.begin()), t_end(targets_.end()); + for (; t_it!=t_end; ++t_it) + **t_it << buffer_; + } + + +private: + + target_list targets_; + target_map target_map_; + std::string buffer_; + bool enabled_; + + // If working on multiple threads, we need to serialize the output correctly (requires c++11 headers) + #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined( __GXX_EXPERIMENTAL_CXX0X__ ) + std::mutex serializer_; + #endif + +}; + +#undef STREAMBUF + + +//== CLASS DEFINITION ========================================================= + + +/** \class mostream mostream.hh + + This class provides streams that can easily be multiplexed (using + the connect() method) and toggled on/off (using enable() / + disable()). + + \see omlog, omout, omerr +*/ + +class mostream : public std::ostream +{ +public: + + /// Explicit constructor + explicit mostream() : std::ostream(NULL) { init(&streambuffer_); } + + + /// Connect target to multiplexer + template bool connect(T& _target) + { + return streambuffer_.connect(_target); + } + + + /// Disconnect target from multiplexer + template bool disconnect(T& _target) + { + return streambuffer_.disconnect(_target); + } + + + /// is buffer enabled + bool is_enabled() const { return streambuffer_.is_enabled(); } + + /// enable this buffer + void enable() { streambuffer_.enable(); } + + /// disable this buffer + void disable() { streambuffer_.disable(); } + + +private: + multiplex_streambuf streambuffer_; +}; + + +//============================================================================= +#endif +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MOSTREAM_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/System/omstream.hh b/libs/OpenMesh/include/OpenMesh/Core/System/omstream.hh new file mode 100644 index 0000000..01fdfb0 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/System/omstream.hh @@ -0,0 +1,83 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +//============================================================================= +// +// OpenMesh streams: omlog, omout, omerr +// +//============================================================================= + +#ifndef OPENMESH_OMSTREAMS_HH +#define OPENMESH_OMSTREAMS_HH + + +//== INCLUDES ================================================================= + +#include + + +//== CLASS DEFINITION ========================================================= + +/** \file omstream.hh + This file provides the streams omlog, omout, and omerr. +*/ + +/** \name stream replacements + These stream provide replacements for clog, cout, and cerr. They have + the advantage that they can easily be multiplexed. + \see OpenMesh::mostream +*/ +//@{ +OPENMESHDLLEXPORT OpenMesh::mostream& omlog(); +OPENMESHDLLEXPORT OpenMesh::mostream& omout(); +OPENMESHDLLEXPORT OpenMesh::mostream& omerr(); +//@} + +//============================================================================= +#endif // OPENMESH_OMSTREAMS_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Templates/newClass.hh b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClass.hh new file mode 100644 index 0000000..31a2fd2 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClass.hh @@ -0,0 +1,108 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +//============================================================================= +// +// CLASS newClass +// +//============================================================================= +#ifndef DOXY_IGNORE_THIS +#ifndef OPENMESH_NEWCLASS_HH +#define OPENMESH_NEWCLASS_HH + + +//== INCLUDES ================================================================= + + +//== FORWARDDECLARATIONS ====================================================== + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + +/** \class newClass newClass.hh + + Brief Description. + + A more elaborate description follows. +*/ + +class newClass +{ +public: + + /// Default constructor + newClass() {} + + /// Destructor + ~newClass() {} + + +private: + + /// Copy constructor (not used) + newClass(const newClass& _rhs); + + /// Assignment operator (not used) + newClass& operator=(const newClass& _rhs); + +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_NEWCLASS_HH defined +#endif // DOXY_IGNORE_THIS +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Templates/newClass.sh b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClass.sh new file mode 100644 index 0000000..7ea19a7 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClass.sh @@ -0,0 +1,9 @@ +#! /bin/sh + +A=`echo $1_ | tr '[:lower:]' '[:upper:]'` + +sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClass.cc > tmp_newClass.cc +sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClass.hh > tmp_newClass.hh + +mv -i tmp_newClass.cc $1.cc && echo $1.cc - ok +mv -i tmp_newClass.hh $1.hh && echo $1.hh - ok diff --git a/libs/OpenMesh/include/OpenMesh/Core/Templates/newClassT.hh b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClassT.hh new file mode 100644 index 0000000..00b5f14 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClassT.hh @@ -0,0 +1,115 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +//============================================================================= +// +// CLASS newClass +// +//============================================================================= +#ifndef DOXY_IGNORE_THIS +#ifndef OPENMESH_NEWCLASST_HH +#define OPENMESH_NEWCLASST_HH + + +//== INCLUDES ================================================================= + + +//== FORWARDDECLARATIONS ====================================================== + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + + +//== CLASS DEFINITION ========================================================= + + + + +/** \class newClassT newClassT.hh + + Brief Description. + + A more elaborate description follows. +*/ + +template <> +class newClassT +{ +public: + + /// Default constructor + newClassT() {} + + /// Destructor + ~newClassT() {} + + +private: + + /// Copy constructor (not used) + newClassT(const newClassT& _rhs); + + /// Assignment operator (not used) + newClassT& operator=(const newClassT& _rhs); + +}; + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_NEWCLASS_C) +#define OPENMESH_NEWCLASS_TEMPLATES +#include "newClass.cc" +#endif +//============================================================================= +#endif // OPENMESH_NEWCLASST_HH defined +#endif // DOXY_IGNORE_THIS +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Templates/newClassT.sh b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClassT.sh new file mode 100644 index 0000000..7023244 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Templates/newClassT.sh @@ -0,0 +1,9 @@ +#! /bin/sh + +A=`echo $1_ | tr '[:lower:]' '[:upper:]'` + +sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClassT.cc > tmp_newClass.cc +sed -e s/newClass/$1/g -e s/NEWCLASS_/$A/g < newClassT.hh > tmp_newClass.hh + +mv -i tmp_newClass.cc $1.cc && echo $1.cc - ok +mv -i tmp_newClass.hh $1.hh && echo $1.hh - ok diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/AutoPropertyHandleT.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/AutoPropertyHandleT.hh new file mode 100644 index 0000000..fae37a9 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/AutoPropertyHandleT.hh @@ -0,0 +1,138 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_AutoPropertyHandleT_HH +#define OPENMESH_AutoPropertyHandleT_HH + +//== INCLUDES ================================================================= +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== CLASS DEFINITION ========================================================= + +template +class AutoPropertyHandleT : public PropertyHandle_ +{ +public: + typedef Mesh_ Mesh; + typedef PropertyHandle_ PropertyHandle; + typedef PropertyHandle Base; + typedef typename PropertyHandle::Value Value; + typedef AutoPropertyHandleT + Self; +protected: + Mesh* m_; + bool own_property_;//ref counting? + +public: + AutoPropertyHandleT() + : m_(NULL), own_property_(false) + {} + + AutoPropertyHandleT(const Self& _other) + : Base(_other.idx()), m_(_other.m_), own_property_(false) + {} + + explicit AutoPropertyHandleT(Mesh& _m, const std::string& _pp_name = std::string()) + { add_property(_m, _pp_name); } + + AutoPropertyHandleT(Mesh& _m, PropertyHandle _pph) + : Base(_pph.idx()), m_(&_m), own_property_(false) + {} + + ~AutoPropertyHandleT() + { + if (own_property_) + { + m_->remove_property(*this); + } + } + + inline void add_property(Mesh& _m, const std::string& _pp_name = std::string()) + { + assert(!is_valid()); + m_ = &_m; + own_property_ = _pp_name.empty() || !m_->get_property_handle(*this, _pp_name); + if (own_property_) + { + m_->add_property(*this, _pp_name); + } + } + + inline void remove_property() + { + assert(own_property_);//only the owner can delete the property + m_->remove_property(*this); + own_property_ = false; + invalidate(); + } + + template + inline Value& operator [] (_Handle _hnd) + { return m_->property(*this, _hnd); } + + template + inline const Value& operator [] (_Handle _hnd) const + { return m_->property(*this, _hnd); } + + inline bool own_property() const + { return own_property_; } + + inline void free_property() + { own_property_ = false; } +}; + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_AutoPropertyHandleT_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/BaseProperty.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/BaseProperty.hh new file mode 100644 index 0000000..3abcfe2 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/BaseProperty.hh @@ -0,0 +1,188 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_BASEPROPERTY_HH +#define OPENMESH_BASEPROPERTY_HH + +#include +#include +#include + +namespace OpenMesh { + +//== CLASS DEFINITION ========================================================= + +/** \class BaseProperty Property.hh + + Abstract class defining the basic interface of a dynamic property. +**/ + +class OPENMESHDLLEXPORT BaseProperty +{ +public: + + /// Indicates an error when a size is returned by a member. + static const size_t UnknownSize = size_t(-1); + +public: + + /// \brief Default constructor. + /// + /// In %OpenMesh all mesh data is stored in so-called properties. + /// We distinuish between standard properties, which can be defined at + /// compile time using the Attributes in the traits definition and + /// at runtime using the request property functions defined in one of + /// the kernels. + /// + /// If the property should be stored along with the default properties + /// in the OM-format one must name the property and enable the persistant + /// flag with set_persistent(). + /// + /// \param _name Optional textual name for the property. + /// + BaseProperty(const std::string& _name = "") + : name_(_name), persistent_(false) + {} + + /// \brief Copy constructor + BaseProperty(const BaseProperty & _rhs) + : name_( _rhs.name_ ), persistent_( _rhs.persistent_ ) {} + + /// Destructor. + virtual ~BaseProperty() {} + +public: // synchronized array interface + + /// Reserve memory for n elements. + virtual void reserve(size_t _n) = 0; + + /// Resize storage to hold n elements. + virtual void resize(size_t _n) = 0; + + /// Clear all elements and free memory. + virtual void clear() = 0; + + /// Extend the number of elements by one. + virtual void push_back() = 0; + + /// Let two elements swap their storage place. + virtual void swap(size_t _i0, size_t _i1) = 0; + + /// Copy one element to another + virtual void copy(size_t _io, size_t _i1) = 0; + + /// Return a deep copy of self. + virtual BaseProperty* clone () const = 0; + +public: // named property interface + + /// Return the name of the property + const std::string& name() const { return name_; } + + virtual void stats(std::ostream& _ostr) const; + +public: // I/O support + + /// Returns true if the persistent flag is enabled else false. + bool persistent(void) const { return persistent_; } + + /// Enable or disable persistency. Self must be a named property to enable + /// persistency. + virtual void set_persistent( bool _yn ) = 0; + + /// Number of elements in property + virtual size_t n_elements() const = 0; + + /// Size of one element in bytes or UnknownSize if not known. + virtual size_t element_size() const = 0; + + /// Return size of property in bytes + virtual size_t size_of() const + { + return size_of( n_elements() ); + } + + /// Estimated size of property if it has _n_elem elements. + /// The member returns UnknownSize if the size cannot be estimated. + virtual size_t size_of(size_t _n_elem) const + { + return (element_size()!=UnknownSize) + ? (_n_elem*element_size()) + : UnknownSize; + } + + /// Store self as one binary block + virtual size_t store( std::ostream& _ostr, bool _swap ) const = 0; + + /** Restore self from a binary block. Uses reserve() to set the + size of self before restoring. + **/ + virtual size_t restore( std::istream& _istr, bool _swap ) = 0; + +protected: + + // To be used in a derived class, when overloading set_persistent() + template < typename T > + void check_and_set_persistent( bool _yn ) + { + if ( _yn && !IO::is_streamable() ) + omerr() << "Warning! Type of property value is not binary storable!\n"; + persistent_ = IO::is_streamable() && _yn; + } + +private: + + std::string name_; + bool persistent_; +}; + +}//namespace OpenMesh + +#endif //OPENMESH_BASEPROPERTY_HH + + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/Endian.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/Endian.hh new file mode 100644 index 0000000..e511c00 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/Endian.hh @@ -0,0 +1,103 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + + +#ifndef OPENMESH_UTILS_ENDIAN_HH +#define OPENMESH_UTILS_ENDIAN_HH + + +//== INCLUDES ================================================================= + + +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//============================================================================= + + +/** Determine byte order of host system. + */ +class OPENMESHDLLEXPORT Endian +{ +public: + + enum Type { + LSB = 1, ///< Little endian (Intel family and clones) + MSB ///< big endian (Motorola's 68x family, DEC Alpha, MIPS) + }; + + /// Return endian type of host system. + static Type local() { return local_; } + + /// Return type _t as string. + static const char * as_string(Type _t); + +private: + static int one_; + static const Type local_; +}; + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESHREADER_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/GenProg.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/GenProg.hh new file mode 100644 index 0000000..bf0b20a --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/GenProg.hh @@ -0,0 +1,165 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Utils for generic/generative programming +// +//============================================================================= + +#ifndef OPENMESH_GENPROG_HH +#define OPENMESH_GENPROG_HH + + +//== INCLUDES ================================================================= + +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +namespace GenProg { +#ifndef DOXY_IGNORE_THIS + +//== IMPLEMENTATION =========================================================== + + +/// This type maps \c true or \c false to different types. +template struct Bool2Type { enum { my_bool = b }; }; + +/// This class generates different types from different \c int 's. +template struct Int2Type { enum { my_int = i }; }; + +/// Handy typedef for Bool2Type classes +typedef Bool2Type TrueType; + +/// Handy typedef for Bool2Type classes +typedef Bool2Type FalseType; + +//----------------------------------------------------------------------------- +/// compile time assertions +template struct AssertCompile; +template <> struct AssertCompile {}; + + + +//--- Template "if" w/ partial specialization --------------------------------- +#if OM_PARTIAL_SPECIALIZATION + + +template +struct IF { typedef Then Result; }; + +/** Template \c IF w/ partial specialization +\code +typedef IF::Result ResultType; +\endcode +*/ +template +struct IF { typedef Else Result; }; + + + + + +//--- Template "if" w/o partial specialization -------------------------------- +#else + + +struct SelectThen +{ + template struct Select { + typedef Then Result; + }; +}; + +struct SelectElse +{ + template struct Select { + typedef Else Result; + }; +}; + +template struct ChooseSelector { + typedef SelectThen Result; +}; + +template <> struct ChooseSelector { + typedef SelectElse Result; +}; + + +/** Template \c IF w/o partial specialization. Use it like +\code +typedef IF::Result ResultType; +\endcode +*/ + +template +class IF +{ + typedef typename ChooseSelector::Result Selector; +public: + typedef typename Selector::template Select::Result Result; +}; + +#endif + +//============================================================================= +#endif +} // namespace GenProg +} // namespace OpenMesh + +#define assert_compile(EXPR) GenProg::AssertCompile<(EXPR)>(); + +//============================================================================= +#endif // OPENMESH_GENPROG_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/Noncopyable.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/Noncopyable.hh new file mode 100644 index 0000000..ddbfb3e --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/Noncopyable.hh @@ -0,0 +1,94 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements the Non-Copyable metapher +// +//============================================================================= + +#ifndef OPENMESH_NONCOPYABLE_HH +#define OPENMESH_NONCOPYABLE_HH + + +//----------------------------------------------------------------------------- + +#include + +//----------------------------------------------------------------------------- + +namespace OpenMesh { +namespace Utils { + +//----------------------------------------------------------------------------- + +/** This class demonstrates the non copyable idiom. In some cases it is + important an object can't be copied. Deriving from Noncopyable makes sure + all relevant constructor and operators are made inaccessable, for public + AND derived classes. +**/ +class Noncopyable +{ +public: + Noncopyable() { } + +private: + /// Prevent access to copy constructor + Noncopyable( const Noncopyable& ); + + /// Prevent access to assignment operator + const Noncopyable& operator=( const Noncopyable& ); +}; + +//============================================================================= +} // namespace Utils +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_NONCOPYABLE_HH +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/Property.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/Property.hh new file mode 100644 index 0000000..ab26d9d --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/Property.hh @@ -0,0 +1,555 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_PROPERTY_HH +#define OPENMESH_PROPERTY_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== CLASS DEFINITION ========================================================= + +/** \class PropertyT Property.hh + * + * \brief Default property class for any type T. + * + * The default property class for any type T. + * + * The property supports persistency if T is a "fundamental" type: + * - integer fundamental types except bool: + * char, short, int, long, long long (__int64 for MS VC++) and + * their unsigned companions. + * - float fundamentals except long double: + * float, double + * - %OpenMesh vector types + * + * Persistency of non-fundamental types is supported if and only if a + * specialization of struct IO::binary<> exists for the wanted type. + */ + +// TODO: it might be possible to define Property using kind of a runtime info +// structure holding the size of T. Then reserve, swap, resize, etc can be written +// in pure malloc() style w/o virtual overhead. Template member function proved per +// element access to the properties, asserting dynamic_casts in debug + +template +class PropertyT : public BaseProperty +{ +public: + + typedef T Value; + typedef std::vector vector_type; + typedef T value_type; + typedef typename vector_type::reference reference; + typedef typename vector_type::const_reference const_reference; + +public: + + /// Default constructor + PropertyT(const std::string& _name = "") + : BaseProperty(_name) + {} + + /// Copy constructor + PropertyT(const PropertyT & _rhs) + : BaseProperty( _rhs ), data_( _rhs.data_ ) {} + +public: // inherited from BaseProperty + + virtual void reserve(size_t _n) { data_.reserve(_n); } + virtual void resize(size_t _n) { data_.resize(_n); } + virtual void clear() { data_.clear(); vector_type().swap(data_); } + virtual void push_back() { data_.push_back(T()); } + virtual void swap(size_t _i0, size_t _i1) + { std::swap(data_[_i0], data_[_i1]); } + virtual void copy(size_t _i0, size_t _i1) + { data_[_i1] = data_[_i0]; } + +public: + + virtual void set_persistent( bool _yn ) + { check_and_set_persistent( _yn ); } + + virtual size_t n_elements() const { return data_.size(); } + virtual size_t element_size() const { return IO::size_of(); } + +#ifndef DOXY_IGNORE_THIS + struct plus { + size_t operator () ( size_t _b, const T& _v ) + { return _b + IO::size_of(_v); } + }; +#endif + + virtual size_t size_of(void) const + { + if (element_size() != IO::UnknownSize) + return this->BaseProperty::size_of(n_elements()); + return std::accumulate(data_.begin(), data_.end(), size_t(0), plus()); + } + + virtual size_t size_of(size_t _n_elem) const + { return this->BaseProperty::size_of(_n_elem); } + + virtual size_t store( std::ostream& _ostr, bool _swap ) const + { + if ( IO::is_streamable() ) + return IO::store(_ostr, data_, _swap ); + size_t bytes = 0; + for (size_t i=0; i() ) + return IO::restore(_istr, data_, _swap ); + size_t bytes = 0; + for (size_t i=0; i* clone() const + { + PropertyT* p = new PropertyT( *this ); + return p; + } + + +private: + + vector_type data_; +}; + +//----------------------------------------------------------------------------- + + +/** Property specialization for bool type. + + The data will be stored as a bitset. + */ +template <> +class PropertyT : public BaseProperty +{ +public: + + typedef std::vector vector_type; + typedef bool value_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + +public: + + PropertyT(const std::string& _name = "") + : BaseProperty(_name) + { } + +public: // inherited from BaseProperty + + virtual void reserve(size_t _n) { data_.reserve(_n); } + virtual void resize(size_t _n) { data_.resize(_n); } + virtual void clear() { data_.clear(); vector_type().swap(data_); } + virtual void push_back() { data_.push_back(bool()); } + virtual void swap(size_t _i0, size_t _i1) + { bool t(data_[_i0]); data_[_i0]=data_[_i1]; data_[_i1]=t; } + virtual void copy(size_t _i0, size_t _i1) + { data_[_i1] = data_[_i0]; } + +public: + + virtual void set_persistent( bool _yn ) + { + check_and_set_persistent( _yn ); + } + + virtual size_t n_elements() const { return data_.size(); } + virtual size_t element_size() const { return UnknownSize; } + virtual size_t size_of() const { return size_of( n_elements() ); } + virtual size_t size_of(size_t _n_elem) const + { + return _n_elem / 8 + ((_n_elem % 8)!=0); + } + + size_t store( std::ostream& _ostr, bool /* _swap */ ) const + { + size_t bytes = 0; + + size_t N = data_.size() / 8; + size_t R = data_.size() % 8; + + size_t idx; // element index + size_t bidx; + unsigned char bits; // bitset + + for (bidx=idx=0; idx < N; ++idx, bidx+=8) + { + bits = static_cast(data_[bidx]) + | (static_cast(data_[bidx+1]) << 1) + | (static_cast(data_[bidx+2]) << 2) + | (static_cast(data_[bidx+3]) << 3) + | (static_cast(data_[bidx+4]) << 4) + | (static_cast(data_[bidx+5]) << 5) + | (static_cast(data_[bidx+6]) << 6) + | (static_cast(data_[bidx+7]) << 7); + _ostr << bits; + } + bytes = N; + + if (R) + { + bits = 0; + for (idx=0; idx < R; ++idx) + bits |= static_cast(data_[bidx+idx]) << idx; + _ostr << bits; + ++bytes; + } + + assert( bytes == size_of() ); + + return bytes; + } + + size_t restore( std::istream& _istr, bool /* _swap */ ) + { + size_t bytes = 0; + + size_t N = data_.size() / 8; + size_t R = data_.size() % 8; + + size_t idx; // element index + size_t bidx; // + unsigned char bits; // bitset + + for (bidx=idx=0; idx < N; ++idx, bidx+=8) + { + _istr >> bits; + data_[bidx+0] = (bits & 0x01) != 0; + data_[bidx+1] = (bits & 0x02) != 0; + data_[bidx+2] = (bits & 0x04) != 0; + data_[bidx+3] = (bits & 0x08) != 0; + data_[bidx+4] = (bits & 0x10) != 0; + data_[bidx+5] = (bits & 0x20) != 0; + data_[bidx+6] = (bits & 0x40) != 0; + data_[bidx+7] = (bits & 0x80) != 0; + } + bytes = N; + + if (R) + { + _istr >> bits; + for (idx=0; idx < R; ++idx) + data_[bidx+idx] = (bits & (1<* clone() const + { + PropertyT* p = new PropertyT( *this ); + return p; + } + + +private: + + vector_type data_; +}; + + +//----------------------------------------------------------------------------- + + +/** Property specialization for std::string type. +*/ +template <> +class PropertyT : public BaseProperty +{ +public: + + typedef std::string Value; + typedef std::vector vector_type; + typedef std::string value_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + +public: + + PropertyT(const std::string& _name = "") + : BaseProperty(_name) + { } + +public: // inherited from BaseProperty + + virtual void reserve(size_t _n) { data_.reserve(_n); } + virtual void resize(size_t _n) { data_.resize(_n); } + virtual void clear() { data_.clear(); vector_type().swap(data_); } + virtual void push_back() { data_.push_back(std::string()); } + virtual void swap(size_t _i0, size_t _i1) { + std::swap(data_[_i0], data_[_i1]); + } + virtual void copy(size_t _i0, size_t _i1) + { data_[_i1] = data_[_i0]; } + +public: + + virtual void set_persistent( bool _yn ) + { check_and_set_persistent( _yn ); } + + virtual size_t n_elements() const { return data_.size(); } + virtual size_t element_size() const { return UnknownSize; } + virtual size_t size_of() const + { return IO::size_of( data_ ); } + + virtual size_t size_of(size_t /* _n_elem */) const + { return UnknownSize; } + + /// Store self as one binary block. Max. length of a string is 65535 bytes. + size_t store( std::ostream& _ostr, bool _swap ) const + { return IO::store( _ostr, data_, _swap ); } + + size_t restore( std::istream& _istr, bool _swap ) + { return IO::restore( _istr, data_, _swap ); } + +public: + + const value_type* data() const { + if( data_.empty() ) + return 0; + + return (value_type*) &data_[0]; + } + + /// Access the i'th element. No range check is performed! + reference operator[](int _idx) { + assert( size_t(_idx) < data_.size()); + return ((value_type*) &data_[0])[_idx]; + } + + /// Const access the i'th element. No range check is performed! + const_reference operator[](int _idx) const { + assert( size_t(_idx) < data_.size()); + return ((value_type*) &data_[0])[_idx]; + } + + PropertyT* clone() const { + PropertyT* p = new PropertyT( *this ); + return p; + } +private: + + vector_type data_; + +}; + +/// Base property handle. +template +struct BasePropHandleT : public BaseHandle +{ + typedef T Value; + typedef std::vector vector_type; + typedef T value_type; + typedef typename vector_type::reference reference; + typedef typename vector_type::const_reference const_reference; + + explicit BasePropHandleT(int _idx=-1) : BaseHandle(_idx) {} +}; + + +/** \ingroup mesh_property_handle_group + * Handle representing a vertex property + */ +template +struct VPropHandleT : public BasePropHandleT +{ + typedef T Value; + typedef T value_type; + + explicit VPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} + explicit VPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} +}; + + +/** \ingroup mesh_property_handle_group + * Handle representing a halfedge property + */ +template +struct HPropHandleT : public BasePropHandleT +{ + typedef T Value; + typedef T value_type; + + explicit HPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} + explicit HPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} +}; + + +/** \ingroup mesh_property_handle_group + * Handle representing an edge property + */ +template +struct EPropHandleT : public BasePropHandleT +{ + typedef T Value; + typedef T value_type; + + explicit EPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} + explicit EPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} +}; + + +/** \ingroup mesh_property_handle_group + * Handle representing a face property + */ +template +struct FPropHandleT : public BasePropHandleT +{ + typedef T Value; + typedef T value_type; + + explicit FPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} + explicit FPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} +}; + + +/** \ingroup mesh_property_handle_group + * Handle representing a mesh property + */ +template +struct MPropHandleT : public BasePropHandleT +{ + typedef T Value; + typedef T value_type; + + explicit MPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} + explicit MPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} +}; + +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_PROPERTY_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/PropertyContainer.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/PropertyContainer.hh new file mode 100644 index 0000000..d8d7393 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/PropertyContainer.hh @@ -0,0 +1,375 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef OPENMESH_PROPERTYCONTAINER +#define OPENMESH_PROPERTYCONTAINER + +// Use static casts when not debugging +#ifdef NDEBUG +#define OM_FORCE_STATIC_CAST +#endif + +#include + +//----------------------------------------------------------------------------- +namespace OpenMesh +{ +//== FORWARDDECLARATIONS ====================================================== + class BaseKernel; + +//== CLASS DEFINITION ========================================================= +/// A a container for properties. +class PropertyContainer +{ +public: + + //-------------------------------------------------- constructor / destructor + + PropertyContainer() {} + virtual ~PropertyContainer() { std::for_each(properties_.begin(), properties_.end(), Delete()); } + + + //------------------------------------------------------------- info / access + + typedef std::vector Properties; + const Properties& properties() const { return properties_; } + size_t size() const { return properties_.size(); } + + + + //--------------------------------------------------------- copy / assignment + + PropertyContainer(const PropertyContainer& _rhs) { operator=(_rhs); } + + PropertyContainer& operator=(const PropertyContainer& _rhs) + { + // The assignment below relies on all previous BaseProperty* elements having been deleted + std::for_each(properties_.begin(), properties_.end(), Delete()); + properties_ = _rhs.properties_; + Properties::iterator p_it=properties_.begin(), p_end=properties_.end(); + for (; p_it!=p_end; ++p_it) + if (*p_it) + *p_it = (*p_it)->clone(); + return *this; + } + + + + //--------------------------------------------------------- manage properties + + template + BasePropHandleT add(const T&, const std::string& _name="") + { + Properties::iterator p_it=properties_.begin(), p_end=properties_.end(); + int idx=0; + for ( ; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx ) {}; + if (p_it==p_end) properties_.push_back(NULL); + properties_[idx] = new PropertyT(_name); + return BasePropHandleT(idx); + } + + + template + BasePropHandleT handle(const T&, const std::string& _name) const + { + Properties::const_iterator p_it = properties_.begin(); + for (int idx=0; p_it != properties_.end(); ++p_it, ++idx) + { + if (*p_it != NULL && + (*p_it)->name() == _name //skip deleted properties +// Skip type check +#ifndef OM_FORCE_STATIC_CAST + && dynamic_cast*>(properties_[idx]) != NULL //check type +#endif + ) + { + return BasePropHandleT(idx); + } + } + return BasePropHandleT(); + } + + BaseProperty* property( const std::string& _name ) const + { + Properties::const_iterator p_it = properties_.begin(); + for (int idx=0; p_it != properties_.end(); ++p_it, ++idx) + { + if (*p_it != NULL && (*p_it)->name() == _name) //skip deleted properties + { + return *p_it; + } + } + return NULL; + } + + template PropertyT& property(BasePropHandleT _h) + { + assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); + assert(properties_[_h.idx()] != NULL); +#ifdef OM_FORCE_STATIC_CAST + return *static_cast *> (properties_[_h.idx()]); +#else + PropertyT* p = dynamic_cast*>(properties_[_h.idx()]); + assert(p != NULL); + return *p; +#endif + } + + + template const PropertyT& property(BasePropHandleT _h) const + { + assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); + assert(properties_[_h.idx()] != NULL); +#ifdef OM_FORCE_STATIC_CAST + return *static_cast*>(properties_[_h.idx()]); +#else + PropertyT* p = dynamic_cast*>(properties_[_h.idx()]); + assert(p != NULL); + return *p; +#endif + } + + + template void remove(BasePropHandleT _h) + { + assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); + delete properties_[_h.idx()]; + properties_[_h.idx()] = NULL; + } + + + void clear() + { + // Clear properties vector: + // Replaced the old version with new one + // which performs a swap to clear values and + // deallocate memory. + + // Old version (changed 22.07.09) { + // std::for_each(properties_.begin(), properties_.end(), Delete()); + // } + + std::for_each(properties_.begin(), properties_.end(), ClearAll()); + } + + + //---------------------------------------------------- synchronize properties + +/* + * In C++11 an beyond we can introduce more efficient and more legible + * implementations of the following methods. + */ +#if ((defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY) + /** + * Reserves space for \p _n elements in all property vectors. + */ + void reserve(size_t _n) const { + std::for_each(properties_.begin(), properties_.end(), + [_n](BaseProperty* p) { if (p) p->reserve(_n); }); + } + + /** + * Resizes all property vectors to the specified size. + */ + void resize(size_t _n) const { + std::for_each(properties_.begin(), properties_.end(), + [_n](BaseProperty* p) { if (p) p->resize(_n); }); + } + + /** + * Same as resize() but ignores property vectors that have a size larger + * than \p _n. + * + * Use this method instead of resize() if you plan to frequently reduce + * and enlarge the property container and you don't want to waste time + * reallocating the property vectors every time. + */ + void resize_if_smaller(size_t _n) const { + std::for_each(properties_.begin(), properties_.end(), + [_n](BaseProperty* p) { if (p && p->n_elements() < _n) p->resize(_n); }); + } + + /** + * Swaps the items with index \p _i0 and index \p _i1 in all property + * vectors. + */ + void swap(size_t _i0, size_t _i1) const { + std::for_each(properties_.begin(), properties_.end(), + [_i0, _i1](BaseProperty* p) { if (p) p->swap(_i0, _i1); }); + } +#else + /** + * Reserves space for \p _n elements in all property vectors. + */ + void reserve(size_t _n) const { + std::for_each(properties_.begin(), properties_.end(), Reserve(_n)); + } + + /** + * Resizes all property vectors to the specified size. + */ + void resize(size_t _n) const { + std::for_each(properties_.begin(), properties_.end(), Resize(_n)); + } + + /** + * Same as \sa resize() but ignores property vectors that have a size + * larger than \p _n. + * + * Use this method instead of \sa resize() if you plan to frequently reduce + * and enlarge the property container and you don't want to waste time + * reallocating the property vectors every time. + */ + void resize_if_smaller(size_t _n) const { + std::for_each(properties_.begin(), properties_.end(), ResizeIfSmaller(_n)); + } + + /** + * Swaps the items with index \p _i0 and index \p _i1 in all property + * vectors. + */ + void swap(size_t _i0, size_t _i1) const { + std::for_each(properties_.begin(), properties_.end(), Swap(_i0, _i1)); + } +#endif + + + +protected: // generic add/get + + size_t _add( BaseProperty* _bp ) + { + Properties::iterator p_it=properties_.begin(), p_end=properties_.end(); + size_t idx=0; + for (; p_it!=p_end && *p_it!=NULL; ++p_it, ++idx) {}; + if (p_it==p_end) properties_.push_back(NULL); + properties_[idx] = _bp; + return idx; + } + + BaseProperty& _property( size_t _idx ) + { + assert( _idx < properties_.size()); + assert( properties_[_idx] != NULL); + BaseProperty *p = properties_[_idx]; + assert( p != NULL ); + return *p; + } + + const BaseProperty& _property( size_t _idx ) const + { + assert( _idx < properties_.size()); + assert( properties_[_idx] != NULL); + BaseProperty *p = properties_[_idx]; + assert( p != NULL ); + return *p; + } + + + typedef Properties::iterator iterator; + typedef Properties::const_iterator const_iterator; + iterator begin() { return properties_.begin(); } + iterator end() { return properties_.end(); } + const_iterator begin() const { return properties_.begin(); } + const_iterator end() const { return properties_.end(); } + + friend class BaseKernel; + +private: + + //-------------------------------------------------- synchronization functors + +#ifndef DOXY_IGNORE_THIS + struct Reserve + { + Reserve(size_t _n) : n_(_n) {} + void operator()(BaseProperty* _p) const { if (_p) _p->reserve(n_); } + size_t n_; + }; + + struct Resize + { + Resize(size_t _n) : n_(_n) {} + void operator()(BaseProperty* _p) const { if (_p) _p->resize(n_); } + size_t n_; + }; + + struct ResizeIfSmaller + { + ResizeIfSmaller(size_t _n) : n_(_n) {} + void operator()(BaseProperty* _p) const { if (_p && _p->n_elements() < n_) _p->resize(n_); } + size_t n_; + }; + + struct ClearAll + { + ClearAll() {} + void operator()(BaseProperty* _p) const { if (_p) _p->clear(); } + }; + + struct Swap + { + Swap(size_t _i0, size_t _i1) : i0_(_i0), i1_(_i1) {} + void operator()(BaseProperty* _p) const { if (_p) _p->swap(i0_, i1_); } + size_t i0_, i1_; + }; + + struct Delete + { + Delete() {} + void operator()(BaseProperty* _p) const { if (_p) delete _p; _p=NULL; } + }; +#endif + + Properties properties_; +}; + +}//namespace OpenMesh + +#endif//OPENMESH_PROPERTYCONTAINER + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/PropertyManager.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/PropertyManager.hh new file mode 100644 index 0000000..ae8ad18 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/PropertyManager.hh @@ -0,0 +1,577 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + +#ifndef PROPERTYMANAGER_HH_ +#define PROPERTYMANAGER_HH_ + +#include +#include +#include + +namespace OpenMesh { + +/** + * This class is intended to manage the lifecycle of properties. + * It also defines convenience operators to access the encapsulated + * property's value. + * + * For C++11, it is recommended to use the factory functions + * makePropertyManagerFromNew, makePropertyManagerFromExisting, + * makePropertyManagerFromExistingOrNew to construct a PropertyManager, e.g. + * + * \code + * TriMesh mesh; + * auto visited = makePropertyManagerFromNew>(mesh, "visited.plugin-example.i8.informatik.rwth-aachen.de"); + * + * for (auto vh : mesh.vertices()) { + * if (!visited[vh]) { + * visitComponent(mesh, vh, visited); + * } + * } + * \endcode + * + * For C++98, it is usually more convenient to use the constructor explicitly, + * i.e. + * + * \code + * TriMesh mesh; + * PropertyManager, TriMesh> visited(mesh, "visited.plugin-example.i8.informatik.rwth-aachen.de"); + * + * for (TriMesh::VertexIter vh_it = mesh.begin(); ... ; ...) { + * if (!visited[*vh_it]) { + * visitComponent(mesh, *vh_it, visited); + * } + * } + * \endcode + * + */ +template +class PropertyManager { +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) + public: + PropertyManager(const PropertyManager&) = delete; + PropertyManager& operator=(const PropertyManager&) = delete; +#else + private: + /** + * Noncopyable because there aren't no straightforward copy semantics. + */ + PropertyManager(const PropertyManager&); + + /** + * Noncopyable because there aren't no straightforward copy semantics. + */ + PropertyManager& operator=(const PropertyManager&); +#endif + + public: + /** + * Constructor. + * + * Throws an \p std::runtime_error if \p existing is true and + * no property named \p propname of the appropriate property type + * exists. + * + * @param mesh The mesh on which to create the property. + * @param propname The name of the property. + * @param existing If false, a new property is created and its lifecycle is managed (i.e. + * the property is deleted upon destruction of the PropertyManager instance). If true, + * the instance merely acts as a convenience wrapper around an existing property with no + * lifecycle management whatsoever. + * + * @see PropertyManager::createIfNotExists, makePropertyManagerFromNew, + * makePropertyManagerFromExisting, makePropertyManagerFromExistingOrNew + */ + PropertyManager(MeshT &mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing), name_(propname) { + if (existing) { + if (!mesh_->get_property_handle(prop_, propname)) { + std::ostringstream oss; + oss << "Requested property handle \"" << propname << "\" does not exist."; + throw std::runtime_error(oss.str()); + } + } else { + mesh_->add_property(prop_, propname); + } + } + + PropertyManager() : mesh_(0), retain_(false) { + } + + ~PropertyManager() { + deleteProperty(); + } + + void swap(PropertyManager &rhs) { + std::swap(mesh_, rhs.mesh_); + std::swap(prop_, rhs.prop_); + std::swap(retain_, rhs.retain_); + std::swap(name_, rhs.name_); + } + + static bool propertyExists(MeshT &mesh, const char *propname) { + PROPTYPE dummy; + return mesh.get_property_handle(dummy, propname); + } + + bool isValid() const { return mesh_ != 0; } + operator bool() const { return isValid(); } + + const PROPTYPE &getRawProperty() const { return prop_; } + + const std::string &getName() const { return name_; } + + MeshT &getMesh() const { return *mesh_; } + +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) + /// Only for pre C++11 compatibility. + + typedef PropertyManager Proxy; + + /** + * Move constructor. Transfers ownership (delete responsibility). + */ + PropertyManager(PropertyManager &&rhs) : mesh_(rhs.mesh_), prop_(rhs.prop_), retain_(rhs.retain_), name_(rhs.name_) { + rhs.retain_ = true; + } + + /** + * Move assignment. Transfers ownership (delete responsibility). + */ + PropertyManager &operator=(PropertyManager &&rhs) { + if (&rhs != this) { + deleteProperty(); + mesh_ = rhs.mesh_; + prop_ = rhs.prop_; + retain_ = rhs.retain_; + name_ = rhs.name_; + rhs.retain_ = true; + } + return *this; + } + + /** + * Create a property manager for the supplied property and mesh. + * If the property doesn't exist, it is created. In any case, + * lifecycle management is disabled. + * + * @see makePropertyManagerFromExistingOrNew + */ + static PropertyManager createIfNotExists(MeshT &mesh, const char *propname) { + PROPTYPE dummy_prop; + PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); + pm.retain(); + 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); + pm.mesh_->property(pm.prop_) = mesh_->property(prop_); + return pm; + } + + /** + * Included for backwards compatibility with non-C++11 version. + */ + PropertyManager move() { + return std::move(*this); + } + +#else + class Proxy { + private: + Proxy(MeshT *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) : + mesh_(mesh_), prop_(prop_), retain_(retain_), name_(name_) {} + MeshT *mesh_; + PROPTYPE prop_; + bool retain_; + std::string name_; + + friend class PropertyManager; + }; + + operator Proxy() { + Proxy p(mesh_, prop_, retain_, name_); + mesh_ = 0; + retain_ = true; + return p; + } + + Proxy move() { + return (Proxy)*this; + } + + PropertyManager(Proxy p) : mesh_(p.mesh_), prop_(p.prop_), retain_(p.retain_), name_(p.name_) {} + + PropertyManager &operator=(Proxy p) { + PropertyManager(p).swap(*this); + return *this; + } + + /** + * Create a property manager for the supplied property and mesh. + * If the property doesn't exist, it is created. In any case, + * lifecycle management is disabled. + * + * @see makePropertyManagerFromExistingOrNew + */ + static Proxy createIfNotExists(MeshT &mesh, const char *propname) { + PROPTYPE dummy_prop; + PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); + pm.retain(); + 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_); + return (Proxy)pm; + } +#endif + + /** + * \brief Disable lifecycle management for this property. + * + * If this method is called, the encapsulated property will not be deleted + * upon destruction of the PropertyManager instance. + */ + inline void retain(bool doRetain = true) { + retain_ = doRetain; + } + + /** + * Access the encapsulated property. + */ + inline PROPTYPE &operator* () { + return prop_; + } + + /** + * Access the encapsulated property. + */ + inline const PROPTYPE &operator* () const { + return prop_; + } + + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + template + inline typename PROPTYPE::reference operator[] (const HandleType &handle) { + return mesh_->property(prop_, handle); + } + + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + template + inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const { + return mesh_->property(prop_, handle); + } + + /** + * Conveniently set the property for an entire range of values. + * + * Examples: + * \code + * MeshT mesh; + * PropertyManager, MeshT> distance( + * mesh, "distance.plugin-example.i8.informatik.rwth-aachen.de"); + * distance.set_range( + * mesh.vertices_begin(), mesh.vertices_end(), + * std::numeric_limits::infinity()); + * \endcode + * or + * \code + * MeshT::VertexHandle vh; + * distance.set_range( + * mesh.vv_begin(vh), mesh.vv_end(vh), + * std::numeric_limits::infinity()); + * \endcode + * + * @param begin Start iterator. Needs to dereference to HandleType. + * @param end End iterator. (Exclusive.) + * @param value The value the range will be set to. + */ + template + void set_range(HandleTypeIterator begin, HandleTypeIterator end, + const PROP_VALUE &value) { + for (; begin != end; ++begin) + (*this)[*begin] = value; + } + +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __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. + * + * @param begin Start iterator. Needs to dereference to HandleType. Will + * be used with this property manager. + * @param end End iterator. (Exclusive.) Will be used with this property + * manager. + * @param dst_propmanager The destination property manager. + * @param dst_begin Start iterator. Needs to dereference to the + * HandleType of dst_propmanager. Will be used with dst_propmanager. + * @param dst_end End iterator. (Exclusive.) + * Will be used with dst_propmanager. Used to double check the bounds. + */ + template + void copy_to(HandleTypeIterator begin, HandleTypeIterator end, + PropertyManager &dst_propmanager, + HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const { + + for (; begin != end && dst_begin != dst_end; ++begin, ++dst_begin) { + dst_propmanager[*dst_begin] = (*this)[*begin]; + } + } + + template + void copy_to(const RangeType &range, + PropertyManager &dst_propmanager, + const RangeType_2 &dst_range) const { + copy_to(range.begin(), range.end(), dst_propmanager, + dst_range.begin(), dst_range.end()); + } + + /** + * Copy the values of a property from a source range to + * a target range. The source range must not be smaller than the + * target range. + * + * @param prop_name Name of the property to copy. Must exist on the + * source mesh. Will be created on the target mesh if it doesn't exist. + * + * @param src_mesh Source mesh from which to copy. + * @param src_range Source range which to copy. Must not be smaller than + * dst_range. + * @param dst_mesh Destination mesh on which to copy. + * @param dst_range Destination range. + */ + template + static void copy(const char *prop_name, + MeshT &src_mesh, const RangeType &src_range, + MeshT_2 &dst_mesh, const RangeType_2 &dst_range) { + + typedef OpenMesh::PropertyManager DstPM; + DstPM dst(DstPM::createIfNotExists(dst_mesh, prop_name)); + + typedef OpenMesh::PropertyManager SrcPM; + SrcPM src(src_mesh, prop_name, true); + + src.copy_to(src_range, dst, dst_range); + } + + private: + void deleteProperty() { + if (!retain_) + mesh_->remove_property(prop_); + } + + private: + MeshT *mesh_; + PROPTYPE prop_; + bool retain_; + std::string name_; +}; + +/** \relates PropertyManager + * Creates a new property whose lifecycle is managed by the returned + * PropertyManager. + * + * Intended for temporary properties. Shadows any existsing properties of + * matching name and type. + */ +template +PropertyManager makePropertyManagerFromNew(MeshT &mesh, const char *propname) { + return PropertyManager(mesh, propname, false); +} + +/** \relates PropertyManager + * Creates a non-owning wrapper for an existing mesh property (no lifecycle + * management). + * + * Intended for convenient access. + * + * @pre Property with the name \p propname of matching type exists. + * @throws std::runtime_error if no property with the name \p propname of + * matching type exists. + */ +template +PropertyManager makePropertyManagerFromExisting(MeshT &mesh, const char *propname) { + return PropertyManager(mesh, propname, true); +} + +/** \relates PropertyManager + * 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) { + 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/libs/OpenMesh/include/OpenMesh/Core/Utils/RandomNumberGenerator.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/RandomNumberGenerator.hh new file mode 100644 index 0000000..aaedfcd --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/RandomNumberGenerator.hh @@ -0,0 +1,117 @@ +/* ========================================================================= * + * * + * 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: 693 $ * + * $Date: 2012-09-23 16:25:16 +0200 (So, 23 Sep 2012) $ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for generating a random number between 0.0 and 1.0 with +// a garantueed resolution +// +//============================================================================= + + +#ifndef OPENMESH_UTILS_RANDOMNUMBERGENERATOR_HH +#define OPENMESH_UTILS_RANDOMNUMBERGENERATOR_HH + + +//== INCLUDES ================================================================= + + +#include +#include + + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//============================================================================= + + +/** Generate a random number between 0.0 and 1.0 with a guaranteed resolution + * ( Number of possible values ) + * + * Especially useful on windows, as there MAX_RAND is often only 32k which is + * not enough resolution for a lot of applications + */ +class OPENMESHDLLEXPORT RandomNumberGenerator +{ +public: + + /** \brief Constructor + * + * @param _resolution specifies the desired resolution for the random number generated + */ + explicit RandomNumberGenerator(const size_t _resolution); + + /// returns a random double between 0.0 and 1.0 with a guaranteed resolution + double getRand() const; + + double resolution() const; + +private: + + /// desired resolution + const size_t resolution_; + + /// number of "blocks" of RAND_MAX that make up the desired _resolution + size_t iterations_; + + /// maximum random number generated, which is used for normalization + double maxNum_; +}; + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_UTILS_RANDOMNUMBERGENERATOR_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.hh new file mode 100644 index 0000000..b0745c4 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.hh @@ -0,0 +1,154 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Implements a simple singleton template +// +//============================================================================= + + +#ifndef __SINGLETON_HH__ +#define __SINGLETON_HH__ + + +//=== INCLUDES ================================================================ + +// OpenMesh +#include + +// STL +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//=== IMPLEMENTATION ========================================================== + + +/** A simple singleton template. + Encapsulates an arbitrary class and enforces its uniqueness. +*/ + +template +class SingletonT +{ +public: + + /** Singleton access function. + Use this function to obtain a reference to the instance of the + encapsulated class. Note that this instance is unique and created + on the first call to Instance(). + */ + + static T& Instance() + { + if (!pInstance__) + { + // check if singleton alive + if (destroyed__) + { + OnDeadReference(); + } + // first time request -> initialize + else + { + Create(); + } + } + return *pInstance__; + } + + +private: + + // Disable constructors/assignment to enforce uniqueness + SingletonT(); + SingletonT(const SingletonT&); + SingletonT& operator=(const SingletonT&); + + // Create a new singleton and store its pointer + static void Create() + { + static T theInstance; + pInstance__ = &theInstance; + } + + // Will be called if instance is accessed after its lifetime has expired + static void OnDeadReference() + { + throw std::runtime_error("[Singelton error] - Dead reference detected!\n"); + } + + virtual ~SingletonT() + { + pInstance__ = 0; + destroyed__ = true; + } + + static T* pInstance__; + static bool destroyed__; +}; + + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SINGLETON_C) +# define OPENMESH_SINGLETON_TEMPLATES +# include "SingletonT.cc" +#endif +//============================================================================= +#endif // __SINGLETON_HH__ +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/color_cast.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/color_cast.hh new file mode 100644 index 0000000..0dd9901 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/color_cast.hh @@ -0,0 +1,385 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + + +#ifndef OPENMESH_COLOR_CAST_HH +#define OPENMESH_COLOR_CAST_HH + + +//== INCLUDES ================================================================= + + +#include +#include + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//============================================================================= + + +/** \name Cast vector type to another vector type. +*/ +//@{ + +//----------------------------------------------------------------------------- +#ifndef DOXY_IGNORE_THIS + +/// Cast one color vector to another. +template +struct color_caster +{ + typedef dst_t return_type; + + inline static return_type cast(const src_t& _src) + { + dst_t dst; + vector_cast(_src, dst, GenProg::Int2Type::size_>()); + return dst; + } +}; + + +template <> +struct color_caster +{ + typedef Vec3uc return_type; + + inline static return_type cast(const Vec3f& _src) + { + return Vec3uc( (unsigned char)(_src[0]* 255.0f + 0.5f), + (unsigned char)(_src[1]* 255.0f + 0.5f), + (unsigned char)(_src[2]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3uc return_type; + + inline static return_type cast(const Vec4f& _src) + { + return Vec3uc( (unsigned char)(_src[0]* 255.0f + 0.5f), + (unsigned char)(_src[1]* 255.0f + 0.5f), + (unsigned char)(_src[2]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3i return_type; + + inline static return_type cast(const Vec3f& _src) + { + return Vec3i( (int)(_src[0]* 255.0f + 0.5f), + (int)(_src[1]* 255.0f + 0.5f), + (int)(_src[2]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3i return_type; + + inline static return_type cast(const Vec4f& _src) + { + return Vec3i( (int)(_src[0]* 255.0f + 0.5f), + (int)(_src[1]* 255.0f + 0.5f), + (int)(_src[2]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4i return_type; + + inline static return_type cast(const Vec4f& _src) + { + return Vec4i( (int)(_src[0]* 255.0f + 0.5f), + (int)(_src[1]* 255.0f + 0.5f), + (int)(_src[2]* 255.0f + 0.5f), + (int)(_src[3]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3ui return_type; + + inline static return_type cast(const Vec3f& _src) + { + return Vec3ui( (unsigned int)(_src[0]* 255.0f + 0.5f), + (unsigned int)(_src[1]* 255.0f + 0.5f), + (unsigned int)(_src[2]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3ui return_type; + + inline static return_type cast(const Vec4f& _src) + { + return Vec3ui( (unsigned int)(_src[0]* 255.0f + 0.5f), + (unsigned int)(_src[1]* 255.0f + 0.5f), + (unsigned int)(_src[2]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4ui return_type; + + inline static return_type cast(const Vec4f& _src) + { + return Vec4ui( (unsigned int)(_src[0]* 255.0f + 0.5f), + (unsigned int)(_src[1]* 255.0f + 0.5f), + (unsigned int)(_src[2]* 255.0f + 0.5f), + (unsigned int)(_src[3]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4uc return_type; + + inline static return_type cast(const Vec3f& _src) + { + return Vec4uc( (unsigned char)(_src[0]* 255.0f + 0.5f), + (unsigned char)(_src[1]* 255.0f + 0.5f), + (unsigned char)(_src[2]* 255.0f + 0.5f), + (unsigned char)(255) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4f return_type; + + inline static return_type cast(const Vec3f& _src) + { + return Vec4f( _src[0], + _src[1], + _src[2], + 1.0f ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4ui return_type; + + inline static return_type cast(const Vec3uc& _src) + { + return Vec4ui(_src[0], + _src[1], + _src[2], + 255 ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4f return_type; + + inline static return_type cast(const Vec3i& _src) + { + const float f = 1.0f / 255.0f; + return Vec4f(_src[0]*f, _src[1]*f, _src[2]*f, 1.0f ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4uc return_type; + + inline static return_type cast(const Vec4f& _src) + { + return Vec4uc( (unsigned char)(_src[0]* 255.0f + 0.5f), + (unsigned char)(_src[1]* 255.0f + 0.5f), + (unsigned char)(_src[2]* 255.0f + 0.5f), + (unsigned char)(_src[3]* 255.0f + 0.5f) ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4f return_type; + + inline static return_type cast(const Vec4i& _src) + { + const float f = 1.0f / 255.0f; + return Vec4f( _src[0] * f, _src[1] * f, _src[2] * f , _src[3] * f ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4uc return_type; + + inline static return_type cast(const Vec3uc& _src) + { + return Vec4uc( _src[0], _src[1], _src[2], 255 ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3f return_type; + + inline static return_type cast(const Vec3uc& _src) + { + const float f = 1.0f / 255.0f; + return Vec3f(_src[0] * f, _src[1] * f, _src[2] * f ); + } +}; + +template <> +struct color_caster +{ + typedef Vec3f return_type; + + inline static return_type cast(const Vec4uc& _src) + { + const float f = 1.0f / 255.0f; + return Vec3f(_src[0] * f, _src[1] * f, _src[2] * f ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4f return_type; + + inline static return_type cast(const Vec3uc& _src) + { + const float f = 1.0f / 255.0f; + return Vec4f(_src[0] * f, _src[1] * f, _src[2] * f, 1.0f ); + } +}; + +template <> +struct color_caster +{ + typedef Vec4f return_type; + + inline static return_type cast(const Vec4uc& _src) + { + const float f = 1.0f / 255.0f; + return Vec4f(_src[0] * f, _src[1] * f, _src[2] * f, _src[3] * f ); + } +}; + +// ---------------------------------------------------------------------------- + + +#ifndef DOXY_IGNORE_THIS + +#if !defined(OM_CC_MSVC) +template +struct color_caster +{ + typedef const dst_t& return_type; + + inline static return_type cast(const dst_t& _src) + { + return _src; + } +}; +#endif + +#endif + +//----------------------------------------------------------------------------- + + +template +inline +typename color_caster::return_type +color_cast(const src_t& _src ) +{ + return color_caster::cast(_src); +} + +#endif +//----------------------------------------------------------------------------- + +//@} + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_COLOR_CAST_HH defined +//============================================================================= + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/vector_cast.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/vector_cast.hh new file mode 100644 index 0000000..39fca19 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/vector_cast.hh @@ -0,0 +1,163 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + + +#ifndef OPENMESH_VECTORCAST_HH +#define OPENMESH_VECTORCAST_HH + + +//== INCLUDES ================================================================= + + +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//============================================================================= + + +/** \name Cast vector type to another vector type. +*/ +//@{ + +//----------------------------------------------------------------------------- + +template +inline void vector_cast( const src_t &_src, dst_t &_dst, GenProg::Int2Type ) +{ + assert_compile(vector_traits::size_ <= vector_traits::size_) + vector_cast(_src,_dst, GenProg::Int2Type()); + _dst[n-1] = static_cast::value_type >(_src[n-1]); +} + +template +inline void vector_cast( const src_t & /*_src*/, dst_t & /*_dst*/, GenProg::Int2Type<0> ) +{ +} + +template +inline void vector_copy( const src_t &_src, dst_t &_dst, GenProg::Int2Type ) +{ + assert_compile(vector_traits::size_ <= vector_traits::size_) + vector_copy(_src,_dst, GenProg::Int2Type()); + _dst[n-1] = _src[n-1]; +} + +template +inline void vector_copy( const src_t & /*_src*/, dst_t & /*_dst*/ , GenProg::Int2Type<0> ) +{ +} + + + +//----------------------------------------------------------------------------- +#ifndef DOXY_IGNORE_THIS + +template +struct vector_caster +{ + typedef dst_t return_type; + + inline static return_type cast(const src_t& _src) + { + dst_t dst; + vector_cast(_src, dst, GenProg::Int2Type::size_>()); + return dst; + } +}; + +#if !defined(OM_CC_MSVC) +template +struct vector_caster +{ + typedef const dst_t& return_type; + + inline static return_type cast(const dst_t& _src) + { + return _src; + } +}; +#endif + +#endif +//----------------------------------------------------------------------------- + + +/// Cast vector type to another vector type by copying the vector elements +template +inline +typename vector_caster::return_type +vector_cast(const src_t& _src ) +{ + return vector_caster::cast(_src); +} + + +//@} + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESHREADER_HH defined +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/vector_traits.hh b/libs/OpenMesh/include/OpenMesh/Core/Utils/vector_traits.hh new file mode 100644 index 0000000..fb78b3c --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/vector_traits.hh @@ -0,0 +1,115 @@ +/* ========================================================================= * + * * + * 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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + + +#ifndef OPENMESH_VECTOR_TRAITS_HH +#define OPENMESH_VECTOR_TRAITS_HH + + +//== INCLUDES ================================================================= + +#include +#include +#if defined(OM_CC_MIPS) +# include +#else +# include +#endif + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//============================================================================= + + +/** \name Provide a standardized access to relevant information about a + vector type. +*/ +//@{ + +//----------------------------------------------------------------------------- + +/** Helper class providing information about a vector type. + * + * If want to use a different vector type than the one provided %OpenMesh + * you need to supply a specialization of this class for the new vector type. + */ +template +struct vector_traits +{ + /// Type of the vector class + typedef typename T::vector_type vector_type; + + /// Type of the scalar value + typedef typename T::value_type value_type; + + /// size/dimension of the vector + static const size_t size_ = T::size_; + + /// size/dimension of the vector + static size_t size() { return size_; } +}; + +//@} + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_MESHREADER_HH defined +//============================================================================= diff --git a/libs/OpenMesh/liblinux/libOpenMeshCore.a b/libs/OpenMesh/liblinux/libOpenMeshCore.a new file mode 100644 index 0000000..29578ff Binary files /dev/null and b/libs/OpenMesh/liblinux/libOpenMeshCore.a differ diff --git a/libs/OpenMesh/libwin/OpenMeshCore.lib b/libs/OpenMesh/libwin/OpenMeshCore.lib new file mode 100644 index 0000000..1521cdd Binary files /dev/null and b/libs/OpenMesh/libwin/OpenMeshCore.lib differ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..0eab917 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,16 @@ +#include "main_window.h" +#include +#include + + +int main(int argc, char *argv[]) { + using namespace std; + QApplication app(argc, argv); + if (argc > 2) { + cerr << "Utilisation : " << argv[0] << " [fichier OBJ]" << endl; + return 1; + } + MainWindow mw; + mw.show(); + return app.exec(); +} diff --git a/src/main_window.cpp b/src/main_window.cpp new file mode 100644 index 0000000..d9568ee --- /dev/null +++ b/src/main_window.cpp @@ -0,0 +1,56 @@ +#include "main_window.h" + +#include +#include + + +MainWindow::MainWindow(QWidget *parent) + :QMainWindow(parent), + mesh_viewer(this), + toolbar(this) { + connect(&mesh_viewer, &MeshViewer::initialized, this, &MainWindow::meshViewerInitialized); + setCentralWidget(&mesh_viewer); + addToolBar(Qt::RightToolBarArea, &toolbar); + open_action = toolbar.addAction("Ouvrir…", [&](){ + open(QFileDialog::getOpenFileName(this, "Ouvrir un fichier OBJ")); + }); + // toolbar_actions.append(toolbar.addAction("Fractionner", [&](){ + // QVector> fragments = shatter(mesh); + // mesh_viewer.removeOpenGLMesh(glm); + // for (auto &[pos, fragment] : fragments) { + // fragment.triangulate(); + // QMatrix4x4 mat; + // float scale = 1.2; + // mat.translate(pos[0] * scale, pos[1] * scale, pos[2] * scale); + // mesh_viewer.addOpenGLMeshFromOpenMesh(&fragment, mat); + // } + // })); + open_action->setEnabled(false); + for (QAction *a : toolbar_actions) { + a->setEnabled(false); + } +} + + +void MainWindow::open(const QString &path) { + if (!OpenMesh::IO::read_mesh(mesh, path.toUtf8().constData())) { + qWarning() << "Failed to read" << path; + return; + } + for (const VertexHandle &vh : mesh.vertices()) { + mesh.set_color(vh, MyMesh::Color(.5, .5, .5)); + } + if (glm != nullptr) mesh_viewer.removeOpenGLMesh(glm); + glm = mesh_viewer.addOpenGLMeshFromOpenMesh(&mesh); + for (QAction *a : toolbar_actions) { + a->setEnabled(true); + } +} + + +void MainWindow::meshViewerInitialized() { + if (qApp->arguments().size() == 2) { + open(qApp->arguments().at(1)); + } + open_action->setEnabled(true); +} diff --git a/src/main_window.h b/src/main_window.h new file mode 100644 index 0000000..54d3be2 --- /dev/null +++ b/src/main_window.h @@ -0,0 +1,32 @@ +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include +#include + +#include "mesh_viewer.h" +#include "my_mesh.h" + + +class MainWindow : public QMainWindow { + Q_OBJECT + +public: + MainWindow(QWidget *parent=nullptr); + void open(const QString &path); + +private slots: + void meshViewerInitialized(); + +private: + MyMesh mesh; + MeshViewer mesh_viewer; + OpenGLMesh *glm = nullptr; + QToolBar toolbar; + QAction *open_action; + QList toolbar_actions; + +}; + + +#endif diff --git a/src/mesh_viewer.cpp b/src/mesh_viewer.cpp new file mode 100644 index 0000000..c648a60 --- /dev/null +++ b/src/mesh_viewer.cpp @@ -0,0 +1,261 @@ +#include "mesh_viewer.h" + +#include +#include + + +const GLchar *vertex_shader_source = R"glsl( +#version 150 core + +in vec3 pos; +in vec3 col; + +out vec3 frag_col; + +uniform mat4 proj; +uniform mat4 view; +uniform mat4 model; + +void main() { + gl_Position = proj * view * model * vec4(pos, 1.0); + frag_col = col; +} +)glsl"; + +const GLchar *fragment_shader_source = R"glsl( +#version 150 core + +in vec3 frag_col; +out vec4 final_col; + +uniform vec3 wf_col; +uniform bool wireframe; +uniform float alpha; + +void main() { + if (wireframe) + final_col = vec4(wf_col, alpha); + else + final_col = vec4(frag_col, alpha); +} +)glsl"; + + +MeshViewer::MeshViewer(QWidget *parent) : QOpenGLWidget(parent) { + setMouseTracking(true); + setFocus(); +} + + +void GLAPIENTRY +opengl_debug_cb(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) { + (void) source; + (void) type; + (void) id; + (void) severity; + (void) length; + (void) userParam; + qDebug() << "OpenGL debug output:" << message; +} + + +void MeshViewer::initializeGL() { + // initializeOpenGLFunctions(); + + GLint major, minor; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + qDebug("OpenGL version %d.%d", major, minor); + + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(opengl_debug_cb, 0); + + /* Compile the vertex shader. */ + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); + glCompileShader(vertex_shader); + GLint status; + glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) { + char log[1024]; + glGetShaderInfoLog(vertex_shader, sizeof log, NULL, log); + fprintf(stderr, "Failed to compile the vertex shader: %s\n", log); + exit(1); + } + + /* Compile the fragment shader. */ + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); + glCompileShader(fragment_shader); + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) { + char log[1024]; + glGetShaderInfoLog(fragment_shader, sizeof log, NULL, log); + fprintf(stderr, "Failed to compile the fragment shader: %s\n", log); + exit(1); + } + + /* Link the shader program. */ + GLuint shader_program = glCreateProgram(); + glAttachShader(shader_program, vertex_shader); + glAttachShader(shader_program, fragment_shader); + glBindFragDataLocation(shader_program, 0, "out_color"); + glLinkProgram(shader_program); + glGetProgramiv(shader_program, GL_LINK_STATUS, &status); + if (status != GL_TRUE) { + char log[1024]; + glGetProgramInfoLog(shader_program, sizeof log, NULL, log); + fprintf(stderr, "Failed to link the shader program: %s\n", log); + exit(1); + } + + /* Use it. */ + glUseProgram(shader_program); + + /* Get the position attribute. */ + pos_attr = glGetAttribLocation(shader_program, "pos"); + col_attr = glGetAttribLocation(shader_program, "col"); + + proj_attr = glGetUniformLocation(shader_program, "proj"); + view_attr = glGetUniformLocation(shader_program, "view"); + model_attr = glGetUniformLocation(shader_program, "model"); + wf_col_attr = glGetUniformLocation(shader_program, "wf_col"); + wireframe_attr = glGetUniformLocation(shader_program, "wireframe"); + alpha_attr = glGetUniformLocation(shader_program, "alpha"); + + glUniform1f(alpha_attr, 1); + glUniform3f(wf_col_attr, WIREFRAME_COLOR); + + glClearColor(1, 1, 1, 0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + + emit initialized(); +} + + +void MeshViewer::resizeGL(int w, int h) { + QMatrix4x4 projection; + projection.perspective(FOV, (float) w/h, .01, 100); + glUniformMatrix4fv(proj_attr, 1, GL_FALSE, projection.data()); +} + + +void MeshViewer::paintGL() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + QMatrix4x4 trans; + trans.translate(0, 0, -cam_dist); + QMatrix4x4 view = trans * rot; + glUniformMatrix4fv(view_attr, 1, GL_FALSE, view.data()); + for (const OpenGLMesh m : meshes) { + glUniformMatrix4fv(model_attr, 1, GL_FALSE, m.mat.data()); + + /* Mesh */ + glBindVertexArray(m.vao); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.0, 2); + glDrawArrays(GL_TRIANGLES, 0, m.nverts); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDisable(GL_POLYGON_OFFSET_FILL); + + /* Wireframe */ + glUniform1f(wireframe_attr, 1); + glDrawArrays(GL_TRIANGLES, 0, m.nverts); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1); + glUniform1f(wireframe_attr, 0); + } +} + + +OpenGLMesh *MeshViewer::addOpenGLMesh(size_t nverts, const GLfloat *verts, QMatrix4x4 mat, QColor col) { + makeCurrent(); + + GLuint vao, vbo; + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, nverts * 6 * sizeof (GLfloat), verts, GL_DYNAMIC_DRAW); + glVertexAttribPointer(pos_attr, 3, GL_FLOAT, GL_FALSE, 6 * sizeof (GLfloat), 0); + glEnableVertexAttribArray(pos_attr); + glVertexAttribPointer(col_attr, 3, GL_FLOAT, GL_FALSE, 6 * sizeof (GLfloat), + (const void *) (3 * sizeof (GLfloat))); + glEnableVertexAttribArray(col_attr); + + glBindVertexArray(0); + + meshes.append({vao, vbo, nverts, mat, col}); + doneCurrent(); + update(); + return &meshes.last(); +} + + +OpenGLMesh *MeshViewer::addOpenGLMeshFromOpenMesh(MyMesh* mesh, QMatrix4x4 mat, QColor col) { + GLfloat *verts = new GLfloat[mesh->n_faces() * 3 * 6]; + size_t i = 0; + + for (MyMesh::FaceHandle face : mesh->faces()) { + for (MyMesh::VertexHandle vec : mesh->fv_range(face)) { + verts[6*i + 0] = mesh->point(vec)[0]; + verts[6*i + 1] = mesh->point(vec)[1]; + verts[6*i + 2] = mesh->point(vec)[2]; + verts[6*i + 3] = mesh->color(vec)[0]; + verts[6*i + 4] = mesh->color(vec)[1]; + verts[6*i + 5] = mesh->color(vec)[2]; + i++; + } + } + + OpenGLMesh *ret = addOpenGLMesh(i, verts, mat, col); + delete[] verts; + return ret; +} + + +void MeshViewer::removeOpenGLMesh(OpenGLMesh *mesh) { + glDeleteVertexArrays(1, &mesh->vao); + glDeleteBuffers(1, &mesh->vbo); + for (int i = 0; i < meshes.size(); i++) { + if (&meshes[i] == mesh) meshes.removeAt(i); + } +} + + +void MeshViewer::mousePressEvent(QMouseEvent *e) { + if (e->button() == Qt::LeftButton) { + mouse_pos = e->pos(); + } +} + + +void MeshViewer::mouseReleaseEvent(QMouseEvent *e) { + (void) e; + rot_start = rot; +} + + +void MeshViewer::mouseMoveEvent(QMouseEvent *e) { + if (e->buttons() & Qt::LeftButton) { + QPoint delta = e->pos() - mouse_pos; + rot = rot_start; + rot.rotate(delta.x() / 5., 0, 1, 0); + rot.rotate(delta.y() / 5., QVector3D(1, 0, 0) * rot); + update(); + } +} + + +void MeshViewer::wheelEvent(QWheelEvent *e) { + cam_dist -= e->angleDelta().y() / 1000. * cam_dist; + update(); +} diff --git a/src/mesh_viewer.h b/src/mesh_viewer.h new file mode 100644 index 0000000..f8db306 --- /dev/null +++ b/src/mesh_viewer.h @@ -0,0 +1,64 @@ +#ifndef MESH_VIEWER_H +#define MESH_VIEWER_H + +#define GL_GLEXT_PROTOTYPES +#include "my_mesh.h" +#include +#include +#include +#include +#include +#include +#include + + +#define WIREFRAME_COLOR 0, 0, 0 +#define FOV 70 + + +using namespace OpenMesh; + + +struct OpenGLMesh { + GLuint vao; + GLuint vbo; + size_t nverts; + QMatrix4x4 mat; + QColor col; +}; + + +class MeshViewer : public QOpenGLWidget { + Q_OBJECT + +public: + MeshViewer(QWidget *parent=nullptr); + void initializeGL() override; + void resizeGL(int w, int h) override; + void paintGL() override; + OpenGLMesh *addOpenGLMesh(size_t nverts, const GLfloat *verts, QMatrix4x4 mat=QMatrix4x4(), QColor col={153, 153, 153}); + OpenGLMesh *addOpenGLMeshFromOpenMesh(MyMesh* _mesh, QMatrix4x4 mat=QMatrix4x4(), QColor col={153, 153, 153}); + void removeOpenGLMesh(OpenGLMesh *mesh); + void setOpenGLMeshMatrix(OpenGLMesh *mv, QMatrix4x4 mat); + +private: + QList meshes; + GLint pos_attr, col_attr, proj_attr, view_attr, model_attr; + GLint wf_col_attr, wireframe_attr, alpha_attr; + QMatrix4x4 proj; + QMatrix4x4 rot, rot_start; + GLfloat cam_dist = 1; + QPoint mouse_pos; + +protected: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e); + virtual void wheelEvent(QWheelEvent *e); + +signals: + void initialized(); +}; + + +#endif diff --git a/src/my_mesh.h b/src/my_mesh.h new file mode 100644 index 0000000..307878e --- /dev/null +++ b/src/my_mesh.h @@ -0,0 +1,19 @@ +#ifndef MY_MESH_H +#define MY_MESH_H + +#include +#include +#include + + +struct MyTraits : public OpenMesh::DefaultTraits { + VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Color); + HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge); + FaceAttributes(OpenMesh::Attributes::Normal); + EdgeAttributes(OpenMesh::Attributes::Color); + typedef OpenMesh::Vec3f Color; +}; +typedef OpenMesh::PolyMesh_ArrayKernelT MyMesh; + + +#endif diff --git a/tp.pro b/tp.pro new file mode 100644 index 0000000..e8be321 --- /dev/null +++ b/tp.pro @@ -0,0 +1,25 @@ +QT += core gui widgets +TARGET = tp +TEMPLATE = app +DEFINES += QT_DEPRECATED_WARNINGS +CONFIG += qt debug c++17 +INCLUDEPATH += $$PWD/libs/OpenMesh/include/ +DEFINES += OM_STATIC_BUILD + +unix:!macx { + LIBS += -L$$PWD/libs/OpenMesh/liblinux/ -lOpenMeshCore +} +macx { + LIBS += -L$$PWD/libs/OpenMesh/libosx/ -lOpenMeshCore +} +win32 { + LIBS += $$PWD/libs/OpenMesh/libwin/OpenMeshCore.lib +} + +HEADERS += src/my_mesh.h +HEADERS += src/main_window.h +HEADERS += src/mesh_viewer.h + +SOURCES += src/main.cpp +SOURCES += src/main_window.cpp +SOURCES += src/mesh_viewer.cpp