From 348b2d92fbbc070da38d6b3cbffcedbfbee78584 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Thu, 2 Apr 2009 01:07:39 +0000 Subject: [PATCH] Corrected stupid bug (prenormalization of face normals) that stopped the working of curvature optimization. Improved help wording and a deg/rad mismatch too... --- src/fgt/filter_trioptimize/curvedgeflip.h | 12 +++++-- .../filter_trioptimize/filter_trioptimize.cpp | 32 +++++++++---------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/fgt/filter_trioptimize/curvedgeflip.h b/src/fgt/filter_trioptimize/curvedgeflip.h index f0a7c1837..a874ede18 100644 --- a/src/fgt/filter_trioptimize/curvedgeflip.h +++ b/src/fgt/filter_trioptimize/curvedgeflip.h @@ -200,9 +200,11 @@ public: virtual bool IsFeasible() { + // First the flip must be topologically correct. if(!vcg::face::CheckFlipEdge(*this->_pos.F(), this->_pos.E())) return false; + // then the angle between the involved normals must be greater??? if (math::ToDeg(Angle(this->_pos.FFlip()->cN(), this->_pos.F()->cN()) ) <= this->CoplanarAngleThresholdDeg() ) return false; @@ -294,7 +296,13 @@ public: _cv3 = curveval(cd3); float cafter = _cv0 + _cv1 + _cv2 + _cv3; + // The priority of an edge flip is **how much we lower the overall curvature**. + // If after the flip the sum of the curvature is decreased it is a good move; + // good flips have: cafter < cbefore + // Since the local optimization is designed to make the miniumum cost move we put inside + // negative values (the more negative the better). this->_priority = (cafter - cbefore); + //qDebug("computed curvature change, %f->%f (priority = %f)", cbefore,cafter,this->_priority); return this->_priority; } @@ -304,8 +312,8 @@ public: CURVEVAL curveval; heap.clear(); - // comuputing edge flip priority require non normalized vertex normals - vcg::tri::UpdateNormals::PerVertex(m); + // comuputing edge flip priority require non normalized vertex normals AND non normalized face normals. + vcg::tri::UpdateNormals::PerVertexPerFace(m); VertexIterator vi; for (vi = m.vert.begin(); vi != m.vert.end(); ++vi) diff --git a/src/fgt/filter_trioptimize/filter_trioptimize.cpp b/src/fgt/filter_trioptimize/filter_trioptimize.cpp index 423e63ec2..ed0e29a11 100644 --- a/src/fgt/filter_trioptimize/filter_trioptimize.cpp +++ b/src/fgt/filter_trioptimize/filter_trioptimize.cpp @@ -195,9 +195,9 @@ void TriOptimizePlugin::initParameterSet(QAction *action, MeshModel &m, { if (ID(action) == FP_CURVATURE_EDGE_FLIP) { parlst.addBool("selection", m.cm.sfn > 0, tr("Update selection"), tr("Apply edge flip optimization on selected faces only")); - parlst.addAbsPerc("pthreshold", 1.0f, 0.1f, 90.0f, - tr("Planar threshold"), - tr("angle threshold for planar faces (degrees)")); + parlst.addFloat("pthreshold", 1.0f, + tr("Angle Thr (deg)"), + tr("To avoid excessive flipping/swapping we consider only couple of faces with a significant diedral angle (e.g. greater than the indicated threshold). ")); QStringList cmetrics; cmetrics.push_back("mean"); @@ -218,9 +218,9 @@ void TriOptimizePlugin::initParameterSet(QAction *action, MeshModel &m, if (ID(action) == FP_PLANAR_EDGE_FLIP) { parlst.addBool("selection", m.cm.sfn > 0, tr("Update selection"), tr("Apply edge flip optimization on selected faces only")); - parlst.addAbsPerc("pthreshold", 1.0f, 0.1f, 90.0f, - tr("Planar threshold"), - tr("angle threshold for planar faces (degrees)")); + parlst.addFloat("pthreshold", 1.0f, + tr("Planar threshold (deg)"), + tr("angle threshold for planar faces (degrees)")); QStringList pmetrics; pmetrics.push_back("area/max side"); @@ -245,7 +245,7 @@ void TriOptimizePlugin::initParameterSet(QAction *action, MeshModel &m, if (ID(action) == FP_NEAR_LAPLACIAN_SMOOTH) { parlst.addBool("selection", false, tr("Update selection"), tr("Apply laplacian smooth on selected faces only")); - parlst.addFloat("AngleDeg", 0.0001f, tr("Max Normal Dev (deg)"), tr("maximum mean normal angle displacement (degrees) from old to new faces")); + parlst.addFloat("AngleDeg", 0.5f, tr("Max Normal Dev (deg)"), tr("maximum mean normal angle displacement (degrees) from old to new faces")); parlst.addInt("iterations", 1, "Iterations", tr("number of laplacian smooth iterations in every run")); } } @@ -258,12 +258,7 @@ bool TriOptimizePlugin::applyFilter(QAction *filter, MeshModel &m, { float limit = -std::numeric_limits::epsilon(); - if (ID(filter) == FP_CURVATURE_EDGE_FLIP) { - if ( !tri::Clean::IsTwoManifoldFace(m.cm) ) { - errorMessage = "Mesh has some not 2-manifold faces, edge flips requires manifoldness"; - return false; // can't continue, mesh can't be processed - } - + if (ID(filter) == FP_CURVATURE_EDGE_FLIP) { int delvert = tri::Clean::RemoveUnreferencedVertex(m.cm); if (delvert) Log(GLLogStream::FILTER, @@ -275,8 +270,12 @@ bool TriOptimizePlugin::applyFilter(QAction *filter, MeshModel &m, vcg::tri::UpdateTopology::FaceFace(m.cm); vcg::tri::UpdateFlags::FaceBorderFromFF(m.cm); + if ( !tri::Clean::IsTwoManifoldFace(m.cm) ) { + errorMessage = "Mesh has some not 2-manifold faces, edge flips requires manifoldness"; + return false; // can't continue, mesh can't be processed + } vcg::LocalOptimization optimiz(m.cm); - float pthr = par.getAbsPerc("pthreshold"); + float pthr = par.getFloat("pthreshold"); time_t start = clock(); if (par.getBool("selection")) { @@ -309,6 +308,7 @@ bool TriOptimizePlugin::applyFilter(QAction *filter, MeshModel &m, // stop when flips become harmful optimiz.SetTargetMetric(limit); + //optimiz.SetTargetOperations(10); optimiz.DoOptimization(); optimiz.h.clear(); @@ -328,7 +328,7 @@ bool TriOptimizePlugin::applyFilter(QAction *filter, MeshModel &m, vcg::tri::UpdateFlags::FaceBorderFromFF(m.cm); vcg::LocalOptimization optimiz(m.cm); - float pthr = par.getAbsPerc("pthreshold"); + float pthr = par.getFloat("pthreshold"); time_t start = clock(); @@ -378,7 +378,7 @@ bool TriOptimizePlugin::applyFilter(QAction *filter, MeshModel &m, int iternum = par.getInt("iterations"); float dthreshold = par.getFloat("AngleDeg"); - tri::Smooth::VertexCoordPlanarLaplacian(m.cm, iternum, dthreshold, selection,cb); + tri::Smooth::VertexCoordPlanarLaplacian(m.cm, iternum, math::ToRad(dthreshold), selection,cb); tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); }