From c4e7bb140a553777081bd7cba714c9b5bbf27c93 Mon Sep 17 00:00:00 2001 From: papush! Date: Fri, 24 Sep 2021 23:01:56 +0200 Subject: [PATCH] inclusion des fichiers manquants d'OpenMesh --- .../OpenMesh/Core/Geometry/NormalConeT.cc | 161 ++++++ .../include/OpenMesh/Core/IO/OMFormatT.cc | 245 +++++++++ .../OpenMesh/Core/Mesh/ArrayKernelT.cc | 315 ++++++++++++ .../include/OpenMesh/Core/Mesh/PolyMeshT.cc | 463 ++++++++++++++++++ .../include/OpenMesh/Core/Mesh/TriMeshT.cc | 93 ++++ .../include/OpenMesh/Core/Utils/SingletonT.cc | 85 ++++ 6 files changed, 1362 insertions(+) create mode 100644 libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.cc create mode 100644 libs/OpenMesh/include/OpenMesh/Core/IO/OMFormatT.cc create mode 100644 libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernelT.cc create mode 100644 libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.cc create mode 100644 libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.cc create mode 100644 libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.cc diff --git a/libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.cc b/libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.cc new file mode 100644 index 0000000..d5281bf --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Geometry/NormalConeT.cc @@ -0,0 +1,161 @@ +/* ========================================================================= * + * * + * 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 NormalConeT - IMPLEMENTATION +// +//============================================================================= + +#define OPENMESH_NORMALCONE_C + +//== INCLUDES ================================================================= + +#include +#include "NormalConeT.hh" + +#ifdef max +# undef max +#endif + +#ifdef min +# undef min +#endif + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== IMPLEMENTATION ========================================================== + +template +NormalConeT:: +NormalConeT(const Vec3& _center_normal, Scalar _angle) + : center_normal_(_center_normal), angle_(_angle) +{ +} + + +//---------------------------------------------------------------------------- + + +template +Scalar +NormalConeT:: +max_angle(const Vec3& _norm) const +{ + Scalar dotp = (center_normal_ | _norm); + return (dotp >= 1.0 ? 0.0 : (dotp <= -1.0 ? M_PI : acos(dotp))) + + angle_; +} + + +//---------------------------------------------------------------------------- + + +template +Scalar +NormalConeT:: +max_angle(const NormalConeT& _cone) const +{ + Scalar dotp = (center_normal_ | _cone.center_normal_); + Scalar centerAngle = dotp >= 1.0 ? 0.0 : (dotp <= -1.0 ? M_PI : acos(dotp)); + Scalar sideAngle0 = std::max(angle_-centerAngle, _cone.angle_); + Scalar sideAngle1 = std::max(_cone.angle_-centerAngle, angle_); + + return centerAngle + sideAngle0 + sideAngle1; +} + + +//---------------------------------------------------------------------------- + + +template +void +NormalConeT:: +merge(const NormalConeT& _cone) +{ + Scalar dotp = (center_normal_ | _cone.center_normal_); + + if (fabs(dotp) < 0.99999f) + { + // new angle + Scalar centerAngle = acos(dotp); + Scalar minAngle = std::min(-angle(), centerAngle - _cone.angle()); + Scalar maxAngle = std::max( angle(), centerAngle + _cone.angle()); + angle_ = (maxAngle - minAngle) * Scalar(0.5f); + + // axis by SLERP + Scalar axisAngle = Scalar(0.5f) * (minAngle + maxAngle); + center_normal_ = ((center_normal_ * sin(centerAngle-axisAngle) + + _cone.center_normal_ * sin(axisAngle)) + / sin(centerAngle)); + } + else + { + // axes point in same direction + if (dotp > 0.0f) + angle_ = std::max(angle_, _cone.angle_); + + // axes point in opposite directions + else + angle_ = Scalar(2.0f * M_PI); + } +} + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/IO/OMFormatT.cc b/libs/OpenMesh/include/OpenMesh/Core/IO/OMFormatT.cc new file mode 100644 index 0000000..fa332b1 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/IO/OMFormatT.cc @@ -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$ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for binary reading / writing +// +//============================================================================= + + +#define OPENMESH_IO_OMFORMAT_CC + + +//== INCLUDES ================================================================= + +#include +#include +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace IO { + + // 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) + { + assert( OMFormat::is_integer( _val ) ); + + switch( _b ) + { + case OMFormat::Chunk::Integer_8: + { + OMFormat::int8 v = static_cast(_val); + return store( _os, v, _swap ); + } + case OMFormat::Chunk::Integer_16: + { + OMFormat::int16 v = static_cast(_val); + return store( _os, v, _swap ); + } + case OMFormat::Chunk::Integer_32: + { + OMFormat::int32 v = static_cast(_val); + return store( _os, v, _swap ); + } + case OMFormat::Chunk::Integer_64: + { + OMFormat::int64 v = static_cast(_val); + return store( _os, v, _swap ); + } + } + return 0; + } + + + // 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) + { + assert( OMFormat::is_integer( _val ) ); + + switch( _b ) + { + case OMFormat::Chunk::Integer_8: + { + OMFormat::uint8 v = static_cast(_val); + return store( _os, v, _swap ); + } + case OMFormat::Chunk::Integer_16: + { + OMFormat::uint16 v = static_cast(_val); + return store( _os, v, _swap ); + } + case OMFormat::Chunk::Integer_32: + { + OMFormat::uint32 v = static_cast(_val); + return store( _os, v, _swap ); + } + + case OMFormat::Chunk::Integer_64: + { + OMFormat::uint64 v = static_cast(_val); + return store( _os, v, _swap ); + } + } + return 0; + } + + + // helper to restore a an integer + template< typename T > + size_t + restore( std::istream& _is, + T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap, + t_signed) + { + assert( OMFormat::is_integer( _val ) ); + size_t bytes = 0; + + switch( _b ) + { + case OMFormat::Chunk::Integer_8: + { + OMFormat::int8 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + case OMFormat::Chunk::Integer_16: + { + OMFormat::int16 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + case OMFormat::Chunk::Integer_32: + { + OMFormat::int32 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + case OMFormat::Chunk::Integer_64: + { + OMFormat::int64 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + } + return bytes; + } + + + // helper to restore a an unsigned integer + template< typename T > + size_t + restore( std::istream& _is, + T& _val, + OMFormat::Chunk::Integer_Size _b, + bool _swap, + t_unsigned) + { + assert( OMFormat::is_integer( _val ) ); + size_t bytes = 0; + + switch( _b ) + { + case OMFormat::Chunk::Integer_8: + { + OMFormat::uint8 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + case OMFormat::Chunk::Integer_16: + { + OMFormat::uint16 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + case OMFormat::Chunk::Integer_32: + { + OMFormat::uint32 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + + case OMFormat::Chunk::Integer_64: + { + OMFormat::uint64 v; + bytes = restore( _is, v, _swap ); + _val = static_cast(v); + break; + } + } + return bytes; + } + +//============================================================================= +} // namespace IO +} // namespace OpenMesh +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernelT.cc b/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernelT.cc new file mode 100644 index 0000000..d38d093 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/ArrayKernelT.cc @@ -0,0 +1,315 @@ +/* ========================================================================= * + * * + * 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: 362 $ * + * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * + * * +\*===========================================================================*/ + +#define OPENMESH_ARRAY_KERNEL_C + +//== INCLUDES ================================================================= + +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh +{ + +//== IMPLEMENTATION ========================================================== + +template +void ArrayKernel::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, bool _e, bool _f) +{ + +#ifdef DEBUG + #ifndef OM_GARBAGE_NO_STATUS_WARNING + if ( !this->has_vertex_status() ) + omerr() << "garbage_collection: No vertex status available. You can request it: mesh.request_vertex_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl; + if ( !this->has_edge_status() ) + omerr() << "garbage_collection: No edge status available. You can request it: mesh.request_edge_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl; + if ( !this->has_face_status() ) + omerr() << "garbage_collection: No face status available. You can request it: mesh.request_face_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl; + #endif +#endif + + const bool track_vhandles = ( !vh_to_update.empty() ); + const bool track_hhandles = ( !hh_to_update.empty() ); + const bool track_fhandles = ( !fh_to_update.empty() ); + + int i, i0, i1; + + int nV = int(n_vertices()); + int nE = int(n_edges()); + int nH = int(2*n_edges()); + int nF = (int(n_faces())); + + std::vector vh_map; + std::vector hh_map; + std::vector fh_map; + + std::map vertex_inverse_map; + std::map halfedge_inverse_map; + std::map face_inverse_map; + + // setup handle mapping: + vh_map.reserve(nV); + for (i=0; i 0 && this->has_vertex_status() ) + { + i0=0; i1=nV-1; + + while (1) + { + // find 1st deleted and last un-deleted + while (!status(VertexHandle(i0)).deleted() && i0 < i1) ++i0; + while ( status(VertexHandle(i1)).deleted() && i0 < i1) --i1; + if (i0 >= i1) break; + + // If we keep track of the vertex handles for updates, + // we need to have the opposite direction + if ( track_vhandles ) { + vertex_inverse_map[i1] = i0; + vertex_inverse_map[i0] = -1; + } + + // swap + std::swap(vertices_[i0], vertices_[i1]); + std::swap(vh_map[i0], vh_map[i1]); + vprops_swap(i0, i1); + }; + + vertices_.resize(status(VertexHandle(i0)).deleted() ? i0 : i0+1); + vprops_resize(n_vertices()); + } + + + // remove deleted edges + if (_e && n_edges() > 0 && this->has_edge_status() ) + { + i0=0; i1=nE-1; + + while (1) + { + // find 1st deleted and last un-deleted + while (!status(EdgeHandle(i0)).deleted() && i0 < i1) ++i0; + while ( status(EdgeHandle(i1)).deleted() && i0 < i1) --i1; + if (i0 >= i1) break; + + // If we keep track of the vertex handles for updates, + // we need to have the opposite direction + if ( track_hhandles ) { + halfedge_inverse_map[2*i1] = 2 * i0; + halfedge_inverse_map[2*i0] = -1; + + halfedge_inverse_map[2*i1 + 1] = 2 * i0 + 1; + halfedge_inverse_map[2*i0 + 1] = -1; + } + + // swap + std::swap(edges_[i0], edges_[i1]); + std::swap(hh_map[2*i0], hh_map[2*i1]); + std::swap(hh_map[2*i0+1], hh_map[2*i1+1]); + eprops_swap(i0, i1); + hprops_swap(2*i0, 2*i1); + hprops_swap(2*i0+1, 2*i1+1); + }; + + edges_.resize(status(EdgeHandle(i0)).deleted() ? i0 : i0+1); + eprops_resize(n_edges()); + hprops_resize(n_halfedges()); + } + + + // remove deleted faces + if (_f && n_faces() > 0 && this->has_face_status() ) + { + i0=0; i1=nF-1; + + while (1) + { + // find 1st deleted and last un-deleted + while (!status(FaceHandle(i0)).deleted() && i0 < i1) ++i0; + while ( status(FaceHandle(i1)).deleted() && i0 < i1) --i1; + if (i0 >= i1) break; + + // If we keep track of the face handles for updates, + // we need to have the opposite direction + if ( track_fhandles ) { + face_inverse_map[i1] = i0; + face_inverse_map[i0] = -1; + } + + // swap + std::swap(faces_[i0], faces_[i1]); + std::swap(fh_map[i0], fh_map[i1]); + fprops_swap(i0, i1); + }; + + faces_.resize(status(FaceHandle(i0)).deleted() ? i0 : i0+1); + fprops_resize(n_faces()); + } + + + // update handles of vertices + if (_e) + { + KernelVertexIter v_it(vertices_begin()), v_end(vertices_end()); + VertexHandle vh; + + for (; v_it!=v_end; ++v_it) + { + vh = handle(*v_it); + if (!is_isolated(vh)) + { + set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]); + } + } + } + + HalfedgeHandle hh; + // update handles of halfedges + for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it) + {//in the first pass update the (half)edges vertices + hh = halfedge_handle(handle(*e_it), 0); + set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]); + hh = halfedge_handle(handle(*e_it), 1); + set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]); + } + for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it) + {//in the second pass update the connectivity of the (half)edges + hh = halfedge_handle(handle(*e_it), 0); + set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]); + if (!is_boundary(hh)) + { + set_face_handle(hh, fh_map[face_handle(hh).idx()]); + } + hh = halfedge_handle(handle(*e_it), 1); + set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]); + if (!is_boundary(hh)) + { + set_face_handle(hh, fh_map[face_handle(hh).idx()]); + } + } + + // update handles of faces + if (_e) + { + KernelFaceIter f_it(faces_begin()), f_end(faces_end()); + FaceHandle fh; + + for (; f_it!=f_end; ++f_it) + { + fh = handle(*f_it); + set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]); + } + } + + const int vertexCount = int(vertices_.size()); + const int halfedgeCount = int(edges_.size() * 2); + const int faceCount = int(faces_.size()); + + // Update the vertex handles in the vertex handle vector + typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end()); + for(; v_it != v_it_end; ++v_it) + { + + // Only changed vertices need to be considered + if ( (*v_it)->idx() != vh_map[(*v_it)->idx()].idx() ) { + *(*v_it) = VertexHandle(vertex_inverse_map[(*v_it)->idx()]); + + // Vertices above the vertex count have to be already mapped, or they are invalid now! + } else if ( ((*v_it)->idx() >= vertexCount) && (vertex_inverse_map.find((*v_it)->idx()) == vertex_inverse_map.end()) ) { + (*v_it)->invalidate(); + } + + } + + // Update the halfedge handles in the halfedge handle vector + typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end()); + for(; hh_it != hh_it_end; ++hh_it) + { + // Only changed faces need to be considered + if ( (*hh_it)->idx() != hh_map[(*hh_it)->idx()].idx() ) { + *(*hh_it) = HalfedgeHandle(halfedge_inverse_map[(*hh_it)->idx()]); + + // Vertices above the face count have to be already mapped, or they are invalid now! + } else if ( ((*hh_it)->idx() >= halfedgeCount) && (halfedge_inverse_map.find((*hh_it)->idx()) == halfedge_inverse_map.end()) ) { + (*hh_it)->invalidate(); + } + + } + + // Update the face handles in the face handle vector + typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end()); + for(; fh_it != fh_it_end; ++fh_it) + { + + // Only changed faces need to be considered + if ( (*fh_it)->idx() != fh_map[(*fh_it)->idx()].idx() ) { + *(*fh_it) = FaceHandle(face_inverse_map[(*fh_it)->idx()]); + + // Vertices above the face count have to be already mapped, or they are invalid now! + } else if ( ((*fh_it)->idx() >= faceCount) && (face_inverse_map.find((*fh_it)->idx()) == face_inverse_map.end()) ) { + (*fh_it)->invalidate(); + } + + } +} + +} + diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.cc b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.cc new file mode 100644 index 0000000..64fc991 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/PolyMeshT.cc @@ -0,0 +1,463 @@ +/* ========================================================================= * + * * + * 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 - IMPLEMENTATION +// +//============================================================================= + + +#define OPENMESH_POLYMESH_C + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include +#include +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + +//== IMPLEMENTATION ========================================================== + +template +uint PolyMeshT::find_feature_edges(Scalar _angle_tresh) +{ + assert(Kernel::has_edge_status());//this function needs edge status property + uint n_feature_edges = 0; + for (EdgeIter e_it = Kernel::edges_begin(); e_it != Kernel::edges_end(); ++e_it) + { + if (fabs(calc_dihedral_angle(*e_it)) > _angle_tresh) + {//note: could be optimized by comparing cos(dih_angle) vs. cos(_angle_tresh) + this->status(*e_it).set_feature(true); + n_feature_edges++; + } + else + { + this->status(*e_it).set_feature(false); + } + } + return n_feature_edges; +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Normal +PolyMeshT::calc_face_normal(FaceHandle _fh) const +{ + return calc_face_normal_impl(_fh, typename GenProg::IF< + vector_traits::Point>::size_ == 3, + PointIs3DTag, + PointIsNot3DTag + >::Result()); +} + +template +typename PolyMeshT::Normal +PolyMeshT::calc_face_normal_impl(FaceHandle _fh, PointIs3DTag) const +{ + assert(this->halfedge_handle(_fh).is_valid()); + ConstFaceVertexIter fv_it(this->cfv_iter(_fh)); + + // Safeguard for 1-gons + if (!(++fv_it).is_valid()) return Normal(0, 0, 0); + + // Safeguard for 2-gons + if (!(++fv_it).is_valid()) return Normal(0, 0, 0); + + // use Newell's Method to compute the surface normal + Normal n(0,0,0); + for(fv_it = this->cfv_iter(_fh); fv_it.is_valid(); ++fv_it) + { + // next vertex + ConstFaceVertexIter fv_itn = fv_it; + ++fv_itn; + + if (!fv_itn.is_valid()) + fv_itn = this->cfv_iter(_fh); + + // http://www.opengl.org/wiki/Calculating_a_Surface_Normal + const Point a = this->point(*fv_it) - this->point(*fv_itn); + const Point b = this->point(*fv_it) + this->point(*fv_itn); + + + // Due to traits, the value types of normals and points can be different. + // Therefore we cast them here. + n[0] += static_cast::value_type>(a[1] * b[2]); + n[1] += static_cast::value_type>(a[2] * b[0]); + n[2] += static_cast::value_type>(a[0] * b[1]); + } + + const typename vector_traits::value_type length = norm(n); + + // The expression ((n *= (1.0/norm)),n) is used because the OpenSG + // vector class does not return self after component-wise + // self-multiplication with a scalar!!! + return (length != typename vector_traits::value_type(0)) + ? ((n *= (typename vector_traits::value_type(1)/length)), n) + : Normal(0, 0, 0); +} + +template +typename PolyMeshT::Normal +PolyMeshT::calc_face_normal_impl(FaceHandle, PointIsNot3DTag) const +{ + // Dummy fallback implementation + return Normal(typename Normal::value_type(0)); +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Normal +PolyMeshT:: +calc_face_normal(const Point& _p0, + const Point& _p1, + const Point& _p2) const +{ + return calc_face_normal_impl(_p0, _p1, _p2, typename GenProg::IF< + vector_traits::Point>::size_ == 3, + PointIs3DTag, + PointIsNot3DTag + >::Result()); +} + +template +typename PolyMeshT::Normal +PolyMeshT:: +calc_face_normal_impl(const Point& _p0, + const Point& _p1, + const Point& _p2, + PointIs3DTag) const +{ +#if 1 + // The OpenSG ::operator -= () does not support the type Point + // as rhs. Therefore use vector_cast at this point!!! + // Note! OpenSG distinguishes between Normal and Point!!! + Normal p1p0(vector_cast(_p0)); p1p0 -= vector_cast(_p1); + Normal p1p2(vector_cast(_p2)); p1p2 -= vector_cast(_p1); + + Normal n = cross(p1p2, p1p0); + typename vector_traits::value_type length = norm(n); + + // The expression ((n *= (1.0/norm)),n) is used because the OpenSG + // vector class does not return self after component-wise + // self-multiplication with a scalar!!! + return (length != typename vector_traits::value_type(0)) + ? ((n *= (typename vector_traits::value_type(1)/length)),n) + : Normal(0,0,0); +#else + Point p1p0 = _p0; p1p0 -= _p1; + Point p1p2 = _p2; p1p2 -= _p1; + + Normal n = vector_cast(cross(p1p2, p1p0)); + typename vector_traits::value_type length = norm(n); + + return (length != 0.0) ? n *= (1.0/length) : Normal(0,0,0); +#endif +} + +template +typename PolyMeshT::Normal +PolyMeshT::calc_face_normal_impl(const Point&, const Point&, const Point&, PointIsNot3DTag) const +{ + return Normal(typename Normal::value_type(0)); +} + +//----------------------------------------------------------------------------- + +template +typename PolyMeshT::Point +PolyMeshT:: +calc_face_centroid(FaceHandle _fh) const +{ + Point _pt; + vectorize(_pt, 0); + Scalar valence = 0.0; + for (ConstFaceVertexIter cfv_it = this->cfv_iter(_fh); cfv_it.is_valid(); ++cfv_it, valence += 1.0) + { + _pt += this->point(*cfv_it); + } + _pt /= valence; + return _pt; +} +//----------------------------------------------------------------------------- + + +template +void +PolyMeshT:: +update_normals() +{ + // Face normals are required to compute the vertex and the halfedge normals + if (Kernel::has_face_normals() ) { + update_face_normals(); + + if (Kernel::has_vertex_normals() ) update_vertex_normals(); + if (Kernel::has_halfedge_normals()) update_halfedge_normals(); + } +} + + +//----------------------------------------------------------------------------- + + +template +void +PolyMeshT:: +update_face_normals() +{ + FaceIter f_it(Kernel::faces_sbegin()), f_end(Kernel::faces_end()); + + for (; f_it != f_end; ++f_it) + this->set_normal(*f_it, calc_face_normal(*f_it)); +} + + +//----------------------------------------------------------------------------- + + +template +void +PolyMeshT:: +update_halfedge_normals(const double _feature_angle) +{ + HalfedgeIter h_it(Kernel::halfedges_begin()), h_end(Kernel::halfedges_end()); + + for (; h_it != h_end; ++h_it) + this->set_normal(*h_it, calc_halfedge_normal(*h_it, _feature_angle)); +} + + +//----------------------------------------------------------------------------- + + +template +typename PolyMeshT::Normal +PolyMeshT:: +calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle) const +{ + if(Kernel::is_boundary(_heh)) + return Normal(0,0,0); + else + { + std::vector fhs; fhs.reserve(10); + + HalfedgeHandle heh = _heh; + + // collect CW face-handles + do + { + fhs.push_back(Kernel::face_handle(heh)); + + heh = Kernel::next_halfedge_handle(heh); + heh = Kernel::opposite_halfedge_handle(heh); + } + while(heh != _heh && !Kernel::is_boundary(heh) && !is_estimated_feature_edge(heh, _feature_angle)); + + // collect CCW face-handles + if(heh != _heh && !is_estimated_feature_edge(_heh, _feature_angle)) + { + heh = Kernel::opposite_halfedge_handle(_heh); + + if ( !Kernel::is_boundary(heh) ) { + do + { + + fhs.push_back(Kernel::face_handle(heh)); + + heh = Kernel::prev_halfedge_handle(heh); + heh = Kernel::opposite_halfedge_handle(heh); + } + while(!Kernel::is_boundary(heh) && !is_estimated_feature_edge(heh, _feature_angle)); + } + } + + Normal n(0,0,0); + for(unsigned int i=0; i +bool +PolyMeshT:: +is_estimated_feature_edge(HalfedgeHandle _heh, const double _feature_angle) const +{ + EdgeHandle eh = Kernel::edge_handle(_heh); + + if(Kernel::has_edge_status()) + { + if(Kernel::status(eh).feature()) + return true; + } + + if(Kernel::is_boundary(eh)) + return false; + + // compute angle between faces + FaceHandle fh0 = Kernel::face_handle(_heh); + FaceHandle fh1 = Kernel::face_handle(Kernel::opposite_halfedge_handle(_heh)); + + Normal fn0 = Kernel::normal(fh0); + Normal fn1 = Kernel::normal(fh1); + + // dihedral angle above angle threshold + return ( dot(fn0,fn1) < cos(_feature_angle) ); +} + + +//----------------------------------------------------------------------------- + + +template +typename PolyMeshT::Normal +PolyMeshT:: +calc_vertex_normal(VertexHandle _vh) const +{ + Normal n; + calc_vertex_normal_fast(_vh,n); + + Scalar length = norm(n); + if (length != 0.0) n *= (Scalar(1.0)/length); + + return n; +} + +//----------------------------------------------------------------------------- +template +void PolyMeshT:: +calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const +{ + vectorize(_n, 0.0); + for (ConstVertexFaceIter vf_it = this->cvf_iter(_vh); vf_it.is_valid(); ++vf_it) + _n += this->normal(*vf_it); +} + +//----------------------------------------------------------------------------- +template +void PolyMeshT:: +calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const +{ + vectorize(_n, 0.0); + ConstVertexIHalfedgeIter cvih_it = this->cvih_iter(_vh); + if (! cvih_it.is_valid() ) + {//don't crash on isolated vertices + return; + } + Normal in_he_vec; + calc_edge_vector(*cvih_it, in_he_vec); + for ( ; cvih_it.is_valid(); ++cvih_it) + {//calculates the sector normal defined by cvih_it and adds it to _n + if (this->is_boundary(*cvih_it)) + { + continue; + } + HalfedgeHandle out_heh(this->next_halfedge_handle(*cvih_it)); + Normal out_he_vec; + calc_edge_vector(out_heh, out_he_vec); + _n += cross(in_he_vec, out_he_vec);//sector area is taken into account + in_he_vec = out_he_vec; + in_he_vec *= -1;//change the orientation + } +} + +//----------------------------------------------------------------------------- +template +void PolyMeshT:: +calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const +{ + static const LoopSchemeMaskDouble& loop_scheme_mask__ = + LoopSchemeMaskDoubleSingleton::Instance(); + + Normal t_v(0.0,0.0,0.0), t_w(0.0,0.0,0.0); + unsigned int vh_val = this->valence(_vh); + unsigned int i = 0; + for (ConstVertexOHalfedgeIter cvoh_it = this->cvoh_iter(_vh); cvoh_it.is_valid(); ++cvoh_it, ++i) + { + VertexHandle r1_v( this->to_vertex_handle(*cvoh_it) ); + t_v += (typename vector_traits::value_type)(loop_scheme_mask__.tang0_weight(vh_val, i))*this->point(r1_v); + t_w += (typename vector_traits::value_type)(loop_scheme_mask__.tang1_weight(vh_val, i))*this->point(r1_v); + } + _n = cross(t_w, t_v);//hack: should be cross(t_v, t_w), but then the normals are reversed? +} + +//----------------------------------------------------------------------------- + + +template +void +PolyMeshT:: +update_vertex_normals() +{ + VertexIter v_it(Kernel::vertices_begin()), v_end(Kernel::vertices_end()); + + for (; v_it!=v_end; ++v_it) + this->set_normal(*v_it, calc_vertex_normal(*v_it)); +} + +//============================================================================= +} // namespace OpenMesh +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.cc b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.cc new file mode 100644 index 0000000..c225cd5 --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Mesh/TriMeshT.cc @@ -0,0 +1,93 @@ +/* ========================================================================= * + * * + * 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 - IMPLEMENTATION +// +//============================================================================= + + +#define OPENMESH_TRIMESH_C + + +//== INCLUDES ================================================================= + + +#include +#include +#include + + +//== NAMESPACES ============================================================== + + +namespace OpenMesh { + + +//== IMPLEMENTATION ========================================================== + +template +typename TriMeshT::Normal +TriMeshT:: +calc_face_normal(FaceHandle _fh) const +{ + assert(this->halfedge_handle(_fh).is_valid()); + ConstFaceVertexIter fv_it(this->cfv_iter(_fh)); + + const Point& p0(this->point(*fv_it)); ++fv_it; + const Point& p1(this->point(*fv_it)); ++fv_it; + const Point& p2(this->point(*fv_it)); + + return PolyMesh::calc_face_normal(p0, p1, p2); +} + +//============================================================================= +} // namespace OpenMesh +//============================================================================= diff --git a/libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.cc b/libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.cc new file mode 100644 index 0000000..abc189a --- /dev/null +++ b/libs/OpenMesh/include/OpenMesh/Core/Utils/SingletonT.cc @@ -0,0 +1,85 @@ +/* ========================================================================= * + * * + * 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 +// +//============================================================================= + + +#define OPENMESH_SINGLETON_C + + +//== INCLUDES ================================================================= + + +// header +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== SINGLETON'S DATA ========================================================= + + +template +T* SingletonT::pInstance__ = 0; + +template +bool SingletonT::destroyed__ = false; + + +//============================================================================= +} // namespace OpenMesh +//=============================================================================