mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-19 19:14:42 +00:00
qualitymapperdialog.h\cpp:
- drawChartBasics is now view and chart indipendent - drawHisrogram enhanced - CHART_INFO struct added to store graphics and stats info about the chart to draw
This commit is contained in:
parent
48fd440d0c
commit
2d9fa40918
@ -12,4 +12,8 @@ typedef unsigned int UINT32;
|
||||
|
||||
#define COLOR_BAND_SIZE 1024
|
||||
|
||||
#define CANVAS_BORDER_DISTANCE 5
|
||||
|
||||
#define Y_SCALE_STEP 5
|
||||
|
||||
#endif
|
||||
@ -124,6 +124,7 @@ void QualityMapperPlugin::StartEdit(QAction *mode, MeshModel &m, GLArea *gla )
|
||||
_qmSettings.meshMidQ = (mmmq.minV+mmmq.maxV)/2;
|
||||
_qualityMapperDialog->setValues(_qmSettings);
|
||||
|
||||
|
||||
//drawing histogram in dialog(??) MAL
|
||||
_qualityMapperDialog->initEqualizerHistogram(_histogram);
|
||||
|
||||
|
||||
@ -89,6 +89,7 @@ public:
|
||||
bool haveToPick;
|
||||
|
||||
void ComputePerVertexQualityHistogram( CMeshO & m, vcg::Frange range, Histogramf &h, int bins);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -8,11 +8,23 @@ QualityMapperDialog::QualityMapperDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
_histogram_info = 0;
|
||||
_transferFunction_info = 0;
|
||||
}
|
||||
|
||||
QualityMapperDialog::~QualityMapperDialog()
|
||||
{
|
||||
if ( _histogram_info )
|
||||
{
|
||||
delete _histogram_info;
|
||||
_histogram_info = 0;
|
||||
}
|
||||
|
||||
if ( _transferFunction_info )
|
||||
{
|
||||
delete _transferFunction_info;
|
||||
_transferFunction_info = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QualityMapperDialog::setValues(const QualityMapperSettings& qms)
|
||||
@ -34,46 +46,21 @@ QualityMapperSettings QualityMapperDialog::getValues()
|
||||
}
|
||||
|
||||
|
||||
void QualityMapperDialog::drawCartesianChartBasics(QGraphicsScene& scene, QGraphicsView *view)
|
||||
void QualityMapperDialog::drawChartBasics(QGraphicsScene& scene, QGraphicsView *view, CHART_INFO *chart_info)
|
||||
{
|
||||
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);
|
||||
//a valid view must be passed!
|
||||
assert(view != 0);
|
||||
|
||||
// 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);
|
||||
assert( chart_info != 0 );
|
||||
|
||||
QPen p( Qt::black, 2 );
|
||||
|
||||
//drawing axis
|
||||
//x axis
|
||||
scene.addLine(leftBorder, lowerBorderForCartesians, rightBorder, lowerBorderForCartesians, p );
|
||||
scene.addLine( chart_info->leftBorder, chart_info->lowerBorder, chart_info->rightBorder, chart_info->lowerBorder, 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);
|
||||
*/
|
||||
scene.addLine( chart_info->leftBorder, chart_info->upperBorder, chart_info->leftBorder, chart_info->lowerBorder, p );
|
||||
}
|
||||
|
||||
|
||||
@ -83,92 +70,65 @@ void QualityMapperDialog::drawCartesianChartBasics(QGraphicsScene& scene, QGraph
|
||||
//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();
|
||||
|
||||
border = 5;
|
||||
chartRectangleThickness = 2;
|
||||
leftBorder = border;
|
||||
rightBorder = width - border;
|
||||
upperBorder = border;
|
||||
lowerBorderForCartesians = height - (int)(border * 3);
|
||||
|
||||
int chartWidth = rightBorder - leftBorder;
|
||||
int chartHeightForCartesians = lowerBorderForCartesians - upperBorder;
|
||||
int yScaleStep = 5;
|
||||
|
||||
float dX = (float)chartWidth / (float)h.n;
|
||||
float dY = (float)chartHeightForCartesians / (float)h.n;
|
||||
|
||||
int maxY = 0;
|
||||
int minY = std::numeric_limits<int>::max();
|
||||
|
||||
//processing minX, maxX, minY and maxY values
|
||||
for (int i=0; i<h.n; i++)
|
||||
//building histogram chart informations
|
||||
if ( _histogram_info == 0 )
|
||||
{
|
||||
if (h.H[i] > maxY)
|
||||
maxY = h.H[i];
|
||||
//processing minY and maxY values for histogram
|
||||
int maxY = 0;
|
||||
int minY = std::numeric_limits<int>::max();
|
||||
for (int i=0; i<h.n; 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];
|
||||
}
|
||||
_histogram_info = new CHART_INFO( ui.equalizerGraphicsView->width(), ui.equalizerGraphicsView->height(), h.n, h.minv, h.maxv, minY, maxY );
|
||||
}
|
||||
|
||||
int maxRoundedY = (int)(maxY + yScaleStep - (maxY % yScaleStep)); //the highest value represented in the y values scale
|
||||
float variance = maxY - minY; //variance of y values
|
||||
float barHeight = 0.0F; //initializing height of the histogram bars
|
||||
float barWidth = dX * 4.0F / 5.0F; //processing width of the histogram bars (4\5 of dX)
|
||||
float barSeparator = dX / 5.0F; //processing space between consecutive bars of the histogram bars (1\5 of dX)
|
||||
// _equalizerScene.addText("Hello World!");
|
||||
this->drawChartBasics( _equalizerScene, ui.equalizerGraphicsView, _histogram_info );
|
||||
|
||||
// assert(_histogram_info != 0);
|
||||
//
|
||||
// int maxY = 0;
|
||||
// int minY = std::numeric_limits<int>::max();
|
||||
//
|
||||
// //processing minX, maxX, minY and maxY values
|
||||
// for (int i=0; i<_histogram_info->numOfItems; i++)
|
||||
// {
|
||||
// if (h.H[i] > maxY)
|
||||
// maxY = h.H[i];
|
||||
//
|
||||
// if (h.H[i] < minY)
|
||||
// minY = h.H[i];
|
||||
// }
|
||||
|
||||
// _histogram_info->updateMinMax( h.minv, h.maxv, minY, maxY );
|
||||
|
||||
float barHeight = 0.0f; //initializing height of the histogram bars
|
||||
float barWidth = _histogram_info->dX; //processing width of the histogram bars (4\5 of dX)
|
||||
// float barSeparator = dX - barWidth; //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);
|
||||
|
||||
QPointF startBarPt;
|
||||
QSizeF barSize;
|
||||
|
||||
//QColor valuesColor;
|
||||
|
||||
//drawing chart basics
|
||||
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 < _histogram_info->numOfItems; i++)
|
||||
{
|
||||
barHeight = (float)(chartHeightForCartesians * h.H[i]) / (float)maxRoundedY;
|
||||
startBarPt.setX( leftBorder + ((barSeparator + barWidth) * i) );
|
||||
startBarPt.setY( (float)lowerBorderForCartesians - barHeight );
|
||||
barHeight = (float)(_histogram_info->chartHeight * h.H[i]) / (float)_histogram_info->maxRoundedY;
|
||||
startBarPt.setX( _histogram_info->leftBorder + ( barWidth * i ) );
|
||||
startBarPt.setY( (float)_histogram_info->lowerBorder - barHeight );
|
||||
|
||||
barSize.setWidth(barWidth);
|
||||
barSize.setHeight(barHeight);
|
||||
|
||||
//drawing histogram bar
|
||||
_equalizerScene.addRect(startBarPt.x(), startBarPt.y(), barSize.width(), barSize.height(), drawingPen, drawingBrush);
|
||||
|
||||
/*
|
||||
//drawing bar (numeric) value
|
||||
//if the bar is large enough to contain a numeric value...
|
||||
valuesStringSize = g.MeasureString(values[i].yValue.ToString(), f);
|
||||
|
||||
//choosing text color (red for min and max value, white else)
|
||||
if ((Convert.ToSingle(values[i].yValue) == maxY) || (Convert.ToSingle(values[i].yValue) == minY))
|
||||
valuesColor = Color.Red;
|
||||
else
|
||||
valuesColor = Color.Gray;
|
||||
valuesColor = QColor(128,128,128);
|
||||
|
||||
if (barHeight < (valuesStringSize.Height + chartRectangleThickness))
|
||||
startBarPt.Y -= (valuesStringSize.Height + chartRectangleThickness);
|
||||
|
||||
//the value is written only if there's space enough between the bars or if the value to represent is the min or the max value
|
||||
if ((barSize.Width >= (valuesStringSize.Width * 0.9F)) || (valuesColor == Color.Red))
|
||||
{
|
||||
this.writeString(g, Convert.ToString(values[i].yValue), valuesLabelSize, valuesColor, Positions.Custom, startBarPt);
|
||||
}*/
|
||||
}
|
||||
|
||||
ui.equalizerGraphicsView->setScene(&_equalizerScene);
|
||||
@ -177,7 +137,105 @@ void QualityMapperDialog::initEqualizerHistogram( Histogramf& h )
|
||||
|
||||
void QualityMapperDialog::drawTransferFunction(TransferFunction& tf)
|
||||
{
|
||||
this->drawCartesianChartBasics( _transferFunctionScene, ui.transferFunctionView );
|
||||
//building transfer function chart informations
|
||||
if ( _transferFunction_info == 0 )
|
||||
_transferFunction_info = new CHART_INFO( ui.equalizerGraphicsView->width(), ui.equalizerGraphicsView->height(), tf.size(), 0.0f, 1.0f, 0.0f, 1.0f );
|
||||
|
||||
this->drawChartBasics( _transferFunctionScene, ui.transferFunctionView, _transferFunction_info );
|
||||
_transferFunctionScene.addLine(0, 0, 100, 430, QPen(Qt::green, 3));
|
||||
ui.transferFunctionView->setScene( &_transferFunctionScene );
|
||||
|
||||
/*
|
||||
|
||||
float dX = Convert.ToSingle(chartWidth) / values.Length;
|
||||
float dY = Convert.ToSingle(chartHeightForCartesians) / values.Length;
|
||||
|
||||
//Single maxX = Single.MinValue;
|
||||
float maxY = Single.MinValue;
|
||||
float minY = Single.MaxValue;
|
||||
|
||||
//processing minX, maxX, minY and maxY values
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
/ *
|
||||
if (Convert.ToSingle(values[i].xValue) > maxX)
|
||||
maxX = Convert.ToSingle(values[i].xValue);* /
|
||||
|
||||
if (values[i].yValue > maxY)
|
||||
maxY = values[i].yValue;
|
||||
|
||||
if (values[i].yValue < minY)
|
||||
minY = values[i].yValue;
|
||||
}
|
||||
|
||||
int maxRoundedY = Convert.ToInt32(Math.Floor(maxY + yScaleStep - (maxY % yScaleStep))); //the highest value represented in the y values scale
|
||||
float variance = maxY - minY; //variance of y values
|
||||
Point3f pointToRepresent = new PointF();
|
||||
Point3f previousPoint = new PointF();
|
||||
|
||||
QPen drawingPen = new Pen(Color.Navy);
|
||||
QBrush drawingBrush = new SolidBrush(Color.Navy);
|
||||
|
||||
Color4f valuesColor;
|
||||
int pointMarkerRadius = 3;
|
||||
|
||||
//drawing chart basics
|
||||
this->drawCartesianChartBasics( _transferFunctionScene, ui.transferFunctionView );
|
||||
SizeF valuesStringSize;
|
||||
Font f = new Font("Verdana", valuesLabelSize);
|
||||
RectangleF pointRect = new RectangleF();
|
||||
|
||||
//drawing chart points
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
pointToRepresent.Y = lowerBorderForCartesians - Convert.ToSingle(chartHeightForCartesians) * values[i].yValue / maxRoundedY;
|
||||
pointToRepresent.X = leftBorder + (dX * i);
|
||||
|
||||
//drawing single current point
|
||||
pointRect.X = pointToRepresent.X - pointMarkerRadius;
|
||||
pointRect.Y = pointToRepresent.Y - pointMarkerRadius;
|
||||
pointRect.Width = 2 * pointMarkerRadius;
|
||||
pointRect.Height = 2 * pointMarkerRadius;
|
||||
g.DrawEllipse(drawingPen, pointRect);
|
||||
g.FillEllipse(drawingBrush, pointRect);
|
||||
|
||||
//linear interpolation between current point and previous one
|
||||
//interpolation will not be executed if the current point is the first of the list
|
||||
if (i > 0)
|
||||
g.DrawLine(drawingPen, previousPoint, pointToRepresent);
|
||||
|
||||
//refresh of previous point.
|
||||
//So, it's possible to interpolate linearly the current point with the previous one
|
||||
previousPoint = pointToRepresent;
|
||||
|
||||
//DRAWING POINT (NUMERIC) VALUE
|
||||
valuesStringSize = g.MeasureString(values[i].yValue.ToString(), f);
|
||||
|
||||
//choosing text color (red for min and max value, white else)
|
||||
if ((values[i].yValue == maxY) || (values[i].yValue == minY))
|
||||
valuesColor = Color.Red;
|
||||
else
|
||||
valuesColor = Color.Gray;
|
||||
|
||||
//if the point is too low...
|
||||
if (lowerBorderForCartesians - pointToRepresent.Y < (valuesStringSize.Height + chartRectangleThickness))
|
||||
pointToRepresent.Y -= (valuesStringSize.Height + chartRectangleThickness);
|
||||
|
||||
//if there's space enough between consecutive points to contain a numeric value...
|
||||
//the value is written only if there's space enough between the bars or if the value to represent is the min or the max value
|
||||
if ((dX >= (valuesStringSize.Width * 0.9F)) || (valuesColor == Color.Red))
|
||||
{
|
||||
this.writeString(g, Convert.ToString(values[i].yValue), valuesLabelSize, valuesColor, Positions.Custom, pointToRepresent);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -46,9 +46,61 @@ public:
|
||||
range=500;
|
||||
meshMaxQ=meshMinQ=meshMidQ=manualMaxQ=manualMinQ=manualMidQ=0.0f;
|
||||
//useManual=false;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//questa dovrebbe essere trasferita in util.h
|
||||
struct CHART_INFO
|
||||
{
|
||||
int leftBorder;
|
||||
int rightBorder;
|
||||
int upperBorder;
|
||||
int lowerBorder;
|
||||
float chartWidth;
|
||||
float chartHeight;
|
||||
int numOfItems;
|
||||
int yScaleStep;
|
||||
int maxRoundedY;
|
||||
float minX;
|
||||
float maxX;
|
||||
float minY;
|
||||
float maxY;
|
||||
float dX;
|
||||
float dY;
|
||||
float variance; //variance of y values
|
||||
|
||||
CHART_INFO(int view_width, int view_height, int num_of_items=1, float min_X=0.0f, float max_X=0.0f, float min_Y=0.0f, float max_Y=0.0f )
|
||||
{
|
||||
assert(num_of_items != 0);
|
||||
|
||||
leftBorder = CANVAS_BORDER_DISTANCE;
|
||||
rightBorder = view_width - CANVAS_BORDER_DISTANCE;
|
||||
upperBorder = CANVAS_BORDER_DISTANCE;
|
||||
lowerBorder = view_height - CANVAS_BORDER_DISTANCE;
|
||||
chartWidth = rightBorder - leftBorder;
|
||||
chartHeight = lowerBorder - upperBorder;
|
||||
numOfItems = num_of_items;
|
||||
yScaleStep = Y_SCALE_STEP;
|
||||
this->updateMinMax( min_X, max_X, min_Y, max_Y );
|
||||
|
||||
dX = chartWidth / (float)numOfItems;
|
||||
dY = chartHeight / (float)numOfItems;
|
||||
}
|
||||
inline void updateMinMax( float min_X=0.0f, float max_X=0.0f, float min_Y=0.0f, float max_Y=0.0f )
|
||||
{
|
||||
minX = min_X;
|
||||
maxX = max_X;
|
||||
minY = min_Y;
|
||||
maxY = max_Y;
|
||||
maxRoundedY = (int)(maxY + Y_SCALE_STEP - (relative2AbsoluteVali(maxY, maxY) % Y_SCALE_STEP)); //the highest value represented in the y values scale
|
||||
variance = maxY - minY; //variance of y values
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class QualityMapperDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -60,26 +112,24 @@ public:
|
||||
void setValues(const QualityMapperSettings& qms);
|
||||
QualityMapperSettings getValues();
|
||||
|
||||
void drawCartesianChartBasics(QGraphicsScene& scene, QGraphicsView *view /*, float maxRoundedY*/); //controllare il puntatore alla vista (!!) MAL
|
||||
void initEqualizerHistogram(vcg::Histogramf& h);
|
||||
void drawChartBasics(QGraphicsScene& scene, QGraphicsView *view, CHART_INFO *current_chart_info ); //controllare il puntatore alla vista (!!) MAL
|
||||
void initEqualizerHistogram( vcg::Histogramf& h );
|
||||
void drawTransferFunction( TransferFunction& tf);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Ui::QualityMapperDialogClass ui;
|
||||
QualityMapperSettings _settings;
|
||||
|
||||
CHART_INFO *_histogram_info;
|
||||
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
|
||||
|
||||
CHART_INFO *_transferFunction_info;
|
||||
QGraphicsScene _transferFunctionScene;
|
||||
|
||||
|
||||
//questi parametri variano a seconda del grafico che si sta disegnando MAL
|
||||
//in effetti si, a parte forse border, leftBorder, rightBorder, upperBorder che potrebbero essere gli stessi UCCIO
|
||||
int border;
|
||||
int chartRectangleThickness;
|
||||
int leftBorder;
|
||||
int rightBorder;
|
||||
int upperBorder;
|
||||
int lowerBorderForCartesians;
|
||||
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
@ -117,6 +117,8 @@ public:
|
||||
float getChannelValuef(float x_position);
|
||||
UINT8 getChannelValueb(float x_position);
|
||||
|
||||
int size() { return KEYS.size(); }
|
||||
|
||||
#ifdef NOW_TESTING
|
||||
void testInitChannel();
|
||||
#endif
|
||||
@ -145,6 +147,15 @@ public:
|
||||
|
||||
void buildColorBand();
|
||||
void saveColorBand();
|
||||
int size()
|
||||
{
|
||||
int result = 0;
|
||||
for (int i=0; i<NUMBER_OF_CHANNELS; i++)
|
||||
if ( _channels[i].size() > result )
|
||||
result = _channels[i].size();
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,7 +1,7 @@
|
||||
/********************************************************************************
|
||||
** Form generated from reading ui file 'qualitymapperdialog.ui'
|
||||
**
|
||||
** Created: Sun 20. Jan 13:31:18 2008
|
||||
** Created: Mon 21. Jan 16:14:15 2008
|
||||
** by: Qt User Interface Compiler version 4.3.2
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user