diff --git a/src/meshlabplugins/cleanfilter/cleanfilter.cpp b/src/meshlabplugins/cleanfilter/cleanfilter.cpp new file mode 100644 index 000000000..498714640 --- /dev/null +++ b/src/meshlabplugins/cleanfilter/cleanfilter.cpp @@ -0,0 +1,310 @@ +/**************************************************************************** +* 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.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 +#include +#include +#include +#include + + +// temporaneamente prendo la versione corrente dalla cartella test +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "cleanfilter.h" +#include "remove_small_cc.h" +#include +#include + +/////////////////////// Accessory functions + +bool askFloat(float &val, QString Title, QString Label, QWidget *parent) +{ + QDialog *dialog=new QDialog(parent); + dialog->setModal(true); + dialog->setWindowTitle(Title); + + QPushButton *okButton = new QPushButton("OK", dialog); + QPushButton *cancButton = new QPushButton("cancel", dialog); + QGridLayout *gridLayout = new QGridLayout(dialog); + dialog->setLayout(gridLayout); + + gridLayout->addWidget(okButton,1,1); + gridLayout->addWidget(cancButton,1,0); + + QLineEdit *floatEdit = new QLineEdit(dialog); + floatEdit->setText(QString::number(val)); + QLabel *label = new QLabel(Label,dialog); + gridLayout->addWidget(label,0,0 ); + gridLayout->addWidget(floatEdit,0,1); + + QObject::connect(floatEdit, SIGNAL(returnPressed ()), dialog, SLOT(accept())); + QObject::connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept())); + QObject::connect(cancButton, SIGNAL(clicked()), dialog, SLOT(reject())); + + dialog->exec(); + if(dialog->result()== QDialog::Accepted ) + { + val=floatEdit->text().toFloat(); + return true; + } + if(dialog->result()== QDialog::Rejected ) return false; + assert(0); + return true; +} + + +bool askInt(int &val, QString Title, QString Label, QWidget *parent) +{ + QDialog *dialog=new QDialog(parent); + dialog->setModal(true); + dialog->setWindowTitle(Title); + + QPushButton *okButton = new QPushButton("OK", dialog); + QPushButton *cancButton = new QPushButton("cancel", dialog); + QGridLayout *gridLayout = new QGridLayout(dialog); + dialog->setLayout(gridLayout); + + gridLayout->addWidget(okButton,1,1); + gridLayout->addWidget(cancButton,1,0); + + QLineEdit *floatEdit = new QLineEdit(dialog); + floatEdit->setText(QString::number(val)); + QLabel *label = new QLabel(Label,dialog); + gridLayout->addWidget(label,0,0 ); + gridLayout->addWidget(floatEdit,0,1); + + QObject::connect(floatEdit, SIGNAL(returnPressed ()), dialog, SLOT(accept())); + QObject::connect(okButton, SIGNAL(clicked()), dialog, SLOT(accept())); + QObject::connect(cancButton, SIGNAL(clicked()), dialog, SLOT(reject())); + + dialog->exec(); + if(dialog->result()== QDialog::Accepted ) + { + val=floatEdit->text().toInt(); + return true; + } + if(dialog->result()== QDialog::Rejected ) return false; + assert(0); + return true; +} + +///////////////////////////////////////////////////////////////////// + + +using namespace vcg; + +CleanFilter::CleanFilter() +{ + typeList << FP_REBUILD_SURFACE << FP_REMOVE_WRT_Q << FP_REMOVE_ISOLATED_COMPLEXITY << FP_REMOVE_ISOLATED_DIAMETER; + + FilterType tt; + foreach(tt , types()) + actionList << new QAction(ST(tt), this); +} + +CleanFilter::~CleanFilter() { + for (int i = 0; i < actionList.count() ; i++ ) + delete actionList.at(i); +} + +const QString CleanFilter::ST(FilterType filter) +{ + switch(filter) + { + case FP_REBUILD_SURFACE : return QString("Build surface from points"); + case FP_REMOVE_WRT_Q : return QString("Remove Faces 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)"); + 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 ActionInfo &CleanFilter::Info(QAction *action) +{ + static ActionInfo ai; + switch(ID(action)) + { + case FP_REBUILD_SURFACE : ai.Help = tr("Merge"); break; + case FP_REMOVE_ISOLATED_COMPLEXITY: ai.Help = tr("Remove Isolated"); break; + case FP_REMOVE_ISOLATED_DIAMETER: ai.Help = tr("Remove Isolated"); break; + case FP_REMOVE_WRT_Q: ai.Help = tr("Remove all the faces with quality lower than..."); break; + } + return ai; +} + +const PluginInfo &CleanFilter::Info() +{ + static PluginInfo ai; + ai.Date=tr("__DATE__"); + ai.Version = tr("0.1"); + ai.Author = ("Paolo Cignoni"); + return ai; +} + +const int CleanFilter::getRequirements(QAction *action) +{ + switch(ID(action)) + { + case FP_REMOVE_WRT_Q: + case FP_REBUILD_SURFACE : return 0; + case FP_REMOVE_ISOLATED_COMPLEXITY: + case FP_REMOVE_ISOLATED_DIAMETER: + return MeshModel::MM_FACETOPO | MeshModel::MM_BORDERFLAG | MeshModel::MM_FACEMARK; + default: assert(0); + } + return 0; +} + +bool CleanFilter::getParameters(QAction *action, QWidget *parent, MeshModel &m,FilterParameter &par) +{ + par.clear(); + switch(ID(action)) + { + case FP_REBUILD_SURFACE : + { + static float maxDiag=0; + if(askFloat(maxDiag, "Ballpivoting Surface reconstruction", + "Enter ball size as a diag perc. (0 autoguess))",parent)) + { + par.addFloat("BallRadius",m.cm.bbox.Diag()*maxDiag/100.0); + return true; + } + else return false; + } + return true; + case FP_REMOVE_ISOLATED_DIAMETER: + { + static float maxDiag=10; + if(askFloat(maxDiag, "Remove Small Connected Components under a given size","Enter size (as a diag perc 0..100)",parent)) + { + par.addFloat("MinComponentDiag",m.cm.bbox.Diag()*maxDiag/100.0); + return true; + } + else return false; + } + case FP_REMOVE_ISOLATED_COMPLEXITY: + { + static int minCC=25; + if(askInt(minCC, "Remove Small Connected Components","Enter minimum conn. comp size:",parent)) + { + par.addInt("MinComponentSize",minCC); + return true; + } + else return false; + } + case FP_REMOVE_WRT_Q: + { + static float val=1.0; + if(askFloat(val, "Quality Filter","Delete all Vertices with quality under:",parent)) + { + par.addFloat("MaxQualityThr",val); + return true; + } + else return false; + } + } +} + + +bool CleanFilter::applyFilter(QAction *filter, MeshModel &m, FilterParameter & par, vcg::CallBackPos * cb) +{ + if(filter->text() == ST(FP_REBUILD_SURFACE) ) + { + float radius = par.getFloat("BallRadius"); + float clustering = 0.1; + float crease=0; + m.cm.fn=0; + m.cm.face.resize(0); + NormalExtrapolation >::ExtrapolateNormals(m.cm.vert.begin(), m.cm.vert.end(), 10,-1,NormalExtrapolation >::NormalOrientation::IsCorrect, cb); + tri::Pivot pivot(m.cm, radius, clustering, crease); + // the main processing + pivot.buildMesh(cb); + } + if(filter->text() == ST(FP_REMOVE_ISOLATED_DIAMETER) ) + { + float minCC= par.getFloat("MinComponentDiag"); + RemoveSmallConnectedComponentsDiameter(m.cm,minCC); + } + + if(filter->text() == ST(FP_REMOVE_ISOLATED_COMPLEXITY) ) + { + float minCC= par.getInt("MinComponentSize"); + RemoveSmallConnectedComponentsSize(m.cm,minCC); + } + if(filter->text() == ST(FP_REMOVE_WRT_Q) ) + { + float val=par.getFloat("MaxQualityThr"); + CMeshO::VertexIterator vi; + for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi) + if(!(*vi).IsD() && (*vi).Q()IsD() ||(*fi).V(1)->IsD() ||(*fi).V(2)->IsD() ) + { + (*fi).SetD(); + --m.cm.fn; + } + + } + return true; +} + + +Q_EXPORT_PLUGIN(CleanFilter) diff --git a/src/meshlabplugins/cleanfilter/cleanfilter.h b/src/meshlabplugins/cleanfilter/cleanfilter.h new file mode 100644 index 000000000..2813de2b2 --- /dev/null +++ b/src/meshlabplugins/cleanfilter/cleanfilter.h @@ -0,0 +1,82 @@ +/**************************************************************************** +* 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.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 +#include +#include + +#include +#include + + +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 + } ; + + + CleanFilter(); + ~CleanFilter(); + virtual const QString ST(FilterType filter); + virtual const ActionInfo &Info(QAction *); + virtual const PluginInfo &Info(); + + virtual const FilterClass getClass(QAction *); + virtual bool getParameters(QAction *, QWidget *, MeshModel &m, FilterParameter &par); + virtual const int getRequirements(QAction *); + virtual bool applyFilter(QAction *filter, MeshModel &m, FilterParameter & /*parent*/, vcg::CallBackPos * cb) ; + protected: + +}; + + + + + + +#endif diff --git a/src/meshlabplugins/cleanfilter/cleanfilter.pro b/src/meshlabplugins/cleanfilter/cleanfilter.pro new file mode 100644 index 000000000..25cac1259 --- /dev/null +++ b/src/meshlabplugins/cleanfilter/cleanfilter.pro @@ -0,0 +1,30 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. ../../../../sf ../../../../code/lib/glew/include + +HEADERS = cleanfilter.h + +SOURCES = cleanfilter.cpp +TARGET = cleanfilter +DESTDIR = ../../meshlab/plugins +QT += xml + + +# the following line is needed to avoid mismatch between +# the awful min/max macros of windows and the limits max +win32:DEFINES += NOMINMAX +unix{ + QMAKE_CC = gcc + QMAKE_CXX = g++ + QMAKE_LINK = gcc + CONFIG += warn_off debug_and_release +# LIBS += -l3ds +} + + +contains(TEMPLATE,lib) { + CONFIG(debug, debug|release) { + unix:TARGET = $$member(TARGET, 0)_debug + else:TARGET = $$member(TARGET, 0)d + } +} diff --git a/src/meshlabplugins/cleanfilter/parameter.cpp b/src/meshlabplugins/cleanfilter/parameter.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/meshlabplugins/cleanfilter/parameter.h b/src/meshlabplugins/cleanfilter/parameter.h new file mode 100644 index 000000000..ed457b806 --- /dev/null +++ b/src/meshlabplugins/cleanfilter/parameter.h @@ -0,0 +1,12 @@ +class Parameter : QWidget +{ + public: + + void addBool(); + void addOption() + void addFloat(); + void addRangedFloat(); + + exec +}; + diff --git a/src/meshlabplugins/cleanfilter/remove_small_cc.h b/src/meshlabplugins/cleanfilter/remove_small_cc.h new file mode 100644 index 000000000..2828d3375 --- /dev/null +++ b/src/meshlabplugins/cleanfilter/remove_small_cc.h @@ -0,0 +1,93 @@ +/**************************************************************************** +* 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.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 +#include + +namespace vcg +{ +template +void RemoveSmallConnectedComponentsSize(MeshType &m, int maxCCSize) +{ + std::vector< std::pair > CCV; + int tt=vcg::tri::Clean::ConnectedComponents(m, CCV); + + tri::ConnectedIterator ci; + for(unsigned int i=0;i FPV; + if(CCV[i].first::iterator fpvi; + for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi) + (**fpvi).SetD(); + m.fn-=FPV.size(); + } + } +} + +template +void RemoveSmallConnectedComponentsDiameter(MeshType &m, typename MeshType::ScalarType maxDiameter) +{ + std::vector< std::pair > CCV; + int tt=vcg::tri::Clean::ConnectedComponents(m, CCV); + + tri::ConnectedIterator ci; + for(unsigned int i=0;i 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()::iterator fpvi; + for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi) + (**fpvi).SetD(); + m.fn-=FPV.size(); + } + } +} +} //end namespace +#endif