mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-18 18:44:39 +00:00
util.h\util.cpp:
- Optimized relative-absolute and absolute-relative values conversion functions qualitymapper.cpp\qualitymapper.cpp: - Fixed bug about quality representation. Now the quality is represented correctly in the histogram every time the dialog is built and shown. - Added call to transfer function drawing (stub) qualitymapperdialog.h: - Added method for transfer function drawing (stub) - Added some optimizations to drawCartesianChartBasics method to make it completely parametric (view indipendent) (stub yet) - Other minor changes transferfunction.h\transferfunction.h: - added a new overloaded constructor to build the transfer function directly from a TF file (stub) - Some optimizations applied - Other minor changes
This commit is contained in:
parent
8e34bdd142
commit
bfd0cd38f3
@ -3,3 +3,4 @@
|
||||
19.53 16/01/2008 aggiungere alla TF_KEY un campo per capire "a quale punto (su o giù)" è attaccata la linea del grafico!
|
||||
16.51 18/01/2008 valutare il caso in cui una chiave sia legata sia "a sinistra" che "a destra" ad altre chavi. Adeguare la struttura dati di conseguenza
|
||||
16.51 18/01/2008 collassare i 2 (eventuali) nodi una chiave posta in 0.0 o 1.0 ad un solo nodo (quello di giunzione)
|
||||
23.03 19/01/2008 implementare la creazione di una Transfer Function partendo da un file csv e l'esportazione nello stesso formato
|
||||
@ -90,12 +90,10 @@ void QualityMapperPlugin::Decorate(QAction * /*ac*/, MeshModel &m, GLArea * gla)
|
||||
{
|
||||
}
|
||||
|
||||
void QualityMapperPlugin::StartEdit(QAction * /*mode*/, MeshModel &m, GLArea *gla )
|
||||
void QualityMapperPlugin::StartEdit(QAction *mode, MeshModel &m, GLArea *gla )
|
||||
{
|
||||
// gla->setCursor(QCursor(QPixmap(":/images/cur_info.png"),1,1));
|
||||
|
||||
|
||||
|
||||
if(_qualityMapperDialog==0)
|
||||
{
|
||||
//_qualityMapperDialog=new _qualityMapperDialog(gla->parentWidget()->parentWidget());
|
||||
@ -108,26 +106,46 @@ void QualityMapperPlugin::StartEdit(QAction * /*mode*/, MeshModel &m, GLArea *gl
|
||||
// connect(_qualityMapperDialog->ui.glueHereAllButton,SIGNAL(clicked()),this,SLOT(glueHereAll()));
|
||||
// connect(_qualityMapperDialog->ui.falseColorCB, SIGNAL(clicked(bool)) , _gla->window(), SLOT(updateGL() ) );
|
||||
|
||||
Histogramf h;
|
||||
QualityMapperPlugin::ComputePerVertexQualityHistogram(m.cm, h, 100);
|
||||
|
||||
Frange mmmq(tri::Stat<CMeshO>::ComputePerVertexQualityMinMax(m.cm));
|
||||
_qmSettings.meshMinQ = mmmq.minV;
|
||||
_qmSettings.meshMaxQ = mmmq.maxV;
|
||||
_qmSettings.meshMidQ = (mmmq.minV+mmmq.maxV)/2;
|
||||
// Histogramf h;
|
||||
|
||||
// _qmSettings.histoMinQ = H.Percentile(_qmSettings.percentile/100);
|
||||
// _qmSettings.histoMaxQ = H.Percentile(1.0f-_qmSettings.percentile/100);
|
||||
|
||||
_qualityMapperDialog->setValues(_qmSettings);
|
||||
_qualityMapperDialog->initEqualizerHistogram(&h);
|
||||
|
||||
}
|
||||
|
||||
//building up histogram...
|
||||
QualityMapperPlugin::ComputePerVertexQualityHistogram(m.cm, _histogram, 100);
|
||||
Frange mmmq(tri::Stat<CMeshO>::ComputePerVertexQualityMinMax(m.cm));
|
||||
//...histogram built
|
||||
|
||||
//setting and applying settings to dialog (??) MAL
|
||||
_qmSettings.meshMinQ = mmmq.minV;
|
||||
_qmSettings.meshMaxQ = mmmq.maxV;
|
||||
_qmSettings.meshMidQ = (mmmq.minV+mmmq.maxV)/2;
|
||||
_qualityMapperDialog->setValues(_qmSettings);
|
||||
|
||||
//drawing histogram in dialog(??) MAL
|
||||
_qualityMapperDialog->initEqualizerHistogram(_histogram);
|
||||
|
||||
//drawing transferFunction
|
||||
_qualityMapperDialog->drawTransferFunction( _transfer_function );
|
||||
|
||||
// _qualityMapperDialog->edit=this;
|
||||
// _qualityMapperDialog->setTree(& meshTree, meshTree.nodeList.front());
|
||||
|
||||
//dialog ready to be displayed. Show it now!
|
||||
_qualityMapperDialog->show();
|
||||
}
|
||||
|
||||
void QualityMapperPlugin::EndEdit(QAction * , MeshModel &, GLArea * )
|
||||
{
|
||||
if ( _qualityMapperDialog )
|
||||
{
|
||||
delete _qualityMapperDialog;
|
||||
_qualityMapperDialog = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QualityMapperPlugin::ComputePerVertexQualityHistogram( CMeshO & m, Histogramf &h, int bins=10000) // V1.0
|
||||
{
|
||||
h.Clear();
|
||||
|
||||
@ -42,12 +42,14 @@ Beginning
|
||||
#include <meshlab/glarea.h>
|
||||
|
||||
//#include <vcg/math/base.h>
|
||||
#include <vcg/math/histogram.h>
|
||||
//#include <vcg/space/triangle3.h>
|
||||
#include <vcg/complex/trimesh/update/color.h> //<-- contains VertexQuality method
|
||||
|
||||
#include "qualitymapperdialog.h"
|
||||
|
||||
#include <vcg/math/histogram.h>
|
||||
#include "transferfunction.h"
|
||||
|
||||
|
||||
class QualityMapperPlugin : public QObject, public MeshEditInterface
|
||||
{
|
||||
@ -58,6 +60,8 @@ private:
|
||||
QualityMapperDialog *_qualityMapperDialog;
|
||||
QList <QAction *> actionList;
|
||||
Histogramf _histogram;
|
||||
TransferFunction _transfer_function;
|
||||
|
||||
QualityMapperSettings _qmSettings;
|
||||
|
||||
public:
|
||||
@ -72,7 +76,7 @@ public:
|
||||
// Called when the user press the first time the button
|
||||
void StartEdit (QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
// Called when the user press the second time the button
|
||||
void EndEdit (QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){};
|
||||
void EndEdit (QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
void Decorate (QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
void mousePressEvent (QAction *, QMouseEvent *, MeshModel &, GLArea * ) {};
|
||||
void mouseMoveEvent (QAction *, QMouseEvent *, MeshModel &, GLArea * ) {};
|
||||
@ -81,8 +85,7 @@ public:
|
||||
QPoint cur;
|
||||
bool haveToPick;
|
||||
|
||||
void ComputePerVertexQualityHistogram( CMeshO & m, Histogramf &h, int bins);
|
||||
|
||||
void ComputePerVertexQualityHistogram( CMeshO & m, Histogramf &h, int bins);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
|
||||
//#include <vcg/math/histogram.h>
|
||||
|
||||
QualityMapperDialog::QualityMapperDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
@ -50,13 +49,63 @@ QualityMapperSettings QualityMapperDialog::getValues()
|
||||
return _settings;
|
||||
}
|
||||
|
||||
void QualityMapperDialog::initEqualizerHistogram(vcg::Histogramf *h)
|
||||
|
||||
void QualityMapperDialog::drawCartesianChartBasics(QGraphicsScene& scene, QGraphicsView *view)
|
||||
{
|
||||
int width = /*300;*/view->width();
|
||||
int height = /*200;*/view->height();
|
||||
|
||||
border = 5;
|
||||
chartRectangleThickness = 2;
|
||||
leftBorder = border;
|
||||
rightBorder = width - border;
|
||||
upperBorder = border;
|
||||
lowerBorderForCartesians = height - (int)(border * 3);
|
||||
|
||||
// Create a LightBlue background
|
||||
//_equalizerScene.addRect(chartRectangleThickness, chartRectangleThickness, width - (2 * chartRectangleThickness), height - (2 * chartRectangleThickness), QPen(), QBrush(QColor(230, 230, 255), Qt::SolidPattern));
|
||||
|
||||
//drawing chart title
|
||||
//this.writeString(g, title, titleLabelSize, Color.Black, Positions.North);
|
||||
|
||||
//drawing scale values on X and Y axis
|
||||
//this.drawXYValuesScale(chartType, g, maxRoundedY, vals, xyLabelsSize);
|
||||
|
||||
QPen p( Qt::black, 2 );
|
||||
|
||||
//drawing axis
|
||||
//x axis
|
||||
scene.addLine(leftBorder, lowerBorderForCartesians, rightBorder, lowerBorderForCartesians, p );
|
||||
//y axis
|
||||
scene.addLine(leftBorder, upperBorder, leftBorder, lowerBorderForCartesians, p );
|
||||
|
||||
/*
|
||||
//drawing axis labels
|
||||
//drawing X label
|
||||
this.writeString(g, header.xLabel, xyLabelsSize, Color.Black, Positions.South);
|
||||
//drawing Y label
|
||||
String yLabel = header.yLabel;
|
||||
//if the y label represent a delay, the time unit is added to the string (min.) [MINUTE]
|
||||
if ((yLabel.ToLower()).Contains("delay"))
|
||||
yLabel += " min.";
|
||||
this.writeString(g, yLabel, xyLabelsSize, Color.Black, Positions.West);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//il nome non mi sembra giusto. Questo dovrebbe essere piuttosto drawHistogram
|
||||
//il calcolo di miY e maxY mi pare sia superflo. Se non erro già la classe histogram li ha dentro (cmq mi pare vengano calcolati in ComputePerVertexQualityMinMax)
|
||||
//se proprio vanno calcolati minY e maxY, maxY può essere inizializzato a -1 (pedantic mode)
|
||||
//_equalizerScene dovrebbe chiamarsi in realtà histogramScene
|
||||
//l'histogram e la transfer function potrebbero diventare attributi di questa classe? valutare l'impatto.
|
||||
//in generale il codice di questo metodo va ripulito un po'...
|
||||
void QualityMapperDialog::initEqualizerHistogram( Histogramf& h )
|
||||
{
|
||||
//_equalizerScene();
|
||||
_equalizerScene.addText("Hello World!");
|
||||
|
||||
int width = 300;//ui.equalizerGraphicsView->width();
|
||||
int height = 200;//ui.equalizerGraphicsView->height();
|
||||
int width = /*300;*/ui.equalizerGraphicsView->width();
|
||||
int height = /*200;*/ui.equalizerGraphicsView->height();
|
||||
|
||||
border = 5;
|
||||
chartRectangleThickness = 2;
|
||||
@ -70,24 +119,24 @@ void QualityMapperDialog::initEqualizerHistogram(vcg::Histogramf *h)
|
||||
int yScaleStep = 5;
|
||||
|
||||
|
||||
float dX = (float)chartWidth / (float)h->n;
|
||||
float dY = (float)chartHeightForCartesians / (float)h->n;
|
||||
float dX = (float)chartWidth / (float)h.n;
|
||||
float dY = (float)chartHeightForCartesians / (float)h.n;
|
||||
|
||||
//float maxX = float.MinValue;
|
||||
int maxY = std::numeric_limits<int>::min();;
|
||||
int minY = std::numeric_limits<int>::max();;
|
||||
int maxY = std::numeric_limits<int>::min();
|
||||
int minY = std::numeric_limits<int>::max();
|
||||
|
||||
/*std::vector<float>::iterator it;
|
||||
for (it= h->R.begin(); it != h->R.end(); it++)*/
|
||||
|
||||
//processing minX, maxX, minY and maxY values
|
||||
for (int i=0; i<h->n; i++)
|
||||
for (int i=0; i<h.n; i++)
|
||||
{
|
||||
if (h->H[i] > maxY)
|
||||
maxY = h->H[i];
|
||||
if (h.H[i] > maxY)
|
||||
maxY = h.H[i];
|
||||
|
||||
if (h->H[i] < minY)
|
||||
minY = h->H[i];
|
||||
if (h.H[i] < minY)
|
||||
minY = h.H[i];
|
||||
}
|
||||
|
||||
int maxRoundedY = (int)(maxY + yScaleStep - (maxY % yScaleStep)); //the highest value represented in the y values scale
|
||||
@ -97,7 +146,7 @@ void QualityMapperDialog::initEqualizerHistogram(vcg::Histogramf *h)
|
||||
float barSeparator = dX / 5.0F; //processing space between consecutive bars of the histogram bars (1\5 of dX)
|
||||
|
||||
QPen drawingPen(Qt::black);
|
||||
QBrush drawingBrush (QColor(32,32,32),Qt::SolidPattern);
|
||||
QBrush drawingBrush (QColor(32, 32, 32),Qt::SolidPattern);
|
||||
|
||||
QPointF startBarPt;
|
||||
QSizeF barSize;
|
||||
@ -105,15 +154,15 @@ void QualityMapperDialog::initEqualizerHistogram(vcg::Histogramf *h)
|
||||
//QColor valuesColor;
|
||||
|
||||
//drawing chart basics
|
||||
drawCartesianChartBasics(maxRoundedY, h);
|
||||
drawCartesianChartBasics( _equalizerScene, ui.equalizerGraphicsView );
|
||||
QSizeF valuesStringSize;
|
||||
//Font f = new Font("Verdana", valuesLabelSize);
|
||||
|
||||
|
||||
//drawing histogram bars
|
||||
for (int i = 0; i < h->n; i++)
|
||||
for (int i = 0; i < h.n; i++)
|
||||
{
|
||||
barHeight = (float)(chartHeightForCartesians * h->H[i]) / (float)maxRoundedY;
|
||||
barHeight = (float)(chartHeightForCartesians * h.H[i]) / (float)maxRoundedY;
|
||||
startBarPt.setX( leftBorder + ((barSeparator + barWidth) * i) );
|
||||
startBarPt.setY( (float)lowerBorderForCartesians - barHeight );
|
||||
|
||||
@ -149,35 +198,9 @@ void QualityMapperDialog::initEqualizerHistogram(vcg::Histogramf *h)
|
||||
}
|
||||
|
||||
|
||||
void QualityMapperDialog::drawCartesianChartBasics(/*String title,*/ int maxRoundedY, vcg::Histogramf *h /*, ChartHeader header*/)
|
||||
void QualityMapperDialog::drawTransferFunction(TransferFunction& tf)
|
||||
{
|
||||
int width = 300;//ui.equalizerGraphicsView->width();
|
||||
int height = 200;//ui.equalizerGraphicsView->height();
|
||||
|
||||
// Create a LightBlue background
|
||||
//_equalizerScene.addRect(chartRectangleThickness, chartRectangleThickness, width - (2 * chartRectangleThickness), height - (2 * chartRectangleThickness), QPen(), QBrush(QColor(230, 230, 255), Qt::SolidPattern));
|
||||
|
||||
//drawing chart title
|
||||
//this.writeString(g, title, titleLabelSize, Color.Black, Positions.North);
|
||||
|
||||
//drawing scale values on X and Y axis
|
||||
//this.drawXYValuesScale(chartType, g, maxRoundedY, vals, xyLabelsSize);
|
||||
|
||||
//drawing axis
|
||||
//x axis
|
||||
_equalizerScene.addLine(leftBorder, lowerBorderForCartesians, rightBorder, lowerBorderForCartesians, QPen(Qt::black));
|
||||
//y axis
|
||||
_equalizerScene.addLine(leftBorder, upperBorder, leftBorder, lowerBorderForCartesians, QPen(Qt::black));
|
||||
|
||||
/*
|
||||
//drawing axis labels
|
||||
//drawing X label
|
||||
this.writeString(g, header.xLabel, xyLabelsSize, Color.Black, Positions.South);
|
||||
//drawing Y label
|
||||
String yLabel = header.yLabel;
|
||||
//if the y label represent a delay, the time unit is added to the string (min.) [MINUTE]
|
||||
if ((yLabel.ToLower()).Contains("delay"))
|
||||
yLabel += " min.";
|
||||
this.writeString(g, yLabel, xyLabelsSize, Color.Black, Positions.West);
|
||||
*/
|
||||
}
|
||||
this->drawCartesianChartBasics( _transferFunctionScene, ui.transferFunctionView );
|
||||
_transferFunctionScene.addLine(0, 0, 100, 430, QPen(Qt::green, 3));
|
||||
ui.transferFunctionView->setScene( &_transferFunctionScene );
|
||||
}
|
||||
@ -12,9 +12,16 @@
|
||||
*/
|
||||
|
||||
#include <vcg/complex/trimesh/base.h>
|
||||
#include <vcg/math/histogram.h>
|
||||
#include "ui_qualitymapperdialog.h"
|
||||
|
||||
#include <vcg/math/histogram.h>
|
||||
|
||||
#include "transferfunction.h"
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
|
||||
//questa clsse l'hai creata tu? (??) MAL
|
||||
class QualityMapperSettings
|
||||
{
|
||||
public:
|
||||
@ -51,15 +58,19 @@ public:
|
||||
void setValues(const QualityMapperSettings& qms);
|
||||
QualityMapperSettings getValues();
|
||||
|
||||
void initEqualizerHistogram(vcg::Histogramf *h);
|
||||
void drawCartesianChartBasics(int maxRoundedY, vcg::Histogramf *h);
|
||||
void drawCartesianChartBasics(QGraphicsScene& scene, QGraphicsView *view /*, float maxRoundedY*/); //controllare il puntatore alla vista (!!) MAL
|
||||
void initEqualizerHistogram(vcg::Histogramf& h);
|
||||
void drawTransferFunction( TransferFunction& tf);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Ui::QualityMapperDialogClass ui;
|
||||
QualityMapperSettings _settings;
|
||||
QGraphicsScene _equalizerScene;
|
||||
QGraphicsScene _equalizerScene; //questo equivale a graphics di .NET. O ne conserviamo una sola e la utilizziamo per disegnare tutto, o ne creiamo una ogni volta che dobbiamo disegnare qualcosa. forse sbaglio in pieno(??) indagare MAL
|
||||
QGraphicsScene _transferFunctionScene;
|
||||
|
||||
//questi parametri variano a seconda del grafico che si sta disegnando
|
||||
int border;
|
||||
int chartRectangleThickness;
|
||||
int leftBorder;
|
||||
|
||||
@ -200,6 +200,22 @@ void TfChannel::testInitChannel()
|
||||
|
||||
//TRANSFER FUNCTION
|
||||
TransferFunction::TransferFunction(void)
|
||||
{
|
||||
this->initTF();
|
||||
}
|
||||
|
||||
|
||||
TransferFunction::TransferFunction(QString colorBandFile)
|
||||
{
|
||||
this->initTF();
|
||||
}
|
||||
|
||||
TransferFunction::~TransferFunction(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TransferFunction::initTF()
|
||||
{
|
||||
//Initializing channels types and pivoting indexes.
|
||||
//Each index in channel order has the same value of the enum
|
||||
@ -213,10 +229,6 @@ TransferFunction::TransferFunction(void)
|
||||
memset(_color_band,0,sizeof(_color_band));
|
||||
}
|
||||
|
||||
TransferFunction::~TransferFunction(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TransferFunction::buildColorBand()
|
||||
{
|
||||
|
||||
@ -32,7 +32,10 @@
|
||||
#include <map>
|
||||
//#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include <QString>
|
||||
//#include <assert.h>
|
||||
#include "const_types.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
@ -133,11 +136,15 @@ private:
|
||||
int _channels_order[NUMBER_OF_CHANNELS]; //array used to carry out virtual pivoting indexing
|
||||
Color4f _color_band[COLOR_BAND_SIZE]; /*rendere color band una classe a se stante??*/
|
||||
|
||||
void initTF(void);
|
||||
|
||||
public:
|
||||
TransferFunction(void);
|
||||
TransferFunction(QString colorBandFile);
|
||||
~TransferFunction(void);
|
||||
|
||||
void buildColorBand();
|
||||
void saveColorBand();
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,18 +1,18 @@
|
||||
#include "util.h"
|
||||
|
||||
|
||||
//returns a relative-absolute x value conversion rounded to closer integer value
|
||||
int relative2AbsoluteVali(float relative_val, float max_val)
|
||||
{ return (int)((relative_val * max_val)+0.5f); }
|
||||
#include <cassert>
|
||||
|
||||
//returns a relative-absolute x value conversion rounded to closer integer value
|
||||
float relative2AbsoluteValf(float relative_val, float max_val)
|
||||
{ return (relative_val * max_val); }
|
||||
|
||||
//returns an absolute-relative x value conversion
|
||||
int absolute2RelativeVali(float absolute_val, float max_val)
|
||||
{ return (int)((absolute_val / max_val)+0.5f); }
|
||||
//returns a relative-absolute x value conversion rounded to closer integer value
|
||||
int relative2AbsoluteVali(float relative_val, float max_val)
|
||||
{ return (int)(relative2AbsoluteValf(relative_val, max_val)+0.5f); }
|
||||
|
||||
//returns an absolute-relative x value conversion
|
||||
float absolute2RelativeValf(float absolute_val, float max_val)
|
||||
{ return (float)absolute_val / max_val; }
|
||||
{ assert(max_val!=0); return (absolute_val / max_val); }
|
||||
|
||||
//returns an absolute-relative x value conversion
|
||||
int absolute2RelativeVali(float absolute_val, float max_val)
|
||||
{ return (int)(absolute2RelativeValf(absolute_val, max_val)+0.5f); }
|
||||
@ -1,21 +1,12 @@
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "const_types.h"
|
||||
|
||||
|
||||
|
||||
//returns a relative-absolute x value conversion rounded to closer integer value
|
||||
//this functions return a relative-absolute value conversion perspectively as float and int (rounded to closer integer value)
|
||||
float relative2AbsoluteValf(float relative_val, float max_val);
|
||||
int relative2AbsoluteVali(float relative_val, float max_val);
|
||||
|
||||
//returns a relative-absolute x value conversion rounded to closer integer value
|
||||
float relative2AbsoluteValf(float relative_val, float max_val);
|
||||
|
||||
//returns an absolute-relative x value conversion
|
||||
//this functions return a absolute-relative value conversion perspectively as float and int (rounded to closer integer value)
|
||||
float absolute2RelativeValf(float absolute_val, float max_val);
|
||||
int absolute2RelativeVali(float absolute_val, float max_val);
|
||||
|
||||
//returns an absolute-relative x value conversion
|
||||
float absolute2RelativeValf(float absolute_val, float max_val);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user