/*===========================================================================*\ * * * OpenFlipper * * Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen * * www.openflipper.org * * * *--------------------------------------------------------------------------- * * This file is part of OpenFlipper. * * * * OpenFlipper 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. * * * * OpenFlipper 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 OpenFlipper. If not, * * see . * * * \*===========================================================================*/ /*===========================================================================*\ * * * $Revision$ * * $LastChangedBy$ * * $Date$ * * * \*===========================================================================*/ #define COMPONENTSPLUGIN_CC #include "ComponentsPlugin.hh" #include #include #include //------------------------------------------------------------------------------ /** \brief Split mesh into components * * This function will split an arbitrary component out of a mesh. * It takes a copy of the original mesh. * * @param _mesh the original mesh * @param _copy original mesh copy with identical topology and geometry * the copy will contain one component of the original mesh. */ template< class MeshT > void ComponentsPlugin::splitComponent( MeshT* _mesh, MeshT* _copy){ //init properties OpenMesh::FPropHandleT< bool > visited; if ( !_mesh->get_property_handle(visited,"visited") ) _mesh->add_property(visited, "visited"); typename MeshT::FaceIter f_it; typename MeshT::FaceIter f_end = _mesh->faces_end(); //init property for all faces for (f_it = _mesh->faces_begin(); f_it != f_end; ++f_it) _mesh->property(visited, *f_it) = false; typename MeshT::FaceHandle fh; //Take the first face in the mesh as we only split one component apart fh = *(_mesh->faces_begin()); _mesh->property(visited, fh) = true; //if none was found -> finished if (!fh.is_valid() ) return; std::vector< typename MeshT::FaceHandle > handles; handles.push_back( fh ); //grow from face and collect faces in this component while( handles.size() > 0 ){ typename MeshT::FaceHandle current = handles.back(); handles.pop_back(); typename MeshT::FaceFaceIter ff_it; for (ff_it=_mesh->ff_iter( current ); ff_it.is_valid(); ++ff_it) if ( ! _mesh->property(visited, *ff_it) ){ _mesh->property(visited, *ff_it) = true; handles.push_back( *ff_it ); } } //delete the found component from the original mesh and keep it in the copy for (typename MeshT::FaceIter f_it = _mesh->faces_begin(); f_it != f_end; ++f_it) // -1 means not the component if ( _mesh->property(visited, *f_it) ) _mesh->delete_face( *f_it ); else _copy->delete_face( *f_it ); //remove garbage from the components _copy->garbage_collection(); _mesh->garbage_collection(); _mesh->remove_property(visited); } template< class MeshT > void ComponentsPlugin::selectBiggestComponent( MeshT* _mesh){ OpenMesh::FPropHandleT< bool > visited; if ( !_mesh->get_property_handle(visited,"visited") ) _mesh->add_property(visited, "visited"); std::vector facesInBiggest; for (typename MeshT::FaceIter fIter = _mesh->faces_begin(); fIter != _mesh->faces_end(); ++fIter) { if (_mesh->property(visited,*fIter)) continue; //It is a vertex, which is not visited => new component std::vector componentFaces; componentFaces.push_back(*fIter); for(std::size_t i = 0; i < componentFaces.size(); ++i ) { //add all not visited neightbours for (typename MeshT::FaceFaceIter ffIter = _mesh->ff_begin(componentFaces[i]); ffIter.is_valid() ;++ffIter) { if (!ffIter->is_valid()) std::cout << "handleId: " << *ffIter << std::endl; if (ffIter->is_valid() && !_mesh->property(visited,*ffIter) ) { _mesh->property(visited,*ffIter) = true; componentFaces.push_back(*ffIter); } } } //all faces are found, so compare the components if (facesInBiggest.size() < componentFaces.size()) { std::swap(facesInBiggest,componentFaces); } } _mesh->remove_property(visited); //select all faces in the biggest component; for (typename std::vector::iterator iter = facesInBiggest.begin(); iter != facesInBiggest.end(); ++iter) { _mesh->status(*iter).set_selected(true); } } template< class MeshT > void ComponentsPlugin::isolateBiggestComponent( MeshT* _mesh) { for (typename MeshT::FaceIter fIter = _mesh->faces_begin(); fIter != _mesh->faces_end(); ++fIter) { if (!_mesh->status(*fIter).selected()) { //delete face and isolated vertices _mesh->delete_face(*fIter,true); } else { _mesh->status(*fIter).set_selected(false); } } _mesh->garbage_collection(); }