renamed cleanfilter to the standard naming scheme filter_clean

This commit is contained in:
Paolo Cignoni cignoni 2008-12-09 14:31:01 +00:00
parent b0c03e8b89
commit 44725a52f4
8 changed files with 950 additions and 0 deletions

View File

@ -0,0 +1,325 @@
/****************************************************************************
* MeshLab o o *
* A versatile mesh processing toolbox o o *
* _ O _ *
* Copyright(C) 2005 \/)\/ *
* 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. *
* *
****************************************************************************/
#include <QtGui>
#include "align_tools.h"
#include <meshlab/filterparameter.h>
#include <meshlabplugins/edit_pickpoints/pickedPoints.h>
#include <meshlabplugins/editalign/align/align_parameter.h>
#include <meshlabplugins/editalign/meshtree.h>
#include <meshlabplugins/editalign/align/AlignPair.h>
#include <vcg/math/point_matching.h>
#include <vcg/complex/trimesh/update/position.h>
#include <vcg/complex/trimesh/update/bounding.h>
#include <vcg/complex/trimesh/allocate.h>
using namespace vcg;
const QString AlignTools::FilterName = "Align Mesh using Picked Points";
const QString AlignTools::UseMarkers = "UseM";
const QString AlignTools::AllowScaling = "AllowScaling";
const QString AlignTools::UseICP = "UseICP";
const QString AlignTools::StuckMesh = "StuckMesh";
const QString AlignTools::MeshToMove = "MeshToMove";
AlignTools::AlignTools(){}
void AlignTools::buildParameterSet(FilterParameterSet & parlst)
{
vcg::AlignPair::Param ICPParameters;
AlignParameter::buildFilterParameterSet(ICPParameters, parlst);
parlst.addBool(UseMarkers, true, "Use Markers for Alignment","if true (default), then use the user picked markers to do an alignment (or pre alignment if you also use ICP).");
parlst.addBool(AllowScaling, false, "Scale the mesh","if true (false by default), in addition to the alignment, scale the mesh based on the points picked");
parlst.addBool(UseICP, true, "Use ICP for Alignment","if true (default), then use the ICP to align the two meshes.");
parlst.addMesh (StuckMesh, 0, "Stuck Mesh",
"The mesh that will not move.");
parlst.addMesh (MeshToMove, 1, "Mesh to Move",
"The mesh that will move to fit close to the Stuck Mesh.");
}
bool AlignTools::setupThenAlign(MeshModel &/*mm*/, FilterParameterSet & par)
{
//mesh that wont move
MeshModel *stuckModel = par.getMesh(StuckMesh);
PickedPoints *stuckPickedPoints = 0;
//mesh that will move
MeshModel *modelToMove = par.getMesh(MeshToMove);
PickedPoints *modelToMovePickedPoints = 0;
bool useMarkers = par.getBool(UseMarkers);
if(NULL == stuckModel || NULL == modelToMove)
{
qDebug() << "one of the input meshes to filter align was null";
return false;
}
//if we are going to use the markers try to load them
if(useMarkers){
//first try to get points from memory
if(vcg::tri::HasPerMeshAttribute(stuckModel->cm, PickedPoints::Key) )
{
CMeshO::PerMeshAttributeHandle<PickedPoints*> ppHandle =
vcg::tri::Allocator<CMeshO>::GetPerMeshAttribute<PickedPoints*>(stuckModel->cm, PickedPoints::Key);
stuckPickedPoints = ppHandle();
if(NULL == stuckPickedPoints){
qDebug() << "problem casting to picked points";
return false;
}
} else
{
//now try to load them from a file
QString ppFileName = PickedPoints::getSuggestedPickedPointsFileName(*stuckModel);
QFileInfo file(ppFileName);
if(file.exists())
{
stuckPickedPoints = new PickedPoints();
bool success = stuckPickedPoints->open(ppFileName);
if(!success){
qDebug() << "problem loading stuck picked points from a file";
return false;
}
} else
{
qDebug() << "stuck points file didnt exist: " << ppFileName;
//Log(GLLogStream::Info, "No points were found for the Stuck mesh.");
return false;
}
}
if(vcg::tri::HasPerMeshAttribute(modelToMove->cm, PickedPoints::Key) )
{
CMeshO::PerMeshAttributeHandle<PickedPoints*> ppHandle =
vcg::tri::Allocator<CMeshO>::GetPerMeshAttribute<PickedPoints*>(modelToMove->cm, PickedPoints::Key);
modelToMovePickedPoints = ppHandle();
if(NULL == modelToMovePickedPoints){
qDebug() << "problem casting to picked poitns";
return false;
}
} else
{
QString ppFileName = PickedPoints::getSuggestedPickedPointsFileName(*modelToMove);
QFileInfo file(ppFileName);
if(file.exists())
{
modelToMovePickedPoints = new PickedPoints();
bool success = modelToMovePickedPoints->open(ppFileName);
if(!success){
qDebug() << "failed to load modelToMove pick points";
return false;
}
} else
{
qDebug() << "model to move points file didnt exist: " << ppFileName;
//Log(GLLogStream::Info, "No points were found for the mesh to move.");
return false;
}
}
}
bool result = AlignTools::align(stuckModel, stuckPickedPoints,
modelToMove, modelToMovePickedPoints,
0, par);
return result;
}
bool AlignTools::align(MeshModel *stuckModel, PickedPoints *stuckPickedPoints,
MeshModel *modelToMove, PickedPoints *modelToMovePickedPoints,
GLArea *modelToMoveGLArea,
FilterParameterSet &filterParameters,
QWidget *parentWidget, bool confirm)
{
vcg::Matrix44f result;
bool useMarkers = filterParameters.getBool(UseMarkers);
bool allowScaling = filterParameters.getBool(AllowScaling);
bool useICP = filterParameters.getBool(UseICP);
if(useMarkers){
//get the picked points
std::vector<vcg::Point3f> *stuckPoints = stuckPickedPoints->getPoint3fVector();
std::vector<vcg::Point3f> *meshToMovePoints = modelToMovePickedPoints->getPoint3fVector();
//number of points are not the same so return false
if(stuckPoints->size() != meshToMovePoints->size()) return false;
//this will calculate the transform for the destination mesh model which we will be moving
//into alignment with the source
if(allowScaling)
{
qDebug() << "Scaling allowed";
vcg::PointMatching<float>::ComputeSimilarityMatchMatrix(result, *stuckPoints, *meshToMovePoints);
} else
vcg::PointMatching<float>::ComputeRigidMatchMatrix(result, *stuckPoints, *meshToMovePoints);
//set the transform
modelToMove->cm.Tr = result;
if(NULL != modelToMoveGLArea)
modelToMoveGLArea->update();
}
if(useICP)
{
qDebug("Now on to ICP");
//create a meshtree
MeshTree meshTree;
//put both meshes in it
meshTree.nodeList.push_back(new MeshNode(stuckModel, 0));
meshTree.nodeList.push_back(new MeshNode(modelToMove, 1));
//set both to glued
foreach(MeshNode *mn, meshTree.nodeList)
mn->glued=true;
vcg::AlignPair::Param ICPParameters;
//get the parameter values
AlignParameter::buildAlignParameters(filterParameters, ICPParameters);
meshTree.Process(ICPParameters);
qDebug() << "done with process for ICP";
if(NULL != modelToMoveGLArea)
modelToMoveGLArea->update();
}
if(useMarkers || useICP)
{
if(confirm && NULL != modelToMoveGLArea)
{
bool removeMeshAddedForQuestion = false;
vcg::Color4b oldStuckColor;
vcg::Color4b oldToMoveColor;
vcg::GLW::ColorMode oldColorMode;
//if the stuck model is not displayed next to the model to move,
//then temporarily display it
if(!modelToMoveGLArea->meshDoc.meshList.contains(stuckModel))
{
removeMeshAddedForQuestion = true;
modelToMoveGLArea->meshDoc.meshList.push_back(stuckModel);
//save the old colors
oldStuckColor = stuckModel->cm.C();
oldToMoveColor = modelToMove->cm.C();
//set the color of the objects
stuckModel->cm.C() = vcg::Color4b::LightBlue;
modelToMove->cm.C() = vcg::Color4b::LightGray;
//save the old colorMode
oldColorMode = modelToMoveGLArea->rm.colorMode;
//set the new colorMode
modelToMoveGLArea->rm.colorMode = GLW::CMPerMesh;
modelToMoveGLArea->update();
}
int returnValue = QMessageBox::question(parentWidget,
"MeshLab", "Do you want accept this alignment?",
QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
//if we added the other model in for comparing
if(removeMeshAddedForQuestion)
{
//remove the mesh that was added
modelToMoveGLArea->meshDoc.meshList.pop_back();
//set back to how things were before
stuckModel->cm.C() = oldStuckColor;
modelToMove->cm.C() = oldToMoveColor;
modelToMoveGLArea->rm.colorMode = oldColorMode;
modelToMoveGLArea->update();
}
if(returnValue == QMessageBox::No)
{
modelToMove->cm.Tr.SetIdentity();
modelToMoveGLArea->update();
return false;
}
}
//if there are points (may not be if you just used ICP
if(NULL != modelToMovePickedPoints)
{
//now translate the picked points points
modelToMovePickedPoints->translatePoints(modelToMove->cm.Tr);
//update the metadata
CMeshO::PerMeshAttributeHandle<PickedPoints*> ppHandle =
(vcg::tri::HasPerMeshAttribute(modelToMove->cm, PickedPoints::Key) ?
vcg::tri::Allocator<CMeshO>::GetPerMeshAttribute<PickedPoints*> (modelToMove->cm, PickedPoints::Key) :
vcg::tri::Allocator<CMeshO>::AddPerMeshAttribute<PickedPoints*> (modelToMove->cm, PickedPoints::Key) );
ppHandle() = modelToMovePickedPoints;
}
//now save the transform as perMeshData so that we can undo it in the future
CMeshO::PerMeshAttributeHandle<vcg::Matrix44f> transformHandle =
(vcg::tri::HasPerMeshAttribute(modelToMove->cm, getKey()) ?
vcg::tri::Allocator<CMeshO>::GetPerMeshAttribute<vcg::Matrix44f> (modelToMove->cm, getKey()) :
vcg::tri::Allocator<CMeshO>::AddPerMeshAttribute<vcg::Matrix44f> (modelToMove->cm, getKey()) );
transformHandle() = modelToMove->cm.Tr;
//now translate all the points in the mesh
//TODO probably should call a function to do this so if meshlab changes we dont have to
//taken from meshlab/src/meshlabplugins/meshfilter/meshfilter.cpp
//if (ID(filter) == (FP_FREEZE_TRANSFORM) ) {
vcg::tri::UpdatePosition<CMeshO>::Matrix(modelToMove->cm, modelToMove->cm.Tr);
vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(modelToMove->cm);
vcg::tri::UpdateBounding<CMeshO>::Box(modelToMove->cm);
modelToMove->cm.Tr.SetIdentity();
return true;
} else
{
qDebug() << "you ran align without choosing a method";
}
return false;
}

View File

@ -0,0 +1,61 @@
/*
* This class will will hold useful things for doing alignment of meshes
*
* @author Oscar Barney
*
*/
#ifndef ALIGN_TOOLS_H
#define ALIGN_TOOLS_H
#include <QObject>
#include <meshlab/filterparameter.h>
#include <meshlab/meshmodel.h>
#include <meshlab/glarea.h>
#include <meshlabplugins/edit_pickpoints/pickedPoints.h>
#include <meshlabplugins/editalign/align/AlignPair.h>
class AlignTools : public QObject
{
Q_OBJECT
public:
static const QString FilterName;
static const QString UseMarkers;
static const QString AllowScaling;
static const QString UseICP;
static const QString StuckMesh;
static const QString MeshToMove;
//make the default parameter set for this filter
static void buildParameterSet(FilterParameterSet & parlst);
//setup all the parameters and then call align
static bool setupThenAlign(MeshModel &mm, FilterParameterSet & par);
/*
* stuckModel - the mesh one that stays put
* modelToMove - the mesh to be moved into place
* modelToMoveGLArea - so we can update the position of the model
* parentWidget - the widget that should be the parent of the confirm dialog window
* confirm - whether to ask the user if they want the alignment to stay put
*
* return value - true if align was accepted or successful
*/
static bool align(MeshModel *stuckModel, PickedPoints *stuckPickedPoints,
MeshModel *modelToMove, PickedPoints *modelToMovePickedPoints,
GLArea *modelToMoveGLArea,
FilterParameterSet &parameters,
QWidget *parentWidget = 0, bool confirm = false);
//returns the key applied if this transform is stored to perMeshAttribute
static const std::string getKey() { return "TransformAppliedKey"; }
protected:
AlignTools();
};
#endif

View File

@ -0,0 +1,298 @@
/****************************************************************************
* MeshLab o o *
* An extendible mesh processor o o *
* _ O _ *
* Copyright(C) 2005, 2006 \/)\/ *
* 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.19 2008/04/08 10:16:04 cignoni
added missing std:: and vcg::
Revision 1.18 2007/12/14 14:57:20 cignoni
Improved ball pivoting params and descriptions
Revision 1.17 2007/12/13 00:19:35 cignoni
removed deprecated setD
Revision 1.16 2007/10/02 08:13:38 cignoni
New filter interface. Hopefully more clean and easy to use.
Revision 1.15 2007/06/11 15:26:43 ponchio
*** empty log message ***
Revision 1.14 2007/05/30 15:10:54 ponchio
*** empty log message ***
Revision 1.13 2007/05/22 15:26:02 cignoni
Improved params of ball pivoting (again)
Revision 1.12 2007/05/22 15:16:43 cignoni
Improved params of ball pivoting
Revision 1.11 2007/04/16 09:25:28 cignoni
** big change **
Added Layers managemnt.
Interfaces are changing again...
Revision 1.10 2007/03/20 16:23:07 cignoni
Big small change in accessing mesh interface. First step toward layers
Revision 1.9 2007/02/08 23:46:15 pirosu
merged srcpar and par in the GetStdParameters() function
Revision 1.8 2007/01/11 19:52:25 pirosu
fixed bug for QT 4.1.0/dotnet2003
removed the request of the window title to the plugin. The action description is used instead.
Revision 1.7 2006/12/27 21:41:58 pirosu
Added improvements for the standard plugin window:
split of the apply button in two buttons:ok and apply
added support for parameters with absolute and percentage values
Revision 1.6 2006/12/13 17:37:27 pirosu
Added standard plugin window support
Revision 1.5 2006/11/29 00:59:15 cignoni
Cleaned plugins interface; changed useless help class into a plain string
Revision 1.4 2006/11/27 06:57:19 cignoni
Wrong way of using the __DATE__ preprocessor symbol
Revision 1.3 2006/11/07 17:26:01 cignoni
small gcc compiling issues
Revision 1.2 2006/11/07 14:56:23 zifnab1974
Changes for compilation with gcc 3.4.6 on linux AMD64
Revision 1.1 2006/11/07 09:09:27 cignoni
First Working release, moved in from epoch svn
Revision 1.1 2006/01/20 13:03:27 cignoni
*** empty log message ***
*****************************************************************************/
#include <Qt>
#include <QtGui>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
#include <QtXml/QDomNode>
#include <vcg/math/matrix33.h>
#include "cleanfilter.h"
#include "remove_small_cc.h"
#include "align_tools.h"
//#include <wrap/io_trimesh/io_mask.h>
#include <vcg/complex/trimesh/create/platonic.h>
#include <vcg/complex/trimesh/update/bounding.h>
#include <vcg/complex/trimesh/update/normal.h>
#include <vcg/complex/trimesh/update/flag.h>
#include <vcg/complex/trimesh/clean.h>
#include <vcg/complex/trimesh/stat.h>
#include <vcg/complex/trimesh/create/ball_pivoting.h>
#include <vcg/space/normal_extrapolation.h>
using namespace std;
using namespace vcg;
CleanFilter::CleanFilter()
{
typeList << FP_REBUILD_SURFACE << FP_REMOVE_WRT_Q << FP_REMOVE_ISOLATED_COMPLEXITY << FP_REMOVE_ISOLATED_DIAMETER << FP_ALIGN_WITH_PICKED_POINTS;
FilterIDType tt;
foreach(tt , types())
actionList << new QAction(filterName(tt), this);
maxDiag1=0;
maxDiag2=-1;
minCC=25;
val1=1.0;
}
CleanFilter::~CleanFilter() {
for (int i = 0; i < actionList.count() ; i++ )
delete actionList.at(i);
}
const QString CleanFilter::filterName(FilterIDType filter)
{
switch(filter)
{
case FP_REBUILD_SURFACE : return QString("Ball Pivoting Surface Reconstruction");
case FP_REMOVE_WRT_Q : return QString("Remove vertices wrt quality");
case FP_REMOVE_ISOLATED_DIAMETER : return QString("Remove isolated pieces (wrt diameter)");
case FP_REMOVE_ISOLATED_COMPLEXITY : return QString("Remove isolated pieces (wrt face num)");
case FP_ALIGN_WITH_PICKED_POINTS : return AlignTools::FilterName;
default: assert(0);
}
return QString("error!");
}
const QString CleanFilter::filterInfo(FilterIDType filterId)
{
switch(filterId)
{
case FP_REBUILD_SURFACE : return QString("Reconstruct a surface using the <b>Ball Pivoting Algorithm</b> (Bernardini et al. 1999). <br>"
"Starting with a seed triangle, the BPA algorithm pivots a ball around an edge "
"(i.e. it revolves around the edge while keeping in contact with the edge endpoints) "
"until it touches another point, forming another triangle. The process continues until all reachable edges have been tried.");
case FP_REMOVE_ISOLATED_COMPLEXITY: return tr("Remove isolated connected components composed by a limited number of triangles");
case FP_REMOVE_ISOLATED_DIAMETER: return tr("Remove isolated connected components whose diameter is smaller than the specified constant");
case FP_REMOVE_WRT_Q: return tr("Remove all the vertices with a quality lower smaller than the specified constant");
case FP_ALIGN_WITH_PICKED_POINTS: return tr("Align this mesh with another that has corresponding picked points.");
default: assert(0);
}
return QString("error!");
}
const CleanFilter::FilterClass CleanFilter::getClass(QAction *a)
{
switch(ID(a))
{
case FP_REMOVE_WRT_Q :
case FP_REMOVE_ISOLATED_DIAMETER :
case FP_REMOVE_ISOLATED_COMPLEXITY :
return MeshFilterInterface::Cleaning;
default : return MeshFilterInterface::Generic;
}
}
const int CleanFilter::getRequirements(QAction *action)
{
switch(ID(action))
{
case FP_REMOVE_WRT_Q:
case FP_REBUILD_SURFACE : return MeshModel::MM_FACEFLAGBORDER | MeshModel::MM_VERTMARK;
case FP_REMOVE_ISOLATED_COMPLEXITY:
case FP_REMOVE_ISOLATED_DIAMETER:
return MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER | MeshModel::MM_FACEMARK;
case FP_ALIGN_WITH_PICKED_POINTS:
return MeshModel::MM_NONE;
default: assert(0);
}
return 0;
}
void CleanFilter::initParameterSet(QAction *action,MeshModel &m, FilterParameterSet & parlst)
{
pair<float,float> qualityRange;
switch(ID(action))
{
case FP_REBUILD_SURFACE :
parlst.addAbsPerc("BallRadius",(float)maxDiag1,0,m.cm.bbox.Diag(),"Pivoting Ball radius (0 autoguess)","The radius of the ball pivoting (rolling) over the set of points. Gaps that are larger than the ball radius will not be filled; similarly the small pits that are smaller than the ball radius will be filled.");
parlst.addFloat("Clustering",20.0f,"Clustering radius (% of ball radius)","To avoid the creation of too small triangles, if a vertex is found too close to a previous one, it is clustered/merged with it."); parlst.addFloat("CreaseThr", 90.0f,"Angle Threshold (degrees)","If we encounter a crease angle that is too large we should stop the ball rolling");
parlst.addBool("DeleteFaces",false,"Delete intial set of faces","if true all the initial faces of the mesh are deleted and the whole surface is rebuilt from scratch, other wise the current faces are used as a starting point. Useful if you run multiple times the algorithm with an incrasing ball radius.");
break;
case FP_REMOVE_ISOLATED_DIAMETER:
parlst.addAbsPerc("MinComponentDiag",m.cm.bbox.Diag()/10.0,0,m.cm.bbox.Diag(),"Enter max diameter of isolated pieces","Delete all the connected components (floating pieces) with a diameter smaller than the specified one");
break;
case FP_REMOVE_ISOLATED_COMPLEXITY:
parlst.addInt("MinComponentSize",(int)minCC,"Enter minimum conn. comp size:","Delete all the connected components (floating pieces) composed by a number of triangles smaller than the specified one");
break;
case FP_REMOVE_WRT_Q:
qualityRange=tri::Stat<CMeshO>::ComputePerVertexQualityMinMax(m.cm);
parlst.addAbsPerc("MaxQualityThr",(float)val1, qualityRange.first, qualityRange.second,"Delete all vertices with quality under:");
break;
case FP_ALIGN_WITH_PICKED_POINTS :
AlignTools::buildParameterSet(parlst);
break;
default: assert(0);
}
}
bool CleanFilter::applyFilter(QAction *filter, MeshModel &m, FilterParameterSet & par, vcg::CallBackPos * cb)
{
if(filter->text() == filterName(FP_REBUILD_SURFACE) )
{
float Radius = par.getAbsPerc("BallRadius");
float Clustering = par.getFloat("Clustering");
float CreaseThr = math::ToRad(par.getFloat("CreaseThr"));
bool DeleteFaces = par.getBool("DeleteFaces");
if(DeleteFaces) {
m.cm.fn=0;
m.cm.face.resize(0);
}
int startingFn=m.cm.fn;
Clustering /= 100.0;
tri::BallPivoting<CMeshO> pivot(m.cm, Radius, Clustering, CreaseThr);
// the main processing
pivot.BuildMesh(cb);
m.clearDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER);
Log(GLLogStream::Info,"Reconstructed surface. Added %i faces",m.cm.fn-startingFn);
}
if(filter->text() == filterName(FP_REMOVE_ISOLATED_DIAMETER) )
{
float minCC= par.getAbsPerc("MinComponentDiag");
std::pair<int,int> delInfo= RemoveSmallConnectedComponentsDiameter<CMeshO>(m.cm,minCC);
Log(GLLogStream::Info,"Removed %2 connected components out of %1", delInfo.second, delInfo.first);
}
if(filter->text() == filterName(FP_REMOVE_ISOLATED_COMPLEXITY) )
{
float minCC= par.getInt("MinComponentSize");
std::pair<int,int> delInfo=RemoveSmallConnectedComponentsSize<CMeshO>(m.cm,minCC);
Log(GLLogStream::Info,"Removed %i connected components out of %i", delInfo.second, delInfo.first);
}
if(filter->text() == filterName(FP_REMOVE_WRT_Q) )
{
int deletedFN=0;
int deletedVN=0;
float val=par.getAbsPerc("MaxQualityThr");
CMeshO::VertexIterator vi;
for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi)
if(!(*vi).IsD() && (*vi).Q()<val)
{
tri::Allocator<CMeshO>::DeleteVertex(m.cm, *vi);
deletedVN++;
}
CMeshO::FaceIterator fi;
for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) if(!(*fi).IsD())
if((*fi).V(0)->IsD() ||(*fi).V(1)->IsD() ||(*fi).V(2)->IsD() )
{
tri::Allocator<CMeshO>::DeleteFace(m.cm, *fi);
deletedFN++;
}
m.clearDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER);
Log(GLLogStream::Info,"Deleted %i vertices and %i faces with a quality lower than %f", deletedVN,deletedFN,val);
}
if(filter->text() == filterName(FP_ALIGN_WITH_PICKED_POINTS) )
{
bool result = AlignTools::setupThenAlign(m, par);
if(!result)
{
Log(GLLogStream::Info,"Align failed, make sure you have equal numbers of points.");
return false;
}
}
return true;
}
Q_EXPORT_PLUGIN(CleanFilter)

View File

@ -0,0 +1,117 @@
/****************************************************************************
* MeshLab o o *
* A versatile mesh processing toolbox o o *
* _ O _ *
* Copyright(C) 2005 \/)\/ *
* 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.8 2007/10/02 08:13:39 cignoni
New filter interface. Hopefully more clean and easy to use.
Revision 1.7 2007/04/16 09:25:28 cignoni
** big change **
Added Layers managemnt.
Interfaces are changing again...
Revision 1.6 2007/02/08 23:46:16 pirosu
merged srcpar and par in the GetStdParameters() function
Revision 1.5 2007/01/11 19:52:25 pirosu
fixed bug for QT 4.1.0/dotnet2003
removed the request of the window title to the plugin. The action description is used instead.
Revision 1.4 2006/12/27 21:41:58 pirosu
Added improvements for the standard plugin window:
split of the apply button in two buttons:ok and apply
added support for parameters with absolute and percentage values
Revision 1.3 2006/12/13 17:37:27 pirosu
Added standard plugin window support
Revision 1.2 2006/11/29 00:59:15 cignoni
Cleaned plugins interface; changed useless help class into a plain string
Revision 1.1 2006/11/07 09:09:27 cignoni
First Working release, moved in from epoch svn
Revision 1.1 2006/01/20 13:03:27 cignoni
*** empty log message ***
*****************************************************************************/
#ifndef EXTRAIOPLUGINV3D_H
#define EXTRAIOPLUGINV3D_H
#include <QObject>
#include <QStringList>
#include <QString>
#include <meshlab/meshmodel.h>
#include <meshlab/interfaces.h>
class CleanFilter : public QObject, public MeshFilterInterface
{
Q_OBJECT
Q_INTERFACES(MeshFilterInterface)
public:
/* naming convention :
- FP -> Filter Plugin
- name of the plugin separated by _
*/
enum {
FP_REBUILD_SURFACE,
FP_REMOVE_ISOLATED_COMPLEXITY,
FP_REMOVE_ISOLATED_DIAMETER,
FP_REMOVE_WRT_Q,
FP_ALIGN_WITH_PICKED_POINTS
} ;
/* default values for standard parameters' values of the plugin actions */
float maxDiag1;
float maxDiag2;
int minCC;
float val1;
CleanFilter();
~CleanFilter();
virtual const QString filterName(FilterIDType filter);
virtual const QString filterInfo(FilterIDType filter);
virtual const FilterClass getClass(QAction *);
virtual const int getRequirements(QAction *);
virtual bool autoDialog(QAction *) {return true;}
virtual void initParameterSet(QAction *,MeshModel &/*m*/, FilterParameterSet & /*parent*/);
virtual bool applyFilter(QAction *filter, MeshModel &m, FilterParameterSet & /*parent*/, vcg::CallBackPos * cb) ;
};
#endif

View File

@ -0,0 +1,33 @@
include (../../shared.pri)
HEADERS = cleanfilter.h \
../../meshlab/filterparameter.h
SOURCES = cleanfilter.cpp\
../../meshlab/filterparameter.cpp
#align stuff
HEADERS += align_tools.h \
../../meshlabplugins/edit_pickpoints/pickedPoints.h \
../../meshlabplugins/editalign/align/align_parameter.h \
../../meshlabplugins/editalign/meshtree.h \
../../meshlabplugins/editalign/align/AlignPair.h \
../../meshlabplugins/editalign/align/AlignGlobal.h \
../../meshlabplugins/editalign/align/OccupancyGrid.h \
$$VCGDIR/wrap/gl/trimesh.h
SOURCES += align_tools.cpp \
../../meshlabplugins/edit_pickpoints/pickedPoints.cpp \
../../meshlabplugins/editalign/align/align_parameter.cpp \
../../meshlabplugins/editalign/meshtree.cpp \
../../meshlabplugins/editalign/align/AlignPair.cpp \
../../meshlabplugins/editalign/align/AlignGlobal.cpp \
../../meshlabplugins/editalign/align/OccupancyGrid.cpp \
$$VCGDIR/wrap/ply/plylib.cpp
TARGET = filter_clean
QT += opengl
QT += xml

