Commit 06a240b2 authored by Jan Möbius's avatar Jan Möbius

Split the non manifold vertex fixing into seperate class

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@15717 383ad7c9-94d9-4d36-a494-682f7c89f535
parent e79c16a9
...@@ -46,30 +46,34 @@ ...@@ -46,30 +46,34 @@
#include "MeshRepairPlugin.hh" #include "MeshRepairPlugin.hh"
#include "MeshFixingT.hh" #include "MeshFixingT.hh"
#include "NonManifoldVertexFixingT.hh"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MeshRepairPlugin::fixNonManifoldVertices(int _objectId) void MeshRepairPlugin::fixNonManifoldVertices(int _objectId)
{ {
TriMesh* triMesh = 0; TriMesh* triMesh = 0;
PolyMesh* polyMesh = 0; PolyMesh* polyMesh = 0;
PluginFunctions::getMesh(_objectId, triMesh); PluginFunctions::getMesh(_objectId, triMesh);
PluginFunctions::getMesh(_objectId, polyMesh); PluginFunctions::getMesh(_objectId, polyMesh);
if (triMesh) if (triMesh) {
fixNonManifoldVertices(triMesh); NonManifoldVertexFixingT<TriMesh> fixer(*triMesh);
else if (polyMesh) fixer.fix();
fixNonManifoldVertices(polyMesh); }
else else if (polyMesh) {
NonManifoldVertexFixingT<PolyMesh> fixer(*polyMesh);
fixer.fix();
} else
{ {
emit log(LOGERR, tr("Unsupported Object Type.")); emit log(LOGERR, tr("Unsupported Object Type."));
return; return;
} }
emit updatedObject(_objectId, UPDATE_ALL); emit updatedObject(_objectId, UPDATE_ALL);
emit createBackup(_objectId, "fixTopology", UPDATE_ALL); emit createBackup(_objectId, "fixNonManifoldVertices", UPDATE_ALL);
emit scriptInfo("fixTopology(" + QString::number(_objectId) + ")"); emit scriptInfo("fixNonManifoldVertices(" + QString::number(_objectId) + ")");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
......
...@@ -297,21 +297,6 @@ private: ...@@ -297,21 +297,6 @@ private:
template<typename MeshT> template<typename MeshT>
static bool sort_less_pair_second(const std::pair<typename MeshT::VertexHandle,double> &lhs,const std::pair<typename MeshT::VertexHandle,double> &rhs); static bool sort_less_pair_second(const std::pair<typename MeshT::VertexHandle,double> &lhs,const std::pair<typename MeshT::VertexHandle,double> &rhs);
/** \brief Removes non-manifold vertices by duplicating them
*
* @param _mesh target mesh
*/
template<typename MeshT>
void fixNonManifoldVertices(MeshT *_mesh);
// Checked from here
public slots: public slots:
QString version() { QString version() {
return QString("1.2"); return QString("1.2");
......
...@@ -253,95 +253,3 @@ void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps) ...@@ -253,95 +253,3 @@ void MeshRepairPlugin::snapBoundary(MeshT *_mesh, double _eps)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<typename MeshT>
void MeshRepairPlugin::fixNonManifoldVertices(MeshT *_mesh)
{
OpenMesh::FPropHandleT< size_t > component;
if ( !_mesh->get_property_handle(component,"component") )
_mesh->add_property(component, "component");
for (typename MeshT::VertexIter v_iter = _mesh->vertices_begin(); v_iter != _mesh->vertices_end(); ++v_iter)
{
//unmark all faces
for (typename MeshT::VertexFaceIter vf_iter = _mesh->vf_begin(v_iter); vf_iter; ++vf_iter)
_mesh->property(component,vf_iter.handle()) = 0;
size_t componentCount = 1;
//search and isolate new components
//shared vertices will be duplicated
for (typename MeshT::VertexFaceIter vf_iter = _mesh->vf_begin(v_iter); vf_iter; ++vf_iter)
{
//get the first face in the component
std::vector<typename MeshT::FaceHandle> checkNeighbour;
if(_mesh->property(component,vf_iter.handle()) == 0)
{
_mesh->property(component,vf_iter.handle()) = componentCount;
checkNeighbour.push_back(vf_iter.handle());
}
// if a reference face was found, a new component exists
// and a new vertex is required (except for the first component)
typename MeshT::VertexHandle v_new;
if (componentCount > 1 && !checkNeighbour.empty())
{
typename MeshT::Point p = _mesh->point(v_iter.handle());
v_new = _mesh->add_vertex(p);
}
// check all adjacent faces of our reference
while(!checkNeighbour.empty())
{
typename MeshT::FaceHandle face = checkNeighbour.back();
checkNeighbour.pop_back();
std::vector<typename MeshT::VertexHandle> f_vertices;
// get all neighbor faces of face
for (typename MeshT::FaceVertexIter fv_iter = _mesh->fv_begin(face); fv_iter; ++fv_iter)
{
f_vertices.push_back(fv_iter.handle());
if (fv_iter.handle() != v_iter)
{
//find the next neighbor face over edge v_iter and fv_iter
typename MeshT::FaceHandle nf;
for (typename MeshT::VertexFaceIter nf_iter = _mesh->vf_begin(v_iter); nf_iter && !nf.is_valid(); ++nf_iter)
{
if (nf_iter.handle() != face)
for (typename MeshT::FaceVertexIter nfv_iter = _mesh->fv_begin(nf_iter); nfv_iter && !nf.is_valid(); ++nfv_iter)
if (nfv_iter.handle() == fv_iter.handle())
nf = nf_iter.handle();
}
//if such a face was found, it is in the same component as the reference face
if (nf.is_valid() && !_mesh->property(component,nf))
{
_mesh->property(component,nf) = componentCount;
checkNeighbour.push_back(nf);
}
}
}
//if one face wasn't found in the component = 1 run, then it is a new component, due to split
if (componentCount > 1 && v_new.is_valid())
{
std::replace(f_vertices.begin(),f_vertices.end(),v_iter.handle(),v_new);
_mesh->delete_face(face,false);
_mesh->add_face(f_vertices);
}
}
// all faces which belong to v_iter and inside same component found
// the next face will be in a new component
++componentCount;
}
}
_mesh->remove_property(component);
_mesh->garbage_collection();
}
//-----------------------------------------------------------------------------
/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh 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. *
* *
* OpenMesh 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 OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 685 $ *
* $Date: 2012-09-19 18:15:39 +0200 (Mi, 19 Sep 2012) $ *
* *
\*===========================================================================*/
/** \file NonManifoldVertexFixingT.cc
*/
//=============================================================================
//
// CLASS MeshFixing - IMPLEMENTATION
//
//=============================================================================
#define NONMANIFOLDVERTEXFIXING_CC
//== INCLUDES =================================================================
#include "NonManifoldVertexFixingT.hh"
//== NAMESPACE ===============================================================
//== IMPLEMENTATION ==========================================================
template<class MeshT>
NonManifoldVertexFixingT<MeshT>::NonManifoldVertexFixingT(MeshT& _mesh ) :
mesh_(_mesh)
{
}
template<class MeshT>
void NonManifoldVertexFixingT<MeshT>::fix()
{
OpenMesh::FPropHandleT< size_t > component;
if ( !mesh_.get_property_handle(component,"component") )
mesh_.add_property(component, "component");
for (typename MeshT::VertexIter v_iter = mesh_.vertices_begin(); v_iter != mesh_.vertices_end(); ++v_iter)
{
// unmark all faces
for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(v_iter); vf_iter; ++vf_iter)
mesh_.property(component,vf_iter.handle()) = 0;
size_t componentCount = 1;
//search and isolate new components
//shared vertices will be duplicated
for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(v_iter); vf_iter; ++vf_iter)
{
//get the first face in the component
std::vector<typename MeshT::FaceHandle> checkNeighbour;
if(mesh_.property(component,vf_iter.handle()) == 0)
{
mesh_.property(component,vf_iter.handle()) = componentCount;
checkNeighbour.push_back(vf_iter.handle());
}
// if a reference face was found, a new component exists
// and a new vertex is required (except for the first component)
typename MeshT::VertexHandle v_new;
if (componentCount > 1 && !checkNeighbour.empty())
{
typename MeshT::Point p = mesh_.point(v_iter.handle());
v_new = mesh_.add_vertex(p);
}
// check all adjacent faces of our reference
while(!checkNeighbour.empty())
{
typename MeshT::FaceHandle face = checkNeighbour.back();
checkNeighbour.pop_back();
std::vector<typename MeshT::VertexHandle> f_vertices;
// get all neighbor faces of face
for (typename MeshT::FaceVertexIter fv_iter = mesh_.fv_begin(face); fv_iter; ++fv_iter)
{
f_vertices.push_back(fv_iter.handle());
if (fv_iter.handle() != v_iter)
{
//find the next neighbor face over edge v_iter and fv_iter
typename MeshT::FaceHandle nf;
for (typename MeshT::VertexFaceIter nf_iter = mesh_.vf_begin(v_iter); nf_iter && !nf.is_valid(); ++nf_iter)
{
if (nf_iter.handle() != face)
for (typename MeshT::FaceVertexIter nfv_iter = mesh_.fv_begin(nf_iter); nfv_iter && !nf.is_valid(); ++nfv_iter)
if (nfv_iter.handle() == fv_iter.handle())
nf = nf_iter.handle();
}
//if such a face was found, it is in the same component as the reference face
if (nf.is_valid() && !mesh_.property(component,nf))
{
mesh_.property(component,nf) = componentCount;
checkNeighbour.push_back(nf);
}
}
}
//if one face wasn't found in the component = 1 run, then it is a new component, due to split
if (componentCount > 1 && v_new.is_valid())
{
std::replace(f_vertices.begin(),f_vertices.end(),v_iter.handle(),v_new);
mesh_.delete_face(face,false);
mesh_.add_face(f_vertices);
}
}
// all faces which belong to v_iter and inside same component found
// the next face will be in a new component
++componentCount;
}
}
mesh_.remove_property(component);
mesh_.garbage_collection();
}
/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh 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. *
* *
* OpenMesh 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 OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 653 $ *
* $Date: 2012-08-22 10:49:55 +0200 (Mi, 22 Aug 2012) $ *
* *
\*===========================================================================*/
#ifndef NONMANIFOLDVERTEXFIXING_HH
#define NONMANIFOLDVERTEXFIXING_HH
//=============================================================================
//
// CLASS MeshFixing
//
//=============================================================================
//== INCLUDES =================================================================
//== NAMESPACE ================================================================
//== CLASS DEFINITION =========================================================
/** \brief Removed non-manifold vertices from a mesh by duplicating them
*
*
*
*/
template<class MeshT>
class NonManifoldVertexFixingT {
public:
NonManifoldVertexFixingT(MeshT& _mesh );
void fix();
private:
MeshT& mesh_;
};
#if defined(INCLUDE_TEMPLATES) && !defined(NONMANIFOLDVERTEXFIXING_CC)
#define NONMANIFOLDVERTEXFIXING_TEMPLATES
#include "NonManifoldVertexFixingT.cc"
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment