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).
This commit is contained in:
Paolo Cignoni cignoni 2010-04-20 01:19:08 +00:00
parent 374ac6b12c
commit ee2ea565f8
8 changed files with 214 additions and 291 deletions

View File

@ -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<vcg/complex/trimesh/base.h>
#include <vcg/complex/trimesh/clean.h>
#include<vcg/space/triangle3.h>
#include<vcg/complex/trimesh/update/topology.h>
#include<vcg/complex/trimesh/update/color.h>
#include <vcg/container/simple_temporary_data.h>
#include <iostream>
#include <QtGlobal>
namespace vcg{
TO BE REMOVED
} // end namespace
#endif

View File

@ -21,17 +21,15 @@
* *
****************************************************************************/
#include <QtGui>
#include <limits>
#include "meshcolorize.h"
#include "color_manifold.h"
#include <vcg/complex/trimesh/clean.h>
#include <vcg/complex/trimesh/stat.h>
#include <vcg/complex/trimesh/smooth.h>
#include <vcg/complex/trimesh/update/flag.h>
#include <vcg/complex/trimesh/update/selection.h>
#include <vcg/complex/trimesh/update/curvature.h>
#include <vcg/complex/trimesh/update/quality.h>
#include <limits>
#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
"'<i>Discrete Differential-Geometry Operators for Triangulated 2-Manifolds</i>' <br>"
"M. Meyer, M. Desbrun, P. Schroder, A. H. Barr");
case CP_TRIANGLE_QUALITY: return tr("Colorize faces depending on triangle quality:<br/>1: minimum ratio height/edge among the edges<br/>2: ratio between radii of incenter and circumcenter<br/>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<CMeshO>::IsTwoManifoldFace(m.cm) ) {
if ( tri::Clean<CMeshO>::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<CFaceO *> IntersFace;
vector<CFaceO *>::iterator fpi;
tri::Clean<CMeshO>::SelfIntersections(m.cm,IntersFace);
if(ID(filter)==CP_SELFINTERSECT_COLOR)
{
tri::UpdateColor<CMeshO>::FaceConstant(m.cm,Color4b::White);
for(fpi=IntersFace.begin();fpi!=IntersFace.end();++fpi)
(*fpi)->C()=Color4b::Red;
}
else
{
tri::UpdateSelection<CMeshO>::ClearFace(m.cm);
for(fpi=IntersFace.begin();fpi!=IntersFace.end();++fpi)
(*fpi)->SetS();
}
break;
}
case CP_BORDER:
vcg::tri::UpdateColor<CMeshO>::VertexBorderFlag(m.cm);
break;
case CP_RANDOM_FACE:
case CP_RANDOM_FACE:
vcg::tri::UpdateColor<CMeshO>::MultiFaceRandom(m.cm);
break;
case CP_TEXBORDER:
vcg::tri::UpdateTopology<CMeshO>::FaceFaceFromTexCoord(m.cm);
vcg::tri::UpdateFlags<CMeshO>::FaceBorderFromFF(m.cm);
vcg::tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m.cm);
vcg::tri::UpdateColor<CMeshO>::VertexBorderFlag(m.cm);
// Just to be sure restore standard topology and border flags
tri::UpdateTopology<CMeshO>::FaceFace(m.cm);
tri::UpdateFlags<CMeshO>::FaceBorderFromFF(m.cm);
tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m.cm);
break;
case CP_COLOR_NON_MANIFOLD_FACE:
ColorManifoldFace<CMeshO>(m.cm);
break;
case CP_COLOR_NON_MANIFOLD_VERTEX:
ColorManifoldVertex<CMeshO>(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:

View File

@ -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,

View File

@ -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<CMeshO>::CompactFaceVector(m);
tri::Allocator<CMeshO>::CompactVertexVector(m);
tri::UpdateTopology<CMeshO>::FaceFace(m);
tri::Allocator<CMeshO>::CompactFaceVector(m);
tri::Allocator<CMeshO>::CompactVertexVector(m);
tri::UpdateTopology<CMeshO>::FaceFace(m);
tri::UpdateTopology<CMeshO>::VertexFace(m);
bool edgeManif = tri::Clean<CMeshO>::IsTwoManifoldFace(m);
bool vertManif = tri::Clean<CMeshO>::IsTwoManifoldVertexFFVF(m);
int edgeManif = tri::Clean<CMeshO>::CountNonManifoldEdgeFF(m,true);
int faceEdgeManif = tri::UpdateSelection<CMeshO>::CountFace(m);
tri::UpdateSelection<CMeshO>::ClearVertex(m);
tri::UpdateSelection<CMeshO>::ClearFace(m);
int vertManif = tri::Clean<CMeshO>::CountNonManifoldVertexFF(m,true);
tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(m);
int faceVertManif = tri::UpdateSelection<CMeshO>::CountFace(m);
int edgeNum=0,borderNum=0;
tri::Clean<CMeshO>::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<CMeshO>::ConnectedComponents(m);
int connectedComponentsNum = tri::Clean<CMeshO>::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)

