From cf2434fcaf7d18544aff9713b908c8982d0f502a Mon Sep 17 00:00:00 2001 From: Mike Kremer Date: Tue, 24 Jun 2014 13:18:45 +0000 Subject: [PATCH] Made OpenVolumeMesh Mavericks ready. Suspended template functions in status attrib to separate template implementation file. Avoid use of lambda functions on OS 10.9. git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@275 66977474-1d4b-4f09-8fe9-267525286df2 --- CMakeLists.txt | 2 + src/OpenVolumeMesh/Attribs/StatusAttrib.cc | 310 --------------- src/OpenVolumeMesh/Attribs/StatusAttrib.hh | 4 + src/OpenVolumeMesh/Attribs/StatusAttribT.cc | 363 ++++++++++++++++++ .../Core/OpenVolumeMeshHandle.hh | 12 + src/OpenVolumeMesh/Core/TopologyKernel.cc | 48 +++ src/OpenVolumeMesh/Core/TopologyKernel.hh | 14 + .../System/FunctionalInclude.hh | 10 +- src/OpenVolumeMesh/System/MemoryInclude.hh | 14 +- 9 files changed, 461 insertions(+), 316 deletions(-) create mode 100644 src/OpenVolumeMesh/Attribs/StatusAttribT.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 38dd3c5..f58543f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required (VERSION 2.6) +set(CMAKE_MACOSX_RPATH 1) + if("${PROJECT_NAME}" STREQUAL "") message("Setting project name to OpenVolumeMesh") project (OpenVolumeMesh) diff --git a/src/OpenVolumeMesh/Attribs/StatusAttrib.cc b/src/OpenVolumeMesh/Attribs/StatusAttrib.cc index fc4e198..95c7709 100644 --- a/src/OpenVolumeMesh/Attribs/StatusAttrib.cc +++ b/src/OpenVolumeMesh/Attribs/StatusAttrib.cc @@ -164,315 +164,5 @@ void StatusAttrib::garbage_collection(bool _preserveManifoldness) { garbage_collection(vh_empty, hh_empty, hfh_empty, ch_empty, _preserveManifoldness); } -//======================================================================================== - -template -void StatusAttrib::garbage_collection(std_API_Container_VHandlePointer &vh_to_update, - std_API_Container_HHandlePointer &hh_to_update, - std_API_Container_HFHandlePointer &hfh_to_update, - std_API_Container_CHandlePointer &ch_to_update, - bool _preserveManifoldness) { - - /* - * This is not a real garbage collection in its conventional - * sense. What happens in this routine are the following steps: - * - * 1. If an entity of dimension n is marked to be deleted, - * also mark all incident entities of dimension n + 1 - * for deletion. Do this in a bottom-up fashion. - * 2. Then delete all entities in top-down manner, so that - * no invalid incident higher-dimensional entity is generated. - * 3. If desired, search for all isolated entities and mark - * them deleted in a top-down manner. - * 4. Delete all entities marked deleted in step 4 in order - * to prevent manifoldness. - */ - - // setup tracking so we can update the given handles - bool track_vh = !vh_to_update.empty(); - bool track_hh = !hh_to_update.empty(); - bool track_hfh = !hfh_to_update.empty(); - bool track_ch = !ch_to_update.empty(); - int offset_vh = 0; - int offset_hh = 0; - int offset_hfh = 0; - int offset_ch = 0; - - std::map vh_map; - std::map hh_map; - std::map hfh_map; - std::map ch_map; - - // initialise the maps - if (track_vh) { - typename std_API_Container_VHandlePointer::iterator it = vh_to_update.begin(); - typename std_API_Container_VHandlePointer::iterator end = vh_to_update.end(); - - for (it; it != end; ++it) { - vh_map[(*it)->idx()] = (*it)->idx(); - } - } - if (track_hh) { - typename std_API_Container_HHandlePointer::iterator it = hh_to_update.begin(); - typename std_API_Container_HHandlePointer::iterator end = hh_to_update.end(); - - for (it; it != end; ++it) { - hh_map[(*it)->idx()] = (*it)->idx(); - } - } - if (track_hfh) { - typename std_API_Container_HFHandlePointer::iterator it = hfh_to_update.begin(); - typename std_API_Container_HFHandlePointer::iterator end = hfh_to_update.end(); - - for (it; it != end; ++it) { - hfh_map[(*it)->idx()] = (*it)->idx(); - } - } - if (track_ch) { - typename std_API_Container_CHandlePointer::iterator it = ch_to_update.begin(); - typename std_API_Container_CHandlePointer::iterator end = ch_to_update.end(); - - for (it; it != end; ++it) { - ch_map[(*it)->idx()] = (*it)->idx(); - } - } - - // Mark all higher-dimensional entities incident to - // entities marked as deleted from bottom to top - mark_higher_dim_entities(); - - std::vector vertexIndexMap(kernel_.n_vertices(), -1); - - // Turn off bottom-up incidences - bool v_bu = kernel_.has_vertex_bottom_up_incidences(); - bool e_bu = kernel_.has_edge_bottom_up_incidences(); - bool f_bu = kernel_.has_face_bottom_up_incidences(); - - kernel_.enable_bottom_up_incidences(false); - - std::vector tags(kernel_.n_cells(), false); - std::vector::iterator tag_it = tags.begin(); - - for(CellIter c_it = kernel_.cells_begin(); c_it != kernel_.cells_end(); ++c_it, ++tag_it) { - *tag_it = c_status_[c_it->idx()].deleted(); - - if (track_ch) { - if (c_status_[c_it->idx()].deleted()) { - ++offset_ch; - if (ch_map.find(c_it->idx()) != ch_map.end()) - ch_map[c_it->idx()] = -1; - } else { - if (ch_map.find(c_it->idx()) != ch_map.end()) - ch_map[c_it->idx()] = c_it->idx() - offset_ch; - } - } - } - kernel_.delete_multiple_cells(tags); - - tags.resize(kernel_.n_faces(), false); - tag_it = tags.begin(); - - for(FaceIter f_it = kernel_.faces_begin(); f_it != kernel_.faces_end(); ++f_it, ++tag_it) { - *tag_it = f_status_[f_it->idx()].deleted(); - - if (track_hfh) { - int halfface_idx = f_it->idx() * 2; - if (f_status_[f_it->idx()].deleted()) { - offset_hfh += 2; - if (hfh_map.find(halfface_idx) != hfh_map.end()) { - hfh_map[halfface_idx] = -1; - } - if (hfh_map.find(halfface_idx + 1) != hfh_map.end()) { - hfh_map[halfface_idx + 1] = -1; - } - } else { - if (hfh_map.find(halfface_idx) != hfh_map.end()) { - hfh_map[halfface_idx] = halfface_idx - offset_hfh; - } - if (hfh_map.find(halfface_idx + 1) != hfh_map.end()) { - hfh_map[halfface_idx + 1] = halfface_idx + 1 - offset_hfh; - } - } - } - } - kernel_.delete_multiple_faces(tags); - - tags.resize(kernel_.n_edges(), false); - tag_it = tags.begin(); - - for(EdgeIter e_it = kernel_.edges_begin(); e_it != kernel_.edges_end(); ++e_it, ++tag_it) { - *tag_it = e_status_[e_it->idx()].deleted(); - - if (track_hh) { - int halfedge_idx = e_it->idx() * 2; - if (e_status_[e_it->idx()].deleted()) { - offset_hh += 2; - if (hh_map.find(halfedge_idx) != hh_map.end()) { - hh_map[halfedge_idx] = -1; - } - if (hh_map.find(halfedge_idx + 1) != hh_map.end()) { - hh_map[halfedge_idx + 1] = -1; - } - } else { - if (hh_map.find(halfedge_idx) != hh_map.end()) { - hh_map[halfedge_idx] = halfedge_idx - offset_hh; - } - if (hh_map.find(halfedge_idx + 1) != hh_map.end()) { - hh_map[halfedge_idx + 1] = halfedge_idx + 1 - offset_hh; - } - } - } - } - kernel_.delete_multiple_edges(tags); - - tags.resize(kernel_.n_vertices(), false); - tag_it = tags.begin(); - - for(VertexIter v_it = kernel_.vertices_begin(); v_it != kernel_.vertices_end(); ++v_it, ++tag_it) { - *tag_it = v_status_[v_it->idx()].deleted(); - - if (track_vh) { - if (v_status_[v_it->idx()].deleted()) { - if (vh_map.find(v_it->idx()) != vh_map.end()) { - ++offset_vh; - vh_map[v_it->idx()] = -1; - } - } else { - if (vh_map.find(v_it->idx()) != vh_map.end()) { - vh_map[v_it->idx()] = v_it->idx() - offset_vh; - } - } - } - } - kernel_.delete_multiple_vertices(tags); - - // update given handles - if (track_vh) { - typename std_API_Container_VHandlePointer::iterator it = vh_to_update.begin(); - typename std_API_Container_VHandlePointer::iterator end = vh_to_update.end(); - - for (it; it != end; ++it) { - *(*it) = VertexHandle( vh_map[(*it)->idx()] ); - } - } - if (track_hh) { - typename std_API_Container_HHandlePointer::iterator it = hh_to_update.begin(); - typename std_API_Container_HHandlePointer::iterator end = hh_to_update.end(); - - for (it; it != end; ++it) { - *(*it) = HalfEdgeHandle( hh_map[(*it)->idx()] ); - } - } - if (track_hfh) { - typename std_API_Container_HFHandlePointer::iterator it = hfh_to_update.begin(); - typename std_API_Container_HFHandlePointer::iterator end = hfh_to_update.end(); - - for (it; it != end; ++it) { - *(*it) = HalfFaceHandle( hfh_map[(*it)->idx()] ); - } - } - if (track_ch) { - typename std_API_Container_CHandlePointer::iterator it = ch_to_update.begin(); - typename std_API_Container_CHandlePointer::iterator end = ch_to_update.end(); - - for (it; it != end; ++it) { - *(*it) = CellHandle( ch_map[(*it)->idx()] ); - } - } - - // Todo: Resize props - - if(v_bu) kernel_.enable_vertex_bottom_up_incidences(true); - if(e_bu) kernel_.enable_edge_bottom_up_incidences(true); - if(f_bu) kernel_.enable_face_bottom_up_incidences(true); - - // Step 6 - if(_preserveManifoldness) { - if(kernel_.has_full_bottom_up_incidences()) { - - // Go over all faces and find those - // that are not incident to any cell - for(FaceIter f_it = kernel_.faces_begin(); f_it != kernel_.faces_end(); ++f_it) { - - // Get half-faces - HalfFaceHandle hf0 = kernel_.halfface_handle(*f_it, 0); - HalfFaceHandle hf1 = kernel_.halfface_handle(*f_it, 1); - - // If neither of the half-faces is incident to a cell, delete face - if(kernel_.incident_cell(hf0) == TopologyKernel::InvalidCellHandle && - kernel_.incident_cell(hf1) == TopologyKernel::InvalidCellHandle) { - - f_status_[f_it->idx()].set_deleted(true); - } - } - - // Go over all edges and find those - // whose half-edges are not incident to any half-face - for(EdgeIter e_it = kernel_.edges_begin(); e_it != kernel_.edges_end(); ++e_it) { - - // Get half-edges - HalfEdgeHandle he = kernel_.halfedge_handle(*e_it, 0); - - // If the half-edge isn't incident to a half-face, delete edge - HalfEdgeHalfFaceIter hehf_it = kernel_.hehf_iter(he); - - if(!hehf_it.valid()) { - - e_status_[e_it->idx()].set_deleted(true); - - } else { - bool validFace = false; - for(; hehf_it.valid(); ++hehf_it) { - if(!f_status_[kernel_.face_handle(*hehf_it).idx()].deleted()) { - validFace = true; - break; - } - } - if(!validFace) { - e_status_[e_it->idx()].set_deleted(true); - } - } - } - - // Go over all vertices and find those - // that are not incident to any edge - for(VertexIter v_it = kernel_.vertices_begin(); v_it != kernel_.vertices_end(); ++v_it) { - - // If neither of the half-edges is incident to a half-face, delete edge - VertexOHalfEdgeIter voh_it = kernel_.voh_iter(*v_it); - - if(!voh_it.valid()) { - - v_status_[v_it->idx()].set_deleted(true); - } else { - - bool validEdge = false; - for(; voh_it.valid(); ++voh_it) { - if(!e_status_[kernel_.edge_handle(voh_it->idx())].deleted()) { - validEdge = true; - break; - } - } - if(!validEdge) { - v_status_[v_it->idx()].set_deleted(true); - } - } - } - - // Recursive call - garbage_collection(vh_to_update, hh_to_update, hfh_to_update, ch_to_update, false); - - } else { -#ifndef NDEBUG - std::cerr << "Preservation of three-manifoldness in garbage_collection() " - << "requires bottom-up incidences!" << std::endl; -#endif - return; - } - } -} } // Namespace OpenVolumeMesh diff --git a/src/OpenVolumeMesh/Attribs/StatusAttrib.hh b/src/OpenVolumeMesh/Attribs/StatusAttrib.hh index 459af81..b46c195 100644 --- a/src/OpenVolumeMesh/Attribs/StatusAttrib.hh +++ b/src/OpenVolumeMesh/Attribs/StatusAttrib.hh @@ -279,4 +279,8 @@ private: } // Namespace OpenVolumeMesh +#if defined(INCLUDE_TEMPLATES) && !defined(STATUSATTRIBT_CC) +#include "StatusAttribT.cc" +#endif + #endif /* STATUSATTRIB_HH_ */ diff --git a/src/OpenVolumeMesh/Attribs/StatusAttribT.cc b/src/OpenVolumeMesh/Attribs/StatusAttribT.cc new file mode 100644 index 0000000..a643afe --- /dev/null +++ b/src/OpenVolumeMesh/Attribs/StatusAttribT.cc @@ -0,0 +1,363 @@ +/*===========================================================================*\ + * * + * OpenVolumeMesh * + * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen * + * www.openvolumemesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenVolumeMesh. * + * * + * OpenVolumeMesh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of * + * the License, or (at your option) any later version with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenVolumeMesh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenVolumeMesh. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision: 36 $ * + * $Date: 2012-01-10 18:00:06 +0100 (Di, 10 Jan 2012) $ * + * $LastChangedBy: kremer $ * + * * +\*===========================================================================*/ + +#define STATUSATTRIBT_CC + +#include "StatusAttrib.hh" + +#include "../Core/TopologyKernel.hh" +#include "../Core/PropertyDefines.hh" + +#include + +namespace OpenVolumeMesh { +//======================================================================================== + +template +void StatusAttrib::garbage_collection(std_API_Container_VHandlePointer &vh_to_update, + std_API_Container_HHandlePointer &hh_to_update, + std_API_Container_HFHandlePointer &hfh_to_update, + std_API_Container_CHandlePointer &ch_to_update, + bool _preserveManifoldness) { + + /* + * This is not a real garbage collection in its conventional + * sense. What happens in this routine are the following steps: + * + * 1. If an entity of dimension n is marked to be deleted, + * also mark all incident entities of dimension n + 1 + * for deletion. Do this in a bottom-up fashion. + * 2. Then delete all entities in top-down manner, so that + * no invalid incident higher-dimensional entity is generated. + * 3. If desired, search for all isolated entities and mark + * them deleted in a top-down manner. + * 4. Delete all entities marked deleted in step 4 in order + * to prevent manifoldness. + */ + + // setup tracking so we can update the given handles + bool track_vh = !vh_to_update.empty(); + bool track_hh = !hh_to_update.empty(); + bool track_hfh = !hfh_to_update.empty(); + bool track_ch = !ch_to_update.empty(); + int offset_vh = 0; + int offset_hh = 0; + int offset_hfh = 0; + int offset_ch = 0; + + std::map vh_map; + std::map hh_map; + std::map hfh_map; + std::map ch_map; + + // initialise the maps + if (track_vh) { + typename std_API_Container_VHandlePointer::iterator it = vh_to_update.begin(); + typename std_API_Container_VHandlePointer::iterator end = vh_to_update.end(); + + for (it; it != end; ++it) { + vh_map[(*it)->idx()] = (*it)->idx(); + } + } + if (track_hh) { + typename std_API_Container_HHandlePointer::iterator it = hh_to_update.begin(); + typename std_API_Container_HHandlePointer::iterator end = hh_to_update.end(); + + for (it; it != end; ++it) { + hh_map[(*it)->idx()] = (*it)->idx(); + } + } + if (track_hfh) { + typename std_API_Container_HFHandlePointer::iterator it = hfh_to_update.begin(); + typename std_API_Container_HFHandlePointer::iterator end = hfh_to_update.end(); + + for (it; it != end; ++it) { + hfh_map[(*it)->idx()] = (*it)->idx(); + } + } + if (track_ch) { + typename std_API_Container_CHandlePointer::iterator it = ch_to_update.begin(); + typename std_API_Container_CHandlePointer::iterator end = ch_to_update.end(); + + for (it; it != end; ++it) { + ch_map[(*it)->idx()] = (*it)->idx(); + } + } + + // Mark all higher-dimensional entities incident to + // entities marked as deleted from bottom to top + mark_higher_dim_entities(); + + std::vector vertexIndexMap(kernel_.n_vertices(), -1); + + // Turn off bottom-up incidences + bool v_bu = kernel_.has_vertex_bottom_up_incidences(); + bool e_bu = kernel_.has_edge_bottom_up_incidences(); + bool f_bu = kernel_.has_face_bottom_up_incidences(); + + kernel_.enable_bottom_up_incidences(false); + + std::vector tags(kernel_.n_cells(), false); + std::vector::iterator tag_it = tags.begin(); + + for(CellIter c_it = kernel_.cells_begin(); c_it != kernel_.cells_end(); ++c_it, ++tag_it) { + *tag_it = c_status_[c_it->idx()].deleted(); + + if (track_ch) { + if (c_status_[c_it->idx()].deleted()) { + ++offset_ch; + if (ch_map.find(c_it->idx()) != ch_map.end()) + ch_map[c_it->idx()] = -1; + } else { + if (ch_map.find(c_it->idx()) != ch_map.end()) + ch_map[c_it->idx()] = c_it->idx() - offset_ch; + } + } + } + kernel_.delete_multiple_cells(tags); + + tags.resize(kernel_.n_faces(), false); + tag_it = tags.begin(); + + for(FaceIter f_it = kernel_.faces_begin(); f_it != kernel_.faces_end(); ++f_it, ++tag_it) { + *tag_it = f_status_[f_it->idx()].deleted(); + + if (track_hfh) { + int halfface_idx = f_it->idx() * 2; + if (f_status_[f_it->idx()].deleted()) { + offset_hfh += 2; + if (hfh_map.find(halfface_idx) != hfh_map.end()) { + hfh_map[halfface_idx] = -1; + } + if (hfh_map.find(halfface_idx + 1) != hfh_map.end()) { + hfh_map[halfface_idx + 1] = -1; + } + } else { + if (hfh_map.find(halfface_idx) != hfh_map.end()) { + hfh_map[halfface_idx] = halfface_idx - offset_hfh; + } + if (hfh_map.find(halfface_idx + 1) != hfh_map.end()) { + hfh_map[halfface_idx + 1] = halfface_idx + 1 - offset_hfh; + } + } + } + } + kernel_.delete_multiple_faces(tags); + + tags.resize(kernel_.n_edges(), false); + tag_it = tags.begin(); + + for(EdgeIter e_it = kernel_.edges_begin(); e_it != kernel_.edges_end(); ++e_it, ++tag_it) { + *tag_it = e_status_[e_it->idx()].deleted(); + + if (track_hh) { + int halfedge_idx = e_it->idx() * 2; + if (e_status_[e_it->idx()].deleted()) { + offset_hh += 2; + if (hh_map.find(halfedge_idx) != hh_map.end()) { + hh_map[halfedge_idx] = -1; + } + if (hh_map.find(halfedge_idx + 1) != hh_map.end()) { + hh_map[halfedge_idx + 1] = -1; + } + } else { + if (hh_map.find(halfedge_idx) != hh_map.end()) { + hh_map[halfedge_idx] = halfedge_idx - offset_hh; + } + if (hh_map.find(halfedge_idx + 1) != hh_map.end()) { + hh_map[halfedge_idx + 1] = halfedge_idx + 1 - offset_hh; + } + } + } + } + kernel_.delete_multiple_edges(tags); + + tags.resize(kernel_.n_vertices(), false); + tag_it = tags.begin(); + + for(VertexIter v_it = kernel_.vertices_begin(); v_it != kernel_.vertices_end(); ++v_it, ++tag_it) { + *tag_it = v_status_[v_it->idx()].deleted(); + + if (track_vh) { + if (v_status_[v_it->idx()].deleted()) { + if (vh_map.find(v_it->idx()) != vh_map.end()) { + ++offset_vh; + vh_map[v_it->idx()] = -1; + } + } else { + if (vh_map.find(v_it->idx()) != vh_map.end()) { + vh_map[v_it->idx()] = v_it->idx() - offset_vh; + } + } + } + } + kernel_.delete_multiple_vertices(tags); + + // update given handles + if (track_vh) { + typename std_API_Container_VHandlePointer::iterator it = vh_to_update.begin(); + typename std_API_Container_VHandlePointer::iterator end = vh_to_update.end(); + + for (; it != end; ++it) { + *(*it) = VertexHandle( vh_map[(*it)->idx()] ); + } + } + if (track_hh) { + typename std_API_Container_HHandlePointer::iterator it = hh_to_update.begin(); + typename std_API_Container_HHandlePointer::iterator end = hh_to_update.end(); + + for (; it != end; ++it) { + *(*it) = HalfEdgeHandle( hh_map[(*it)->idx()] ); + } + } + if (track_hfh) { + typename std_API_Container_HFHandlePointer::iterator it = hfh_to_update.begin(); + typename std_API_Container_HFHandlePointer::iterator end = hfh_to_update.end(); + + for (; it != end; ++it) { + *(*it) = HalfFaceHandle( hfh_map[(*it)->idx()] ); + } + } + if (track_ch) { + typename std_API_Container_CHandlePointer::iterator it = ch_to_update.begin(); + typename std_API_Container_CHandlePointer::iterator end = ch_to_update.end(); + + for (; it != end; ++it) { + *(*it) = CellHandle( ch_map[(*it)->idx()] ); + } + } + + // Todo: Resize props + + if(v_bu) kernel_.enable_vertex_bottom_up_incidences(true); + if(e_bu) kernel_.enable_edge_bottom_up_incidences(true); + if(f_bu) kernel_.enable_face_bottom_up_incidences(true); + + // Step 6 + if(_preserveManifoldness) { + if(kernel_.has_full_bottom_up_incidences()) { + + // Go over all faces and find those + // that are not incident to any cell + for(FaceIter f_it = kernel_.faces_begin(); f_it != kernel_.faces_end(); ++f_it) { + + // Get half-faces + HalfFaceHandle hf0 = kernel_.halfface_handle(*f_it, 0); + HalfFaceHandle hf1 = kernel_.halfface_handle(*f_it, 1); + + // If neither of the half-faces is incident to a cell, delete face + if(kernel_.incident_cell(hf0) == TopologyKernel::InvalidCellHandle && + kernel_.incident_cell(hf1) == TopologyKernel::InvalidCellHandle) { + + f_status_[f_it->idx()].set_deleted(true); + } + } + + // Go over all edges and find those + // whose half-edges are not incident to any half-face + for(EdgeIter e_it = kernel_.edges_begin(); e_it != kernel_.edges_end(); ++e_it) { + + // Get half-edges + HalfEdgeHandle he = kernel_.halfedge_handle(*e_it, 0); + + // If the half-edge isn't incident to a half-face, delete edge + HalfEdgeHalfFaceIter hehf_it = kernel_.hehf_iter(he); + + if(!hehf_it.valid()) { + + e_status_[e_it->idx()].set_deleted(true); + + } else { + bool validFace = false; + for(; hehf_it.valid(); ++hehf_it) { + if(!f_status_[kernel_.face_handle(*hehf_it).idx()].deleted()) { + validFace = true; + break; + } + } + if(!validFace) { + e_status_[e_it->idx()].set_deleted(true); + } + } + } + + // Go over all vertices and find those + // that are not incident to any edge + for(VertexIter v_it = kernel_.vertices_begin(); v_it != kernel_.vertices_end(); ++v_it) { + + // If neither of the half-edges is incident to a half-face, delete edge + VertexOHalfEdgeIter voh_it = kernel_.voh_iter(*v_it); + + if(!voh_it.valid()) { + + v_status_[v_it->idx()].set_deleted(true); + } else { + + bool validEdge = false; + for(; voh_it.valid(); ++voh_it) { + if(!e_status_[kernel_.edge_handle(voh_it->idx())].deleted()) { + validEdge = true; + break; + } + } + if(!validEdge) { + v_status_[v_it->idx()].set_deleted(true); + } + } + } + + // Recursive call + garbage_collection(vh_to_update, hh_to_update, hfh_to_update, ch_to_update, false); + + } else { +#ifndef NDEBUG + std::cerr << "Preservation of three-manifoldness in garbage_collection() " + << "requires bottom-up incidences!" << std::endl; +#endif + return; + } + } +} +} // Namespace OpenVolumeMesh diff --git a/src/OpenVolumeMesh/Core/OpenVolumeMeshHandle.hh b/src/OpenVolumeMesh/Core/OpenVolumeMeshHandle.hh index 261099b..92d9a6c 100644 --- a/src/OpenVolumeMesh/Core/OpenVolumeMeshHandle.hh +++ b/src/OpenVolumeMesh/Core/OpenVolumeMeshHandle.hh @@ -118,7 +118,13 @@ class HEHandleCorrection { public: HEHandleCorrection(HalfEdgeHandle _thld) : thld_(_thld) {} void correctVecValue(std::vector& _vec) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = _vec.begin(), end = _vec.end(); it != end; ++it) { + correctValue(*it); + } +#else std::for_each(_vec.begin(), _vec.end(), fun::bind(&HEHandleCorrection::correctValue, this, fun::placeholders::_1)); +#endif } void correctValue(HalfEdgeHandle& _h) { if(_h > thld_) _h.idx(_h.idx() - 2); @@ -130,7 +136,13 @@ class HFHandleCorrection { public: HFHandleCorrection(HalfFaceHandle _thld) : thld_(_thld) {} void correctVecValue(std::vector& _vec) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = _vec.begin(), end = _vec.end(); it != end; ++it) { + correctValue(*it); + } +#else std::for_each(_vec.begin(), _vec.end(), fun::bind(&HFHandleCorrection::correctValue, this, fun::placeholders::_1)); +#endif } void correctValue(HalfFaceHandle& _h) { if(_h > thld_) _h.idx(_h.idx() - 2); diff --git a/src/OpenVolumeMesh/Core/TopologyKernel.cc b/src/OpenVolumeMesh/Core/TopologyKernel.cc index 7e0d1fb..d2db00f 100644 --- a/src/OpenVolumeMesh/Core/TopologyKernel.cc +++ b/src/OpenVolumeMesh/Core/TopologyKernel.cc @@ -979,8 +979,15 @@ EdgeIter TopologyKernel::delete_edge_core(const EdgeHandle& _h) { hes.erase(std::remove(hes.begin(), hes.end(), halfedge_handle(_h, 0)), hes.end()); hes.erase(std::remove(hes.begin(), hes.end(), halfedge_handle(_h, 1)), hes.end()); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = hes.begin(), end = hes.end(); + it != end; ++it) { + cor.correctValue(*it); + } +#else std::for_each(hes.begin(), hes.end(), fun::bind(&HEHandleCorrection::correctValue, &cor, fun::placeholders::_1)); +#endif face(*f_it).set_halfedges(hes); } } else { @@ -998,8 +1005,15 @@ EdgeIter TopologyKernel::delete_edge_core(const EdgeHandle& _h) { // Decrease all half-edge handles greater than _h in face HEHandleCorrection cor(halfedge_handle(_h, 1)); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = hes.begin(), end = hes.end(); + it != end; ++it) { + cor.correctValue(*it); + } +#else std::for_each(hes.begin(), hes.end(), fun::bind(&HEHandleCorrection::correctValue, &cor, fun::placeholders::_1)); +#endif face(*f_it).set_halfedges(hes); } } @@ -1015,9 +1029,16 @@ EdgeIter TopologyKernel::delete_edge_core(const EdgeHandle& _h) { // 4) if(v_bottom_up_) { HEHandleCorrection cor(halfedge_handle(_h, 1)); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector >::iterator it = outgoing_hes_per_vertex_.begin(), + end = outgoing_hes_per_vertex_.end(); it != end; ++it) { + cor.correctVecValue(*it); + } +#else std::for_each(outgoing_hes_per_vertex_.begin(), outgoing_hes_per_vertex_.end(), fun::bind(&HEHandleCorrection::correctVecValue, &cor, fun::placeholders::_1)); +#endif } // 5) @@ -1098,8 +1119,15 @@ FaceIter TopologyKernel::delete_face_core(const FaceHandle& _h) { hfs.erase(std::remove(hfs.begin(), hfs.end(), halfface_handle(_h, 1)), hfs.end()); HFHandleCorrection cor(halfface_handle(_h, 1)); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = hfs.begin(), + end = hfs.end(); it != end; ++it) { + cor.correctValue(*it); + } +#else std::for_each(hfs.begin(), hfs.end(), fun::bind(&HFHandleCorrection::correctValue, &cor, fun::placeholders::_1)); +#endif cell(*c_it).set_halffaces(hfs); } @@ -1115,8 +1143,15 @@ FaceIter TopologyKernel::delete_face_core(const FaceHandle& _h) { hfs.erase(std::remove(hfs.begin(), hfs.end(), halfface_handle(_h, 1)), hfs.end()); HFHandleCorrection cor(halfface_handle(_h, 1)); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = hfs.begin(), + end = hfs.end(); it != end; ++it) { + cor.correctValue(*it); + } +#else std::for_each(hfs.begin(), hfs.end(), fun::bind(&HFHandleCorrection::correctValue, &cor, fun::placeholders::_1)); +#endif cell(*c_it).set_halffaces(hfs); } } @@ -1132,9 +1167,15 @@ FaceIter TopologyKernel::delete_face_core(const FaceHandle& _h) { // 4) if(e_bottom_up_) { HFHandleCorrection cor(halfface_handle(_h, 1)); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector >::iterator it = incident_hfs_per_he_.begin(), end = incident_hfs_per_he_.end(); it != end; ++it) { + cor.correctVecValue(*it); + } +#else std::for_each(incident_hfs_per_he_.begin(), incident_hfs_per_he_.end(), fun::bind(&HFHandleCorrection::correctVecValue, &cor, fun::placeholders::_1)); +#endif } // 5) @@ -1182,9 +1223,16 @@ CellIter TopologyKernel::delete_cell_core(const CellHandle& _h) { // 2) if(f_bottom_up_) { CHandleCorrection cor(_h); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(std::vector::iterator it = incident_cell_per_hf_.begin(), + end = incident_cell_per_hf_.end(); it != end; ++it) { + cor.correctValue(*it); + } +#else std::for_each(incident_cell_per_hf_.begin(), incident_cell_per_hf_.end(), fun::bind(&CHandleCorrection::correctValue, &cor, fun::placeholders::_1)); +#endif } // 3) diff --git a/src/OpenVolumeMesh/Core/TopologyKernel.hh b/src/OpenVolumeMesh/Core/TopologyKernel.hh index c1c7218..ee75ab5 100644 --- a/src/OpenVolumeMesh/Core/TopologyKernel.hh +++ b/src/OpenVolumeMesh/Core/TopologyKernel.hh @@ -631,8 +631,15 @@ public: compute_edge_bottom_up_incidences(); if(f_bottom_up_) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(EdgeIter e_it = edges_begin(), e_end = edges_end(); + e_it != e_end; ++e_it) { + reorder_incident_halffaces(*e_it); + } +#else std::for_each(edges_begin(), edges_end(), fun::bind(&TopologyKernel::reorder_incident_halffaces, this, fun::placeholders::_1)); +#endif } } @@ -662,8 +669,15 @@ public: if(updateOrder) { if(e_bottom_up_) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + for(EdgeIter e_it = edges_begin(), e_end = edges_end(); + e_it != e_end; ++e_it) { + reorder_incident_halffaces(*e_it); + } +#else std::for_each(edges_begin(), edges_end(), fun::bind(&TopologyKernel::reorder_incident_halffaces, this, fun::placeholders::_1)); +#endif } } } diff --git a/src/OpenVolumeMesh/System/FunctionalInclude.hh b/src/OpenVolumeMesh/System/FunctionalInclude.hh index eab2051..961c0ae 100644 --- a/src/OpenVolumeMesh/System/FunctionalInclude.hh +++ b/src/OpenVolumeMesh/System/FunctionalInclude.hh @@ -63,8 +63,14 @@ namespace fun = std::tr1; #else // hope for TR1 equivalents - #include - namespace fun = std::tr1; + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + // Mavericks special treatment + #include + namespace fun = std; + #else + #include + namespace fun = std::tr1; + #endif #endif #endif diff --git a/src/OpenVolumeMesh/System/MemoryInclude.hh b/src/OpenVolumeMesh/System/MemoryInclude.hh index 0954564..775a8f6 100644 --- a/src/OpenVolumeMesh/System/MemoryInclude.hh +++ b/src/OpenVolumeMesh/System/MemoryInclude.hh @@ -73,10 +73,16 @@ #pragma warning "TR1 not available! Please install Visual Studio Service Pack 1!" #endif #else - // hope for TR1 equivalents - #include - namespace ptr = std::tr1; - #define ACG_UNIQUE_POINTER_SUPPORTED 0 + // hope for TR1 equivalents + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + // Mavericks special treatment + #include + namespace ptr = std; + #else + #include + namespace ptr = std::tr1; + #endif + #define ACG_UNIQUE_POINTER_SUPPORTED 0 #endif #endif -- GitLab