From ee2ea565f84bda3dbad60137a485b7ccdaeaf1e6 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Tue, 20 Apr 2010 01:19:08 +0000 Subject: [PATCH] Cleaned and moved filters for selecting selfintersecting faces, tex border vertices, non manifold edges and non manifold faces to a the filter_select plugin. Now nonmanifold selecting filters now select both vertex and faces when meaningful. Removed coloring filters for coloring selfintersecting faces and non manifold situations. Improved robustness of self intersecting filter. Changed the name of the filters for better ordering in the menus (subdiv, transformation filters should go together, etc). --- .../filter_colorize/color_manifold.h | 68 ------ .../filter_colorize/meshcolorize.cpp | 124 ++--------- .../filter_colorize/meshcolorize.h | 8 +- .../filter_measure/filter_measure.cpp | 25 ++- .../filter_meshing/meshfilter.cpp | 40 ++-- .../filter_select/filter_select.pro | 3 +- .../filter_select/meshselect.cpp | 210 ++++++++++++------ src/meshlabplugins/filter_select/meshselect.h | 27 ++- 8 files changed, 214 insertions(+), 291 deletions(-) delete mode 100644 src/meshlabplugins/filter_colorize/color_manifold.h diff --git a/src/meshlabplugins/filter_colorize/color_manifold.h b/src/meshlabplugins/filter_colorize/color_manifold.h deleted file mode 100644 index f861e822a..000000000 --- a/src/meshlabplugins/filter_colorize/color_manifold.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log$ -Revision 1.5 2006/12/08 21:27:55 cignoni -Added missing include temporary data - -Revision 1.4 2006/12/06 21:24:00 cignoni -Completed NonManifoldVertex - -Revision 1.3 2006/12/05 15:37:27 cignoni -Added rough version of non manifold vertex coloring - -Revision 1.2 2006/02/15 05:32:34 cignoni -Now it colors also non manifold faces - -Revision 1.1 2006/01/06 11:14:44 giec -Change location meshfilter to meshcolorize. ----------------------------------------------------------------------- ----------------------------------------------------------------------- - -Revision 1.1 2005/12/30 10:15:41 giec -Filter that it colors the edge non manifold - - - -****************************************************************************/ -#ifndef __VCGLIB_COLOR_MANIFOLD -#define __VCGLIB_COLOR_MANIFOLD - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace vcg{ - -TO BE REMOVED - -} // end namespace -#endif diff --git a/src/meshlabplugins/filter_colorize/meshcolorize.cpp b/src/meshlabplugins/filter_colorize/meshcolorize.cpp index de29bd89b..29589dc42 100644 --- a/src/meshlabplugins/filter_colorize/meshcolorize.cpp +++ b/src/meshlabplugins/filter_colorize/meshcolorize.cpp @@ -21,17 +21,15 @@ * * ****************************************************************************/ #include -#include -#include "meshcolorize.h" -#include "color_manifold.h" #include #include #include #include -#include #include #include +#include +#include "meshcolorize.h" class Frange @@ -50,23 +48,16 @@ using namespace vcg; ExtraMeshColorizePlugin::ExtraMeshColorizePlugin() { typeList << - CP_CLAMP_QUALITY << + CP_CLAMP_QUALITY << CP_MAP_QUALITY_INTO_COLOR << CP_DISCRETE_CURVATURE << CP_TRIANGLE_QUALITY << - CP_SELFINTERSECT_SELECT << - CP_SELFINTERSECT_COLOR << - CP_BORDER << - CP_TEXBORDER << - CP_COLOR_NON_MANIFOLD_FACE << - CP_COLOR_NON_MANIFOLD_VERTEX << CP_VERTEX_SMOOTH << CP_FACE_SMOOTH << CP_VERTEX_TO_FACE << CP_FACE_TO_VERTEX << CP_TEXTURE_TO_VERTEX << - //CP_COLOR_NON_TOPO_COHERENT << - CP_RANDOM_FACE; + CP_RANDOM_FACE; FilterIDType tt; foreach(tt , types()) @@ -76,23 +67,17 @@ ExtraMeshColorizePlugin::ExtraMeshColorizePlugin() { QString ExtraMeshColorizePlugin::filterName(FilterIDType c) const{ switch(c) { - case CP_CLAMP_QUALITY: return tr("Clamp vertex quality"); - case CP_MAP_QUALITY_INTO_COLOR: return QString("Colorize by Quality"); - case CP_DISCRETE_CURVATURE: return QString("Discrete Curvatures"); - case CP_TRIANGLE_QUALITY: return QString("Triangle quality"); - case CP_SELFINTERSECT_COLOR: return QString("Self Intersections"); - case CP_SELFINTERSECT_SELECT: return QString("Self Intersecting Faces"); - case CP_BORDER: return QString("Border"); - case CP_TEXBORDER: return QString("Texture Border"); - case CP_COLOR_NON_MANIFOLD_FACE: return QString("Color non Manifold Faces"); - case CP_COLOR_NON_MANIFOLD_VERTEX:return QString("Color non Manifold Vertices"); - case CP_COLOR_NON_TOPO_COHERENT: return QString("Color edges topologically non coherent"); - case CP_VERTEX_SMOOTH: return QString("Laplacian Smooth Vertex Color"); - case CP_FACE_SMOOTH: return QString("Laplacian Smooth Face Color"); - case CP_VERTEX_TO_FACE: return QString("Vertex to Face color transfer"); - case CP_FACE_TO_VERTEX: return QString("Face to Vertex color transfer"); - case CP_TEXTURE_TO_VERTEX: return QString("Texture to Vertex color transfer"); - case CP_RANDOM_FACE: return QString("Random Face Color"); + case CP_CLAMP_QUALITY: return QString("Clamp vertex quality"); + case CP_MAP_QUALITY_INTO_COLOR: return QString("Colorize by Quality"); + case CP_DISCRETE_CURVATURE: return QString("Discrete Curvatures"); + case CP_TRIANGLE_QUALITY: return QString("Triangle quality"); + case CP_COLOR_NON_TOPO_COHERENT: return QString("Color edges topologically non coherent"); + case CP_VERTEX_SMOOTH: return QString("Smooth: Laplacian Vertex Color"); + case CP_FACE_SMOOTH: return QString("Smooth: Laplacian Face Color"); + case CP_VERTEX_TO_FACE: return QString("Transfer Color: Vertex to Face"); + case CP_FACE_TO_VERTEX: return QString("Transfer Color: Face to Vertex"); + case CP_TEXTURE_TO_VERTEX: return QString("Transfer Color: Texture to Vertex"); + case CP_RANDOM_FACE: return QString("Random Face Color"); default: assert(0); } @@ -108,12 +93,6 @@ QString ExtraMeshColorizePlugin::filterInfo(FilterIDType filterId) const "'Discrete Differential-Geometry Operators for Triangulated 2-Manifolds'
" "M. Meyer, M. Desbrun, P. Schroder, A. H. Barr"); case CP_TRIANGLE_QUALITY: return tr("Colorize faces depending on triangle quality:
1: minimum ratio height/edge among the edges
2: ratio between radii of incenter and circumcenter
3: 2*sqrt(a, b)/(a+b), a, b the eigenvalues of M^tM, M transform triangle into equilateral"); - case CP_SELFINTERSECT_SELECT: return tr("Select only self intersecting faces."); - case CP_SELFINTERSECT_COLOR: return tr("Colorize only self intersecting faces."); - case CP_BORDER : return tr("Colorize only border edges."); - case CP_TEXBORDER : return tr("Colorize only border edges."); - case CP_COLOR_NON_MANIFOLD_FACE: return tr("Colorize the non manifold edges, eg the edges where there are more than two incident faces"); - case CP_COLOR_NON_MANIFOLD_VERTEX:return tr("Colorize only non manifold edges eg. "); case CP_VERTEX_SMOOTH: return QString("Laplacian Smooth Vertex Color"); case CP_FACE_SMOOTH: return QString("Laplacian Smooth Face Color"); case CP_VERTEX_TO_FACE: return QString("Vertex to Face color transfer"); @@ -133,13 +112,6 @@ int ExtraMeshColorizePlugin::getRequirements(QAction *action) { case CP_DISCRETE_CURVATURE: return MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER | MeshModel::MM_VERTCURV; case CP_TRIANGLE_QUALITY: return MeshModel::MM_FACECOLOR; - case CP_SELFINTERSECT_SELECT: - case CP_SELFINTERSECT_COLOR: - return MeshModel::MM_FACEMARK | MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACECOLOR; - case CP_BORDER: return MeshModel::MM_FACEFLAGBORDER; - case CP_TEXBORDER: return MeshModel::MM_FACEFACETOPO; - case CP_COLOR_NON_MANIFOLD_FACE: - case CP_COLOR_NON_MANIFOLD_VERTEX: return MeshModel::MM_FACEFACETOPO; case CP_RANDOM_FACE: return MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACECOLOR; case CP_CLAMP_QUALITY: return 0; case CP_MAP_QUALITY_INTO_COLOR: return 0; @@ -237,7 +209,7 @@ bool ExtraMeshColorizePlugin::applyFilter(QAction *filter, MeshDocument &md, Ric } case CP_DISCRETE_CURVATURE: { - if ( ! tri::Clean::IsTwoManifoldFace(m.cm) ) { + if ( tri::Clean::CountNonManifoldEdgeFF(m.cm) > 0) { errorMessage = "Mesh has some not 2-manifold faces, Curvature computation requires manifoldness"; // text return false; // can't continue, mesh can't be processed } @@ -292,50 +264,11 @@ bool ExtraMeshColorizePlugin::applyFilter(QAction *filter, MeshDocument &md, Ric break; } - case CP_SELFINTERSECT_SELECT: - case CP_SELFINTERSECT_COLOR: - { - vector IntersFace; - vector::iterator fpi; - tri::Clean::SelfIntersections(m.cm,IntersFace); - if(ID(filter)==CP_SELFINTERSECT_COLOR) - { - tri::UpdateColor::FaceConstant(m.cm,Color4b::White); - for(fpi=IntersFace.begin();fpi!=IntersFace.end();++fpi) - (*fpi)->C()=Color4b::Red; - } - else - { - tri::UpdateSelection::ClearFace(m.cm); - for(fpi=IntersFace.begin();fpi!=IntersFace.end();++fpi) - (*fpi)->SetS(); - } - break; - } - case CP_BORDER: - vcg::tri::UpdateColor::VertexBorderFlag(m.cm); - break; - case CP_RANDOM_FACE: + case CP_RANDOM_FACE: vcg::tri::UpdateColor::MultiFaceRandom(m.cm); break; - case CP_TEXBORDER: - vcg::tri::UpdateTopology::FaceFaceFromTexCoord(m.cm); - vcg::tri::UpdateFlags::FaceBorderFromFF(m.cm); - vcg::tri::UpdateFlags::VertexBorderFromFace(m.cm); - vcg::tri::UpdateColor::VertexBorderFlag(m.cm); - - // Just to be sure restore standard topology and border flags - tri::UpdateTopology::FaceFace(m.cm); - tri::UpdateFlags::FaceBorderFromFF(m.cm); - tri::UpdateFlags::VertexBorderFromFace(m.cm); - break; - case CP_COLOR_NON_MANIFOLD_FACE: - ColorManifoldFace(m.cm); - break; - case CP_COLOR_NON_MANIFOLD_VERTEX: - ColorManifoldVertex(m.cm); - break; + case CP_VERTEX_SMOOTH: { int iteration = par.getInt("iteration"); @@ -382,20 +315,16 @@ MeshFilterInterface::FilterClass ExtraMeshColorizePlugin::getClass(QAction *a) { case CP_CLAMP_QUALITY: return MeshFilterInterface::Quality; - case CP_BORDER: - case CP_TEXBORDER: - case CP_COLOR_NON_MANIFOLD_VERTEX: - case CP_COLOR_NON_MANIFOLD_FACE: case CP_MAP_QUALITY_INTO_COLOR: case CP_DISCRETE_CURVATURE: case CP_COLOR_NON_TOPO_COHERENT: case CP_VERTEX_SMOOTH: case CP_FACE_TO_VERTEX: return MeshFilterInterface::VertexColoring; + case CP_TEXTURE_TO_VERTEX: return MeshFilterInterface::VertexColoring; - case CP_SELFINTERSECT_SELECT: return MeshFilterInterface::Selection; - case CP_SELFINTERSECT_COLOR: + case CP_TRIANGLE_QUALITY: case CP_RANDOM_FACE: case CP_FACE_SMOOTH: @@ -410,11 +339,6 @@ int ExtraMeshColorizePlugin::getPreConditions(QAction *a) const { switch(ID(a)) { - case CP_BORDER: - case CP_COLOR_NON_MANIFOLD_VERTEX: - case CP_COLOR_NON_MANIFOLD_FACE: - case CP_SELFINTERSECT_SELECT: - case CP_SELFINTERSECT_COLOR: case CP_TRIANGLE_QUALITY: case CP_RANDOM_FACE: case CP_DISCRETE_CURVATURE: @@ -434,8 +358,6 @@ int ExtraMeshColorizePlugin::getPreConditions(QAction *a) const return MeshModel::MM_VERTCOLOR; case CP_TEXTURE_TO_VERTEX: - case CP_TEXBORDER: - return MeshModel::MM_WEDGTEXCOORD; default: assert(0); } @@ -446,22 +368,16 @@ int ExtraMeshColorizePlugin::postCondition( QAction* a ) const { switch(ID(a)) { - case CP_SELFINTERSECT_SELECT: - case CP_SELFINTERSECT_COLOR: case CP_TRIANGLE_QUALITY: case CP_RANDOM_FACE: case CP_COLOR_NON_TOPO_COHERENT: case CP_FACE_SMOOTH: case CP_VERTEX_TO_FACE: return MeshModel::MM_FACECOLOR; - case CP_BORDER: - case CP_COLOR_NON_MANIFOLD_VERTEX: - case CP_COLOR_NON_MANIFOLD_FACE: case CP_MAP_QUALITY_INTO_COLOR: case CP_FACE_TO_VERTEX: case CP_VERTEX_SMOOTH: case CP_TEXTURE_TO_VERTEX: - case CP_TEXBORDER: return MeshModel::MM_VERTCOLOR; case CP_DISCRETE_CURVATURE: diff --git a/src/meshlabplugins/filter_colorize/meshcolorize.h b/src/meshlabplugins/filter_colorize/meshcolorize.h index 90227f4ba..ebee4f621 100644 --- a/src/meshlabplugins/filter_colorize/meshcolorize.h +++ b/src/meshlabplugins/filter_colorize/meshcolorize.h @@ -97,16 +97,10 @@ class ExtraMeshColorizePlugin : public QObject, public MeshFilterInterface public: enum { - CP_CLAMP_QUALITY, + CP_CLAMP_QUALITY, CP_MAP_QUALITY_INTO_COLOR, CP_DISCRETE_CURVATURE, CP_TRIANGLE_QUALITY, - CP_SELFINTERSECT_SELECT, - CP_SELFINTERSECT_COLOR, - CP_BORDER, - CP_TEXBORDER, - CP_COLOR_NON_MANIFOLD_FACE, - CP_COLOR_NON_MANIFOLD_VERTEX, CP_VERTEX_SMOOTH, CP_FACE_SMOOTH, CP_FACE_TO_VERTEX, diff --git a/src/meshlabplugins/filter_measure/filter_measure.cpp b/src/meshlabplugins/filter_measure/filter_measure.cpp index 765e2f1e7..f3aee7fc4 100644 --- a/src/meshlabplugins/filter_measure/filter_measure.cpp +++ b/src/meshlabplugins/filter_measure/filter_measure.cpp @@ -110,27 +110,34 @@ bool FilterMeasurePlugin::applyFilter(QAction *filter, MeshDocument &md, RichPar CMeshO &m=md.mm()->cm; md.mm()->updateDataMask(MeshModel::MM_FACEFACETOPO); md.mm()->updateDataMask(MeshModel::MM_VERTFACETOPO); - tri::Allocator::CompactFaceVector(m); - tri::Allocator::CompactVertexVector(m); - tri::UpdateTopology::FaceFace(m); + tri::Allocator::CompactFaceVector(m); + tri::Allocator::CompactVertexVector(m); + tri::UpdateTopology::FaceFace(m); tri::UpdateTopology::VertexFace(m); - bool edgeManif = tri::Clean::IsTwoManifoldFace(m); - bool vertManif = tri::Clean::IsTwoManifoldVertexFFVF(m); + int edgeManif = tri::Clean::CountNonManifoldEdgeFF(m,true); + int faceEdgeManif = tri::UpdateSelection::CountFace(m); + tri::UpdateSelection::ClearVertex(m); + tri::UpdateSelection::ClearFace(m); + + int vertManif = tri::Clean::CountNonManifoldVertexFF(m,true); + tri::UpdateSelection::FaceFromVertexLoose(m); + int faceVertManif = tri::UpdateSelection::CountFace(m); int edgeNum=0,borderNum=0; tri::Clean::CountEdges(m, edgeNum, borderNum); int holeNum; Log("V: %6i E: %6i F:%6i",m.vn,edgeNum,m.fn); Log("Boundary Edges %i",borderNum); - int connectedComponentsNum = tri::Clean::ConnectedComponents(m); + int connectedComponentsNum = tri::Clean::CountConnectedComponents(m); Log("Mesh is composed by %i connected component(s)",connectedComponentsNum); - if(edgeManif && vertManif) + if(edgeManif==0 && vertManif==0) Log("Mesh has is two-manifold "); - if(!edgeManif) Log("Mesh has some non two manifold edges\n"); - if(!vertManif) Log("Mesh has some non two manifold vertexes\n"); + if(edgeManif!=0) Log("Mesh has %i non two manifold edges and %i faces are incident on these edges\n",edgeManif,faceEdgeManif); + + if(vertManif!=0) Log("Mesh has %i non two manifold vertexes and %i faces are incident on these vertices\n",vertManif,faceVertManif); // For Manifold meshes compute some other stuff if(vertManif && edgeManif) diff --git a/src/meshlabplugins/filter_meshing/meshfilter.cpp b/src/meshlabplugins/filter_meshing/meshfilter.cpp index 188aa2ed7..fe38983fc 100644 --- a/src/meshlabplugins/filter_meshing/meshfilter.cpp +++ b/src/meshlabplugins/filter_meshing/meshfilter.cpp @@ -145,24 +145,25 @@ QString ExtraMeshFilterPlugin::filterName(FilterIDType filter) const { switch (filter) { - case FP_LOOP_SS : return tr("Loop Subdivision Surfaces"); - case FP_BUTTERFLY_SS : return tr("Butterfly Subdivision Surfaces"); - case FP_REMOVE_UNREFERENCED_VERTEX : return tr("Remove Unreferenced Vertex"); + case FP_LOOP_SS : return tr("Subdivision Surfaces: Loop"); + case FP_BUTTERFLY_SS : return tr("Subdivision Surfaces: Butterfly Subdivision"); + case FP_MIDPOINT : return tr("Subdivision Surfaces: Midpoint"); + case FP_REFINE_CATMULL : return tr("Subdivision Surfaces: Catmull-Clark"); + case FP_REMOVE_UNREFERENCED_VERTEX : return tr("Remove Unreferenced Vertex"); case FP_REMOVE_DUPLICATED_VERTEX : return tr("Remove Duplicated Vertex"); case FP_REMOVE_FACES_BY_AREA : return tr("Remove Zero Area Faces"); case FP_REMOVE_FACES_BY_EDGE : return tr("Remove Faces with edges longer than..."); case FP_QUADRIC_SIMPLIFICATION : return tr("Quadric Edge Collapse Decimation"); case FP_QUADRIC_TEXCOORD_SIMPLIFICATION : return tr("Quadric Edge Collapse Decimation (with texture)"); case FP_CLUSTERING : return tr("Clustering decimation"); - case FP_MIDPOINT : return tr("Midpoint Subdivision Surfaces"); - case FP_REORIENT : return tr("Re-Orient all faces coherentely"); + case FP_REORIENT : return tr("Re-Orient all faces coherentely"); case FP_INVERT_FACES : return tr("Invert Faces Orientation"); - case FP_SCALE : return tr("Scale Mesh"); - case FP_CENTER : return tr("Center Mesh"); - case FP_ROTATE : return tr("Rotate Mesh"); - case FP_ROTATE_FIT : return tr("Rotate to Fit to a plane"); - case FP_PRINCIPAL_AXIS : return tr("Align to Principal Axis"); - case FP_FLIP_AND_SWAP : return tr("Flip and/or swap axis"); + case FP_SCALE : return tr("Transform: Scale"); + case FP_CENTER : return tr("Transform: Move, Translate, Center"); + case FP_ROTATE : return tr("Transform: Rotate"); + case FP_ROTATE_FIT : return tr("Transform: Rotate to Fit to a plane"); + case FP_PRINCIPAL_AXIS : return tr("Transform: Align to Principal Axis"); + case FP_FLIP_AND_SWAP : return tr("Transform: Flip and/or swap axis"); case FP_FREEZE_TRANSFORM : return tr("Freeze Current Matrix"); case FP_RESET_TRANSFORM : return tr("Reset Current Matrix"); case FP_REMOVE_NON_MANIFOLD_FACE : return tr("Remove Non Manifold Faces"); @@ -171,8 +172,7 @@ QString ExtraMeshFilterPlugin::filterName(FilterIDType filter) const case FP_COMPUTE_PRINC_CURV_DIR : return tr("Compute curvature principal directions"); case FP_CLOSE_HOLES : return tr("Close Holes"); case FP_CYLINDER_UNWRAP : return tr("Geometric Cylindrical Unwrapping"); - case FP_REFINE_CATMULL : return tr("Catmull-Clark Subdivision Surfaces"); - case FP_REFINE_HALF_CATMULL : return tr("Tri to Quad by 4-8 Subdivision"); + case FP_REFINE_HALF_CATMULL : return tr("Tri to Quad by 4-8 Subdivision"); case FP_QUAD_PAIRING : return tr("Tri to Quad by smart triangle pairing"); case FP_FAUX_CREASE : return tr("Crease Marking with NonFaux Edges"); case FP_VATTR_SEAM : return tr("Vertex Attribute Seam"); @@ -477,7 +477,7 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction * filter, MeshDocument & md, Ric ID(filter) == FP_BUTTERFLY_SS || ID(filter) == FP_MIDPOINT ) { - if ( ! tri::Clean::IsTwoManifoldFace(m.cm) ) + if ( tri::Clean::CountNonManifoldEdgeFF(m.cm) > 0) { errorMessage = "Mesh has some not 2 manifoldfaces, subdivision surfaces require manifoldness"; // text return false; // can't continue, mesh can't be processed @@ -558,7 +558,7 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction * filter, MeshDocument & md, Ric { bool oriented; bool orientable; - if ( ! tri::Clean::IsTwoManifoldFace(m.cm) ) { + if ( tri::Clean::CountNonManifoldEdgeFF(m.cm)>0 ) { errorMessage = "Mesh has some not 2-manifold faces, Orientability requires manifoldness"; // text return false; // can't continue, mesh can't be processed } @@ -860,7 +860,7 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction * filter, MeshDocument & md, Ric switch(par.getEnum("Method")){ case 0: - if ( ! tri::Clean::IsTwoManifoldFace(m.cm) ) { + if ( tri::Clean::CountNonManifoldEdgeFF(m.cm) >0 ) { errorMessage = "Mesh has some not 2-manifold faces, cannot compute principal curvature directions"; // text return false; // can't continue, mesh can't be processed } @@ -869,18 +869,14 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction * filter, MeshDocument & md, Ric case 2: vcg::tri::UpdateTopology::VertexFace(m.cm); vcg::tri::UpdateTopology::FaceFace(m.cm); - if ( ! tri::Clean::IsTwoManifoldFace(m.cm) ) { + if ( ! tri::Clean::CountNonManifoldEdgeFF(m.cm) >0) { errorMessage = "Mesh has some not 2-manifold faces, cannot compute principal curvature directions"; // text return false; // can't continue, mesh can't be processed } vcg::tri::UpdateCurvature::PrincipalDirectionsNormalCycles(m.cm); break; case 3: vcg::tri::UpdateTopology::VertexFace(m.cm); - if ( ! tri::Clean::IsTwoManifoldFace(m.cm) ) { - errorMessage = "Mesh has some not 2-manifold faces, cannot compute principal curvature directions"; // text - return false; // can't continue, mesh can't be processed - } - tri::UpdateCurvatureFitting::computeCurvature(m.cm); + tri::UpdateCurvatureFitting::computeCurvature(m.cm); break; default:assert(0);break; diff --git a/src/meshlabplugins/filter_select/filter_select.pro b/src/meshlabplugins/filter_select/filter_select.pro index 576661d62..3ccbc4398 100644 --- a/src/meshlabplugins/filter_select/filter_select.pro +++ b/src/meshlabplugins/filter_select/filter_select.pro @@ -1,6 +1,7 @@ include (../../shared.pri) -HEADERS += meshselect.h +HEADERS += $$VCGDIR/vcg/complex/trimesh/clean.h\ + meshselect.h SOURCES += meshselect.cpp TARGET = filter_select diff --git a/src/meshlabplugins/filter_select/meshselect.cpp b/src/meshlabplugins/filter_select/meshselect.cpp index 95b07be65..3a99cc466 100644 --- a/src/meshlabplugins/filter_select/meshselect.cpp +++ b/src/meshlabplugins/filter_select/meshselect.cpp @@ -25,35 +25,15 @@ #include #include #include "meshselect.h" -#include +#include #include #include using namespace vcg; - QString SelectionFilterPlugin::filterName(FilterIDType filter) const +SelectionFilterPlugin::SelectionFilterPlugin() { - switch(filter) - { - case FP_SELECT_ALL : return QString("Select All"); - case FP_SELECT_NONE : return QString("Select None"); - case FP_SELECT_INVERT : return QString("Invert Selection"); - case FP_SELECT_DELETE_VERT : return QString("Delete Selected Vertices"); - case FP_SELECT_DELETE_FACE : return QString("Delete Selected Faces"); - case FP_SELECT_DELETE_FACEVERT : return QString("Delete Selected Faces and Vertices"); - case FP_SELECT_ERODE : return QString("Erode Selection"); - case FP_SELECT_DILATE : return QString("Dilate Selection"); - case FP_SELECT_BORDER_FACES: return QString("Select Border Faces"); - case FP_SELECT_BY_QUALITY : return QString("Select by Vertex Quality"); - case FP_SELECT_BY_RANGE: return QString("Select by Coord range"); - case FP_SELECT_BY_COLOR: return QString("Select Face by Vertex Color"); - } - return QString("Unknown filter"); -} - -SelectionFilterPlugin::SelectionFilterPlugin() -{ - typeList << + typeList << FP_SELECT_ALL << FP_SELECT_NONE << FP_SELECT_DELETE_VERT << @@ -61,13 +41,17 @@ SelectionFilterPlugin::SelectionFilterPlugin() FP_SELECT_DELETE_FACEVERT << FP_SELECT_ERODE << FP_SELECT_DILATE << - FP_SELECT_BORDER_FACES << - FP_SELECT_INVERT << - FP_SELECT_BY_QUALITY << - FP_SELECT_BY_COLOR; - + FP_SELECT_BORDER << + FP_SELECT_INVERT << + FP_SELECT_BY_QUALITY << + CP_SELFINTERSECT_SELECT << + CP_SELECT_TEXBORDER << + CP_SELECT_NON_MANIFOLD_FACE << + CP_SELECT_NON_MANIFOLD_VERTEX << + FP_SELECT_BY_COLOR; + FilterIDType tt; - + foreach(tt , types()) { actionList << new QAction(filterName(tt), this); @@ -83,14 +67,59 @@ SelectionFilterPlugin::SelectionFilterPlugin() actionList.last()->setShortcut(QKeySequence ("Shift+Del")); actionList.last()->setIcon(QIcon(":/images/delete_facevert.png")); } - } + } } -SelectionFilterPlugin::~SelectionFilterPlugin() + + QString SelectionFilterPlugin::filterName(FilterIDType filter) const { - for (int i = 0; i < actionList.count() ; i++ ) { - delete actionList.at(i); - } + switch(filter) + { + case FP_SELECT_ALL : return QString("Select All"); + case FP_SELECT_NONE : return QString("Select None"); + case FP_SELECT_INVERT : return QString("Invert Selection"); + case FP_SELECT_DELETE_VERT : return QString("Delete Selected Vertices"); + case FP_SELECT_DELETE_FACE : return QString("Delete Selected Faces"); + case FP_SELECT_DELETE_FACEVERT : return QString("Delete Selected Faces and Vertices"); + case FP_SELECT_ERODE : return QString("Erode Selection"); + case FP_SELECT_DILATE : return QString("Dilate Selection"); + case FP_SELECT_BORDER: return QString("Select Border Faces"); + case FP_SELECT_BY_QUALITY : return QString("Select by Vertex Quality"); + case FP_SELECT_BY_RANGE: return QString("Select by Coord range"); + case FP_SELECT_BY_COLOR: return QString("Select Face by Vertex Color"); + case CP_SELFINTERSECT_SELECT: return QString("Self Intersecting Faces"); + case CP_SELECT_TEXBORDER: return QString("Select Vertex Texture Seams"); + case CP_SELECT_NON_MANIFOLD_FACE: return QString("Select non Manifold Edges "); + case CP_SELECT_NON_MANIFOLD_VERTEX: return QString("Select non Manifold Vertices"); + + } + return QString("Unknown filter"); } + QString SelectionFilterPlugin::filterInfo(FilterIDType filterId) const + { + switch(filterId) + { + case FP_SELECT_DILATE : return tr("Dilate (expand) the current set of selected faces"); + case FP_SELECT_DELETE_VERT : return tr("Delete the current set of selected vertices; faces that share one of the deleted vertexes are deleted too."); + case FP_SELECT_DELETE_FACE : return tr("Delete the current set of selected faces, vertices that remains unreferenced are not deleted."); + case FP_SELECT_DELETE_FACEVERT : return tr("Delete the current set of selected faces and all the vertices surrounded by that faces."); + case CP_SELFINTERSECT_SELECT: return tr("Select only self intersecting faces."); + case FP_SELECT_ERODE : return tr("Erode (reduce) the current set of selected faces"); + case FP_SELECT_INVERT : return tr("Invert the current set of selected faces"); + case FP_SELECT_NONE : return tr("Clear the current set of selected faces"); + case FP_SELECT_ALL : return tr("Select all the faces of the current mesh"); + case FP_SELECT_BORDER : return tr("Select all the faces on the boundary"); + case FP_SELECT_BY_QUALITY : return tr("Select all the faces with all the vertexes within the specified quality range"); + case FP_SELECT_BY_COLOR: return tr("Select part of the mesh based on its color."); + case CP_SELECT_TEXBORDER : return tr("Colorize only border edges."); + case CP_SELECT_NON_MANIFOLD_FACE: return tr("Select the faces and the vertices incident on non manifold edges (e.g. edges where more than two faces are incident); note that this function select the components that are related to non manifold edges. The case of non manifold vertices is specifically managed by the pertinent filter."); + case CP_SELECT_NON_MANIFOLD_VERTEX: return tr("Select the non manifold vertices that do not belong to non manifold edges. For example two cones connected by their apex. Vertices incident on non manifold edges are ignored."); + + + } + assert(0); + return QString(); + } + void SelectionFilterPlugin::initParameterSet(QAction *action, MeshModel &m, RichParameterSet &parlst) { switch(ID(action)) @@ -131,8 +160,8 @@ void SelectionFilterPlugin::initParameterSet(QAction *action, MeshModel &m, Rich bool SelectionFilterPlugin::applyFilter(QAction *action, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * /*cb*/) { - MeshModel &m=*(md.mm()); - CMeshO::FaceIterator fi; + MeshModel &m=*(md.mm()); + CMeshO::FaceIterator fi; CMeshO::VertexIterator vi; switch(ID(action)) { @@ -179,7 +208,7 @@ bool SelectionFilterPlugin::applyFilter(QAction *action, MeshDocument &md, RichP case FP_SELECT_DILATE : tri::UpdateSelection::VertexFromFaceLoose(m.cm); tri::UpdateSelection::FaceFromVertexLoose(m.cm); break; - case FP_SELECT_BORDER_FACES: tri::UpdateSelection::FaceFromBorder(m.cm); + case FP_SELECT_BORDER: tri::UpdateSelection::VertexFromBorderFlag(m.cm); break; case FP_SELECT_BY_QUALITY: { @@ -237,59 +266,104 @@ bool SelectionFilterPlugin::applyFilter(QAction *action, MeshDocument &md, RichP else tri::UpdateSelection::FaceFromVertexLoose(m.cm); } break; + case CP_SELECT_TEXBORDER: + tri::UpdateTopology::FaceFaceFromTexCoord(m.cm); + tri::UpdateFlags::FaceBorderFromFF(m.cm); + tri::UpdateFlags::VertexBorderFromFace(m.cm); + tri::UpdateSelection::VertexFromBorderFlag(m.cm); + + // Just to be sure restore standard topology and border flags + tri::UpdateTopology::FaceFace(m.cm); + tri::UpdateFlags::FaceBorderFromFF(m.cm); + tri::UpdateFlags::VertexBorderFromFace(m.cm); + break; + case CP_SELECT_NON_MANIFOLD_FACE: + tri::Clean::CountNonManifoldEdgeFF(m.cm,true); + break; + case CP_SELECT_NON_MANIFOLD_VERTEX: + tri::Clean::CountNonManifoldVertexFF(m.cm,true); + break; + case CP_SELFINTERSECT_SELECT: + { + std::vector IntersFace; + std::vector::iterator fpi; + tri::Clean::SelfIntersections(m.cm,IntersFace); + tri::UpdateSelection::ClearFace(m.cm); + for(fpi=IntersFace.begin();fpi!=IntersFace.end();++fpi) + (*fpi)->SetS(); + break; + } default: assert(0); } return true; } -QString SelectionFilterPlugin::filterInfo(FilterIDType filterId) const - { - switch(filterId) - { - case FP_SELECT_DILATE : return tr("Dilate (expand) the current set of selected faces"); - case FP_SELECT_DELETE_VERT : return tr("Delete the current set of selected vertices; faces that share one of the deleted vertexes are deleted too."); - case FP_SELECT_DELETE_FACE : return tr("Delete the current set of selected faces, vertices that remains unreferenced are not deleted."); - case FP_SELECT_DELETE_FACEVERT : return tr("Delete the current set of selected faces and all the vertices surrounded by that faces."); - case FP_SELECT_ERODE : return tr("Erode (reduce) the current set of selected faces"); - case FP_SELECT_INVERT : return tr("Invert the current set of selected faces"); - case FP_SELECT_NONE : return tr("Clear the current set of selected faces"); - case FP_SELECT_ALL : return tr("Select all the faces of the current mesh"); - case FP_SELECT_BORDER_FACES : return tr("Select all the faces on the boundary"); - case FP_SELECT_BY_QUALITY : return tr("Select all the faces with all the vertexes within the specified quality range"); - case FP_SELECT_BY_COLOR: return tr("Select part of the mesh based on its color."); - } - assert(0); - return QString(); - } +MeshFilterInterface::FilterClass SelectionFilterPlugin::getClass(QAction *action) +{ + switch(ID(action)) + { + case CP_SELFINTERSECT_SELECT: + case CP_SELECT_NON_MANIFOLD_VERTEX: + case CP_SELECT_NON_MANIFOLD_FACE: + return FilterClass(MeshFilterInterface::Selection + MeshFilterInterface::Cleaning);; + + case CP_SELECT_TEXBORDER : return FilterClass(MeshFilterInterface::Selection + MeshFilterInterface::Texture); + case FP_SELECT_BY_COLOR : return FilterClass(MeshFilterInterface::Selection + MeshFilterInterface::FaceColoring); + case FP_SELECT_BY_QUALITY : return FilterClass(MeshFilterInterface::Selection + MeshFilterInterface::Quality); + } + return MeshFilterInterface::Selection; +} int SelectionFilterPlugin::getRequirements(QAction *action) { switch(ID(action)) { - case FP_SELECT_BORDER_FACES: return MeshModel::MM_FACEFLAGBORDER; - case FP_SELECT_BY_COLOR: return MeshModel::MM_VERTCOLOR; + case CP_SELECT_NON_MANIFOLD_FACE: + case CP_SELECT_NON_MANIFOLD_VERTEX: return MeshModel::MM_FACEFACETOPO; + case FP_SELECT_BORDER: return MeshModel::MM_FACEFLAGBORDER; + case CP_SELECT_TEXBORDER: return MeshModel::MM_FACEFACETOPO; + case CP_SELFINTERSECT_SELECT: + return MeshModel::MM_FACEMARK | MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACECOLOR; + default: return 0; } } int SelectionFilterPlugin::postCondition(QAction *action) const - { - if(ID(action) != FP_SELECT_DELETE_VERT && - ID(action) != FP_SELECT_DELETE_FACE && - ID(action) != FP_SELECT_DELETE_FACEVERT) - return MeshModel::MM_VERTFLAGSELECT | MeshModel::MM_FACEFLAGSELECT; - - return MeshModel::MM_UNKNOWN; +{ + switch(ID(action)) + { + case FP_SELECT_ALL: + case FP_SELECT_NONE: + case FP_SELECT_INVERT: + case FP_SELECT_ERODE: + case FP_SELECT_DILATE: + case FP_SELECT_BORDER: + case FP_SELECT_BY_QUALITY: + case FP_SELECT_BY_RANGE: + case FP_SELECT_BY_COLOR: + case CP_SELFINTERSECT_SELECT: + case CP_SELECT_TEXBORDER: + case CP_SELECT_NON_MANIFOLD_FACE: + case CP_SELECT_NON_MANIFOLD_VERTEX: + return MeshModel::MM_VERTFLAGSELECT | MeshModel::MM_FACEFLAGSELECT; + } + return MeshModel::MM_UNKNOWN; } int SelectionFilterPlugin::getPreConditions( QAction * action) const { switch(ID(action)) { - case FP_SELECT_BY_COLOR: return MeshModel::MM_VERTCOLOR; - case FP_SELECT_BY_QUALITY: return MeshModel::MM_VERTQUALITY; - default: return 0; + case CP_SELECT_NON_MANIFOLD_VERTEX: + case CP_SELECT_NON_MANIFOLD_FACE: + case CP_SELFINTERSECT_SELECT: + case FP_SELECT_BORDER: return MeshModel::MM_FACENUMBER; + case FP_SELECT_BY_COLOR: return MeshModel::MM_VERTCOLOR; + case FP_SELECT_BY_QUALITY: return MeshModel::MM_VERTQUALITY; + case CP_SELECT_TEXBORDER: return MeshModel::MM_WEDGTEXCOORD; } + return 0; } Q_EXPORT_PLUGIN(SelectionFilterPlugin) diff --git a/src/meshlabplugins/filter_select/meshselect.h b/src/meshlabplugins/filter_select/meshselect.h index 295c80cfc..7a31ad39d 100644 --- a/src/meshlabplugins/filter_select/meshselect.h +++ b/src/meshlabplugins/filter_select/meshselect.h @@ -39,26 +39,29 @@ class SelectionFilterPlugin : public QObject, public MeshFilterInterface - name of the plugin separated by _ */ enum { - FP_SELECT_ALL, - FP_SELECT_NONE, - FP_SELECT_INVERT, + FP_SELECT_ALL, + FP_SELECT_NONE, + FP_SELECT_INVERT, FP_SELECT_DELETE_VERT, FP_SELECT_DELETE_FACE, - FP_SELECT_DELETE_FACEVERT, - FP_SELECT_ERODE, - FP_SELECT_DILATE, - FP_SELECT_BORDER_FACES, - FP_SELECT_BY_QUALITY, - FP_SELECT_BY_RANGE, - FP_SELECT_BY_COLOR + FP_SELECT_DELETE_FACEVERT, + FP_SELECT_ERODE, + FP_SELECT_DILATE, + FP_SELECT_BORDER, + FP_SELECT_BY_QUALITY, + FP_SELECT_BY_RANGE, + FP_SELECT_BY_COLOR,CP_SELFINTERSECT_SELECT, + CP_SELECT_TEXBORDER, + CP_SELECT_NON_MANIFOLD_FACE, + CP_SELECT_NON_MANIFOLD_VERTEX } ; SelectionFilterPlugin(); - ~SelectionFilterPlugin(); + //~SelectionFilterPlugin(); virtual QString filterInfo(FilterIDType filter) const; virtual QString filterName(FilterIDType filter) const; - virtual FilterClass getClass(QAction *) {return MeshFilterInterface::Selection;}; + virtual FilterClass getClass(QAction *); void initParameterSet(QAction *action, MeshModel &m, RichParameterSet &parlst); int getPreConditions(QAction *) const; int postCondition( QAction* ) const;