View File

@ -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<CMeshO>::IsTwoManifoldFace(m.cm) )
if ( tri::Clean<CMeshO>::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<CMeshO>::IsTwoManifoldFace(m.cm) ) {
if ( tri::Clean<CMeshO>::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<CMeshO>::IsTwoManifoldFace(m.cm) ) {
if ( tri::Clean<CMeshO>::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<CMeshO>::VertexFace(m.cm);
vcg::tri::UpdateTopology<CMeshO>::FaceFace(m.cm);
if ( ! tri::Clean<CMeshO>::IsTwoManifoldFace(m.cm) ) {
if ( ! tri::Clean<CMeshO>::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<CMeshO>::PrincipalDirectionsNormalCycles(m.cm); break;
case 3:
vcg::tri::UpdateTopology<CMeshO>::VertexFace(m.cm);
if ( ! tri::Clean<CMeshO>::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<CMeshO>::computeCurvature(m.cm);
tri::UpdateCurvatureFitting<CMeshO>::computeCurvature(m.cm);
break;
default:assert(0);break;

View File

@ -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

View File

@ -25,35 +25,15 @@
#include <math.h>
#include <stdlib.h>
#include "meshselect.h"
#include <vcg/complex/trimesh/update/selection.h>
#include <vcg/complex/trimesh/clean.h>
#include <vcg/complex/trimesh/stat.h>
#include <vcg/space/colorspace.h>
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<CMeshO>::VertexFromFaceLoose(m.cm);
tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(m.cm);
break;
case FP_SELECT_BORDER_FACES: tri::UpdateSelection<CMeshO>::FaceFromBorder(m.cm);
case FP_SELECT_BORDER: tri::UpdateSelection<CMeshO>::VertexFromBorderFlag(m.cm);
break;
case FP_SELECT_BY_QUALITY:
{
@ -237,59 +266,104 @@ bool SelectionFilterPlugin::applyFilter(QAction *action, MeshDocument &md, RichP
else tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(m.cm);
}
break;
case CP_SELECT_TEXBORDER:
tri::UpdateTopology<CMeshO>::FaceFaceFromTexCoord(m.cm);
tri::UpdateFlags<CMeshO>::FaceBorderFromFF(m.cm);
tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m.cm);
tri::UpdateSelection<CMeshO>::VertexFromBorderFlag(m.cm);
// Just to be sure restore standard topology and border flags
tri::UpdateTopology<CMeshO>::FaceFace(m.cm);
tri::UpdateFlags<CMeshO>::FaceBorderFromFF(m.cm);
tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m.cm);
break;
case CP_SELECT_NON_MANIFOLD_FACE:
tri::Clean<CMeshO>::CountNonManifoldEdgeFF(m.cm,true);
break;
case CP_SELECT_NON_MANIFOLD_VERTEX:
tri::Clean<CMeshO>::CountNonManifoldVertexFF(m.cm,true);
break;
case CP_SELFINTERSECT_SELECT:
{
std::vector<CFaceO *> IntersFace;
std::vector<CFaceO *>::iterator fpi;
tri::Clean<CMeshO>::SelfIntersections(m.cm,IntersFace);
tri::UpdateSelection<CMeshO>::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)

View File

@ -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;