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:
Paolo Cignoni cignoni 2008-01-21 15:25:08 +00:00
parent 48fd440d0c
commit 2d9fa40918
7 changed files with 236 additions and 111 deletions

View File

@ -12,4 +12,8 @@ typedef unsigned int UINT32;
#define COLOR_BAND_SIZE 1024
#define CANVAS_BORDER_DISTANCE 5
#define Y_SCALE_STEP 5
#endif

View File

@ -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);

View File

@ -89,6 +89,7 @@ public:
bool haveToPick;
void ComputePerVertexQualityHistogram( CMeshO & m, vcg::Frange range, Histogramf &h, int bins);
};
#endif

View File

@ -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);
}
}
*/
}

View File

@ -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:

View File

@ -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

View File

@ -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!