From 9780b2bd8d46d468cfa955d03b7d633b6fdb7fa3 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Fri, 13 Jan 2006 16:24:16 +0000 Subject: [PATCH] Moved gaussian and mean curvature functions into color_curvature.h --- .../meshcolorize/color_curvature.h | 265 ++++++++++++++++++ .../meshcolorize/meshcolorize.cpp | 226 +-------------- .../meshcolorize/meshcolorize.h | 47 ++-- 3 files changed, 299 insertions(+), 239 deletions(-) create mode 100644 src/meshlabplugins/meshcolorize/color_curvature.h diff --git a/src/meshlabplugins/meshcolorize/color_curvature.h b/src/meshlabplugins/meshcolorize/color_curvature.h new file mode 100644 index 000000000..a89417c49 --- /dev/null +++ b/src/meshlabplugins/meshcolorize/color_curvature.h @@ -0,0 +1,265 @@ +/**************************************************************************** + * 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/01/13 16:24:16 vannini +Moved gaussian and mean curvature functions into color_curvature.h + + +****************************************************************************/ + +#ifndef EXTRACOLOR_CURVATURE_H +#define EXTRACOLOR_CURVATURE_H + +#include +#include +#include +#include +#include +#include +#include + +#include "../../meshlab/LogStream.h" + +namespace vcg +{ + template void ColorGaussian(MESH_TYPE &m, GLLogStream *log) + { + assert(m.HasFFTopology()); + + float *area; + int i; + float area0, area1, area2; + float angle0, angle1, angle2; + + float histo_frac = 0.1f; + int histo_range=100000; + vcg::Histogram histo; + float minQ=std::numeric_limits::max(),maxQ = -std::numeric_limits::max(); + + typename MESH_TYPE::VertexIterator vi; + typename MESH_TYPE::FaceIterator fi; + + area = new float[m.vn]; + + for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = 0.0; + + // AreaMix + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + { + // angles + angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) )); + angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) )); + angle2 = M_PI-(angle0+angle1); + + if((angle0 < M_PI/2) || (angle1 < M_PI/2) || (angle2 < M_PI/2)) // triangolo non ottuso + { + float e01 = SquaredDistance( (*fi).V(1)->P() , (*fi).V(0)->P() ); + float e12 = SquaredDistance( (*fi).V(2)->P() , (*fi).V(1)->P() ); + float e20 = SquaredDistance( (*fi).V(0)->P() , (*fi).V(2)->P() ); + + // voronoi area v[0] + area0 = ( e01*(1.0/tan(angle2)) + e20*(1.0/tan(angle1)) ) /8; + // voronoi area v[1] + area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) ) /8; + // voronoi area v[2] + area2 = ( e20*(1.0/tan(angle1)) + e20*(1.0/tan(angle0)) ) /8; + + (*fi).V(0)->Q() += area0; + (*fi).V(1)->Q() += area1; + (*fi).V(2)->Q() += area2; + } + else // triangolo ottuso + { + (*fi).V(0)->Q() += vcg::Area((*fi)) / 3.0; + (*fi).V(1)->Q() += vcg::Area((*fi)) / 3.0; + (*fi).V(2)->Q() += vcg::Area((*fi)) / 3.0; + } + } + + i = 0; + for(vi=m.vert.begin();vi!=m.vert.end();++vi,++i) if(!(*vi).IsD()) + { + area[i] = (*vi).Q(); + (*vi).Q() = (float)(2.0 * M_PI); + } + + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + { + float angle0 = math::Abs(Angle((*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0))); + float angle1 = math::Abs(Angle((*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1))); + float angle2 = M_PI-(angle0+angle1); + + (*fi).V(0)->Q() -= angle0; + (*fi).V(1)->Q() -= angle1; + (*fi).V(2)->Q() -= angle2; + } + + i=0; + for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi,++i) if(!(*vi).IsD()) + { + if(area[i]<=std::numeric_limits::epsilon()) + (*vi).Q() = 0; + else + (*vi).Q() /= area[i]; + + if ((*vi).Q() < minQ) minQ = (*vi).Q(); + if ((*vi).Q() > maxQ) maxQ = (*vi).Q(); + } + + histo.SetRange(minQ, maxQ, histo_range); + + for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) + histo.Add((*vi).Q()); + + minQ = histo.Percentile(histo_frac); + maxQ = histo.Percentile(1.0f-histo_frac); + + for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) + (*vi).Q() = math::Clamp((*vi).Q(), minQ, maxQ); + + if (log) + log->Log(GLLogStream::Info, "Mean Curvature: minQ=%f maxQ=%f range=%d", minQ, maxQ, histo_range); + + delete[] area; + + } + + template void ColorMean(MESH_TYPE &m, GLLogStream *log) + { + assert(m.HasFFTopology()); + + float *area; + int i; + float area0, area1, area2; + float angle0, angle1, angle2; + + float histo_frac = 0.1f; + int histo_range=100000; + vcg::Histogram histo; + float minQ=std::numeric_limits::max(),maxQ = -std::numeric_limits::max(); + + typename MESH_TYPE::VertexIterator vi; + typename MESH_TYPE::FaceIterator fi; + + area = new float[m.vn]; + + for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = 0.0; + + // AreaMix + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + { + // angles + angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) )); + angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) )); + angle2 = M_PI-(angle0+angle1); + + if((angle0 < M_PI/2) || (angle1 < M_PI/2) || (angle2 < M_PI/2)) // triangolo non ottuso + { + float e01 = SquaredDistance( (*fi).V(1)->P() , (*fi).V(0)->P() ); + float e12 = SquaredDistance( (*fi).V(2)->P() , (*fi).V(1)->P() ); + float e20 = SquaredDistance( (*fi).V(0)->P() , (*fi).V(2)->P() ); + + // voronoi area v[0] + area0 = ( e01*(1.0/tan(angle2)) + e20*(1.0/tan(angle1)) ) /8; + // voronoi area v[1] + area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) ) /8; + // voronoi area v[2] + area2 = ( e20*(1.0/tan(angle1)) + e20*(1.0/tan(angle0)) ) /8; + + (*fi).V(0)->Q() += area0; + (*fi).V(1)->Q() += area1; + (*fi).V(2)->Q() += area2; + } + else // triangolo ottuso + { + (*fi).V(0)->Q() += vcg::Area((*fi)) / 3.0; + (*fi).V(1)->Q() += vcg::Area((*fi)) / 3.0; + (*fi).V(2)->Q() += vcg::Area((*fi)) / 3.0; + } + } + + i = 0; + for(vi=m.vert.begin();vi!=m.vert.end();++vi,++i) if(!(*vi).IsD()) + { + area[i] = (*vi).Q(); + (*vi).Q() = 0; + } + + for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + { + + angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) )); + angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) )); + angle2 = M_PI-(angle0+angle1); + + float e01 = Distance( (*fi).V(1)->P() , (*fi).V(0)->P() ); + float e12 = Distance( (*fi).V(2)->P() , (*fi).V(1)->P() ); + float e20 = Distance( (*fi).V(0)->P() , (*fi).V(2)->P() ); + + area0 = ( e01*(1.0/tan(angle2)) + e20*(1.0/tan(angle1)) )/2; + area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) )/2; + area2 = ( e20*(1.0/tan(angle1)) + e20*(1.0/tan(angle0)) )/2; + + (*fi).V(0)->Q() += area0; + (*fi).V(1)->Q() += area1; + (*fi).V(2)->Q() += area2; + + } + + i=0; + for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi,++i) if(!(*vi).IsD()) + { + if(area[i]<=std::numeric_limits::epsilon()) + (*vi).Q() = 0; + else + (*vi).Q() /= area[i]; + + if ((*vi).Q() < minQ) minQ = (*vi).Q(); + if ((*vi).Q() > maxQ) maxQ = (*vi).Q(); + } + + histo.SetRange(minQ, maxQ, histo_range); + + for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) + histo.Add((*vi).Q()); + + minQ = histo.Percentile(histo_frac); + maxQ = histo.Percentile(1.0f-histo_frac); + + for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) + (*vi).Q() = math::Clamp((*vi).Q(), minQ, maxQ); + + if (log) + log->Log(GLLogStream::Info, "Mean Curvature: minQ=%f maxQ=%f range=%d", minQ, maxQ, histo_range); + + delete[] area; + + } + +} + +#endif \ No newline at end of file diff --git a/src/meshlabplugins/meshcolorize/meshcolorize.cpp b/src/meshlabplugins/meshcolorize/meshcolorize.cpp index c612f751d..7d7c804e0 100644 --- a/src/meshlabplugins/meshcolorize/meshcolorize.cpp +++ b/src/meshlabplugins/meshcolorize/meshcolorize.cpp @@ -23,6 +23,9 @@ /**************************************************************************** History $Log$ +Revision 1.15 2006/01/13 16:24:16 vannini +Moved gaussian and mean curvature functions into color_curvature.h + Revision 1.14 2006/01/13 15:22:04 vannini colorize: -colorize nonmanifold now sets colorPerVertex mode @@ -68,7 +71,7 @@ Added copyright info #include #include "meshcolorize.h" #include "color_manifold.h" -#include "../../meshlab/LogStream.h" +#include "color_curvature.h" using namespace vcg; @@ -140,230 +143,13 @@ const PluginInfo &ExtraMeshColorizePlugin::Info() return ai; } -static void Gaussian(CMeshO &m, GLLogStream *log){ - - assert(m.HasPerVertexQuality()); - - CMeshO::VertexIterator vi; // iteratore vertice - CMeshO::FaceIterator fi; // iteratore facce - float *area; // areamix vector - int i; // index - float area0, area1, area2; - float angle0, angle1, angle2; - - //--- Initialization - area = new float[m.vn]; - - //reset the values to 0 - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = 0.0; - - //--- compute Areamix - for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) - { - // angles - angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) )); - angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) )); - angle2 = M_PI-(angle0+angle1); - - if((angle0 < M_PI/2) || (angle1 < M_PI/2) || (angle2 < M_PI/2)) // triangolo non ottuso - { - float e01 = SquaredDistance( (*fi).V(1)->P() , (*fi).V(0)->P() ); - float e12 = SquaredDistance( (*fi).V(2)->P() , (*fi).V(1)->P() ); - float e20 = SquaredDistance( (*fi).V(0)->P() , (*fi).V(2)->P() ); - - // voronoi area v[0] - area0 = ( e01*(1.0/tan(angle2)) + e20*(1.0/tan(angle1)) ) /8; - // voronoi area v[1] - area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) ) /8; - // voronoi area v[2] - area2 = ( e20*(1.0/tan(angle1)) + e20*(1.0/tan(angle0)) ) /8; - - (*fi).V(0)->Q() += area0; - (*fi).V(1)->Q() += area1; - (*fi).V(2)->Q() += area2; - } - else // triangolo ottuso - { - (*fi).V(0)->Q() += vcg::Area((*fi)) / 3.0; - (*fi).V(1)->Q() += vcg::Area((*fi)) / 3.0; - (*fi).V(2)->Q() += vcg::Area((*fi)) / 3.0; - } - } - - i = 0; - for(vi=m.vert.begin();vi!=m.vert.end();++vi,++i) if(!(*vi).IsD()) - { - area[i] = (*vi).Q(); - (*vi).Q() = (float)(2.0 * M_PI); - } - - for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) - { - float angle0 = math::Abs(Angle((*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0))); - float angle1 = math::Abs(Angle((*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1))); - float angle2 = M_PI-(angle0+angle1); - - (*fi).V(0)->Q() -= angle0; - (*fi).V(1)->Q() -= angle1; - (*fi).V(2)->Q() -= angle2; - } - - i=0; - float histo_frac = 0.1f; - int histo_range=100000; - vcg::Histogram histo; - float minQ=std::numeric_limits::max(),maxQ = -std::numeric_limits::max(); - for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi,++i) if(!(*vi).IsD()) - { - if(area[i]<=std::numeric_limits::epsilon()) - (*vi).Q() = 0; - else - (*vi).Q() /= area[i]; - - if ((*vi).Q() < minQ) minQ = (*vi).Q(); - if ((*vi).Q() > maxQ) maxQ = (*vi).Q(); - } - - histo.SetRange(minQ, maxQ, histo_range); - - for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) - histo.Add((*vi).Q()); - - minQ = histo.Percentile(histo_frac); - maxQ = histo.Percentile(1.0f-histo_frac); - - for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) - (*vi).Q() = math::Clamp((*vi).Q(), minQ, maxQ); - - if (log) - log->Log(GLLogStream::Info, "Mean Curvature: minQ=%f maxQ=%f range=%d", minQ, maxQ, histo_range); - - delete[] area; - -} - -static void Mean(CMeshO &m, GLLogStream *log){ - - assert(m.HasPerVertexQuality()); - - CMeshO::VertexIterator vi; // iteratore vertice - CMeshO::FaceIterator fi; // iteratore facce - float *area; // areamix vector - int i; // index - float area0, area1, area2; - float angle0, angle1, angle2; - - //--- Initialization - area = new float[m.vn]; - - //reset the values to 0 - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = 0.0; - - //--- compute Areamix - for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) - { - // angles - angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) )); - angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) )); - angle2 = M_PI-(angle0+angle1); - - if((angle0 < M_PI/2) || (angle1 < M_PI/2) || (angle2 < M_PI/2)) // triangolo non ottuso - { - float e01 = SquaredDistance( (*fi).V(1)->P() , (*fi).V(0)->P() ); - float e12 = SquaredDistance( (*fi).V(2)->P() , (*fi).V(1)->P() ); - float e20 = SquaredDistance( (*fi).V(0)->P() , (*fi).V(2)->P() ); - - // voronoi area v[0] - area0 = ( e01*(1.0/tan(angle2)) + e20*(1.0/tan(angle1)) ) /8; - // voronoi area v[1] - area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) ) /8; - // voronoi area v[2] - area2 = ( e20*(1.0/tan(angle1)) + e20*(1.0/tan(angle0)) ) /8; - - (*fi).V(0)->Q() += area0; - (*fi).V(1)->Q() += area1; - (*fi).V(2)->Q() += area2; - } - else // triangolo ottuso - { - (*fi).V(0)->Q() += vcg::Area((*fi)) / 3.0; - (*fi).V(1)->Q() += vcg::Area((*fi)) / 3.0; - (*fi).V(2)->Q() += vcg::Area((*fi)) / 3.0; - } - } - - i = 0; - for(vi=m.vert.begin();vi!=m.vert.end();++vi,++i) if(!(*vi).IsD()) - { - area[i] = (*vi).Q(); - (*vi).Q() = 0; - } - - for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) - { - - angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) )); - angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) )); - angle2 = M_PI-(angle0+angle1); - - float e01 = Distance( (*fi).V(1)->P() , (*fi).V(0)->P() ); - float e12 = Distance( (*fi).V(2)->P() , (*fi).V(1)->P() ); - float e20 = Distance( (*fi).V(0)->P() , (*fi).V(2)->P() ); - - area0 = ( e01*(1.0/tan(angle2)) + e20*(1.0/tan(angle1)) )/2; - area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) )/2; - area2 = ( e20*(1.0/tan(angle1)) + e20*(1.0/tan(angle0)) )/2; - - (*fi).V(0)->Q() += area0; - (*fi).V(1)->Q() += area1; - (*fi).V(2)->Q() += area2; - - } - - - i=0; - float histo_frac = 0.1f; - int histo_range=100000; - vcg::Histogram histo; - float minQ=std::numeric_limits::max(),maxQ = -std::numeric_limits::max(); - for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi,++i) if(!(*vi).IsD()) - { - if(area[i]<=std::numeric_limits::epsilon()) - (*vi).Q() = 0; - else - (*vi).Q() /= area[i]; - - if ((*vi).Q() < minQ) minQ = (*vi).Q(); - if ((*vi).Q() > maxQ) maxQ = (*vi).Q(); - } - - histo.SetRange(minQ, maxQ, histo_range); - - for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) - histo.Add((*vi).Q()); - - minQ = histo.Percentile(histo_frac); - maxQ = histo.Percentile(1.0f-histo_frac); - - for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) - (*vi).Q() = math::Clamp((*vi).Q(), minQ, maxQ); - - if (log) - log->Log(GLLogStream::Info, "Mean Curvature: minQ=%f maxQ=%f range=%d", minQ, maxQ, histo_range); - - delete[] area; -} - - QList ExtraMeshColorizePlugin::actions() const { return actionList; } void ExtraMeshColorizePlugin::Compute(QAction * mode, MeshModel &m, RenderMode &rm, GLArea *parent){ if(mode->text() == ST(CP_GAUSSIAN)) { - Gaussian(m.cm, log); + ColorGaussian(m.cm, log); vcg::tri::UpdateColor::VertexQuality(m.cm); rm.colorMode = GLW::CMPerVert; return; @@ -371,7 +157,7 @@ void ExtraMeshColorizePlugin::Compute(QAction * mode, MeshModel &m, RenderMode & if(mode->text() == ST(CP_MEAN)) { - Mean(m.cm, log); + ColorMean(m.cm, log); vcg::tri::UpdateColor::VertexQuality(m.cm); rm.colorMode = GLW::CMPerVert; return; diff --git a/src/meshlabplugins/meshcolorize/meshcolorize.h b/src/meshlabplugins/meshcolorize/meshcolorize.h index 22cd720ca..61214b76b 100644 --- a/src/meshlabplugins/meshcolorize/meshcolorize.h +++ b/src/meshlabplugins/meshcolorize/meshcolorize.h @@ -1,22 +1,32 @@ /**************************************************************************** -** -** Copyright (C) 2005-2005 Trolltech AS. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software. -** -** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for -** information about Qt Commercial License Agreements. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** + * 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.12 2006/01/13 16:24:16 vannini +Moved gaussian and mean curvature functions into color_curvature.h + + ****************************************************************************/ #ifndef EXTRACOLORIZEPLUGIN_H @@ -27,7 +37,6 @@ #include #include -#include #include #include #include