View File

@ -0,0 +1,12 @@
class Parameter : QWidget
{
public:
void addBool();
void addOption()
void addFloat();
void addRangedFloat();
exec
};

View File

@ -0,0 +1,104 @@
/****************************************************************************
* MeshLab o o *
* An extendible mesh processor o o *
* _ O _ *
* Copyright(C) 2005, 2006 \/)\/ *
* 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.3 2008/04/04 14:08:17 cignoni
Solved namespace ambiguities caused by the removal of a silly 'using namespace' in meshmodel.h
Revision 1.2 2007/12/14 11:52:18 cignoni
now use the correct deleteFace/vert and returns info on the number of deleted stuff
Revision 1.1 2006/11/07 09:09:28 cignoni
First Working release, moved in from epoch svn
Revision 1.1 2006/01/20 13:03:27 cignoni
*** empty log message ***
*****************************************************************************/
#ifndef __VCGLIB__REMOVE_SMALL_CC
#define __VCGLIB__REMOVE_SMALL_CC
#include <vcg/space/point3.h>
#include <vcg/complex/trimesh/clean.h>
namespace vcg
{
template<class MeshType>
std::pair<int,int> RemoveSmallConnectedComponentsSize(MeshType &m, int maxCCSize)
{
std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
int TotalCC=vcg::tri::Clean<MeshType>::ConnectedComponents(m, CCV);
int DeletedCC=0;
tri::ConnectedIterator<MeshType> ci;
for(unsigned int i=0;i<CCV.size();++i)
{
std::vector<typename MeshType::FacePointer> FPV;
if(CCV[i].first<maxCCSize)
{
DeletedCC++;
for(ci.start(m,CCV[i].second);!ci.completed();++ci)
FPV.push_back(*ci);
typename std::vector<typename MeshType::FacePointer>::iterator fpvi;
for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi)
tri::Allocator<MeshType>::DeleteFace(m,(**fpvi));
}
}
return std::make_pair<int,int>(TotalCC,DeletedCC);
}
/// Remove the connected components smaller than a given diameter
// it returns a pair with the number of connected components and the number of deleted ones.
template<class MeshType>
std::pair<int,int> RemoveSmallConnectedComponentsDiameter(MeshType &m, typename MeshType::ScalarType maxDiameter)
{
std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
int TotalCC=vcg::tri::Clean<MeshType>::ConnectedComponents(m, CCV);
int DeletedCC=0;
tri::ConnectedIterator<MeshType> ci;
for(unsigned int i=0;i<CCV.size();++i)
{
Box3f bb;
std::vector<typename MeshType::FacePointer> FPV;
for(ci.start(m,CCV[i].second);!ci.completed();++ci)
{
FPV.push_back(*ci);
bb.Add((*ci)->P(0));
bb.Add((*ci)->P(1));
bb.Add((*ci)->P(2));
}
if(bb.Diag()<maxDiameter)
{
DeletedCC++;
typename std::vector<typename MeshType::FacePointer>::iterator fpvi;
for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi)
tri::Allocator<MeshType>::DeleteFace(m,(**fpvi));
}
}
return std::make_pair<int,int>(TotalCC,DeletedCC);
}
} //end namespace
#endif