Moved gaussian and mean curvature functions into color_curvature.h

This commit is contained in:
Paolo Cignoni cignoni 2006-01-13 16:24:16 +00:00
parent 2aecf9105a
commit 9780b2bd8d
3 changed files with 299 additions and 239 deletions

View File

@ -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 <iostream>
#include <QtGlobal>
#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/math/histogram.h>
#include "../../meshlab/LogStream.h"
namespace vcg
{
template<class MESH_TYPE> 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<float> histo;
float minQ=std::numeric_limits<float>::max(),maxQ = -std::numeric_limits<float>::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<CFaceO>((*fi)) / 3.0;
(*fi).V(1)->Q() += vcg::Area<CFaceO>((*fi)) / 3.0;
(*fi).V(2)->Q() += vcg::Area<CFaceO>((*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<float>::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<class MESH_TYPE> 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<float> histo;
float minQ=std::numeric_limits<float>::max(),maxQ = -std::numeric_limits<float>::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<CFaceO>((*fi)) / 3.0;
(*fi).V(1)->Q() += vcg::Area<CFaceO>((*fi)) / 3.0;
(*fi).V(2)->Q() += vcg::Area<CFaceO>((*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<float>::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

View File

@ -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 <vcg/complex/trimesh/clean.h>
#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<CFaceO>((*fi)) / 3.0;
(*fi).V(1)->Q() += vcg::Area<CFaceO>((*fi)) / 3.0;
(*fi).V(2)->Q() += vcg::Area<CFaceO>((*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<float> histo;
float minQ=std::numeric_limits<float>::max(),maxQ = -std::numeric_limits<float>::max();
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi,++i) if(!(*vi).IsD())
{
if(area[i]<=std::numeric_limits<float>::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<CFaceO>((*fi)) / 3.0;
(*fi).V(1)->Q() += vcg::Area<CFaceO>((*fi)) / 3.0;
(*fi).V(2)->Q() += vcg::Area<CFaceO>((*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<float> histo;
float minQ=std::numeric_limits<float>::max(),maxQ = -std::numeric_limits<float>::max();
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi,++i) if(!(*vi).IsD())
{
if(area[i]<=std::numeric_limits<float>::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<QAction *> 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<CMeshO>(m.cm, log);
vcg::tri::UpdateColor<CMeshO>::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<CMeshO>(m.cm, log);
vcg::tri::UpdateColor<CMeshO>::VertexQuality(m.cm);
rm.colorMode = GLW::CMPerVert;
return;

View File

@ -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 <QActionGroup>
#include <QList>
#include <math.h>
#include <meshlab/meshmodel.h>
#include <meshlab/interfaces.h>
#include <meshlab/glarea.h>