diff --git a/src/fgt/edit_quality/const_types.h b/src/fgt/edit_quality/const_types.h index 32d3fd6df..5374ae014 100644 --- a/src/fgt/edit_quality/const_types.h +++ b/src/fgt/edit_quality/const_types.h @@ -12,4 +12,8 @@ typedef unsigned int UINT32; #define COLOR_BAND_SIZE 1024 +#define CANVAS_BORDER_DISTANCE 5 + +#define Y_SCALE_STEP 5 + #endif \ No newline at end of file diff --git a/src/fgt/edit_quality/qualitymapper.cpp b/src/fgt/edit_quality/qualitymapper.cpp index 48f33699d..289e9efff 100644 --- a/src/fgt/edit_quality/qualitymapper.cpp +++ b/src/fgt/edit_quality/qualitymapper.cpp @@ -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); diff --git a/src/fgt/edit_quality/qualitymapper.h b/src/fgt/edit_quality/qualitymapper.h index 7263e4646..4aee13587 100644 --- a/src/fgt/edit_quality/qualitymapper.h +++ b/src/fgt/edit_quality/qualitymapper.h @@ -89,6 +89,7 @@ public: bool haveToPick; void ComputePerVertexQualityHistogram( CMeshO & m, vcg::Frange range, Histogramf &h, int bins); + }; #endif diff --git a/src/fgt/edit_quality/qualitymapperdialog.cpp b/src/fgt/edit_quality/qualitymapperdialog.cpp index e78457adf..b2a2411f0 100644 --- a/src/fgt/edit_quality/qualitymapperdialog.cpp +++ b/src/fgt/edit_quality/qualitymapperdialog.cpp @@ -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::max(); - - //processing minX, maxX, minY and maxY values - for (int i=0; i maxY) - maxY = h.H[i]; + //processing minY and maxY values for histogram + int maxY = 0; + int minY = std::numeric_limits::max(); + for (int i=0; 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::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); + } + } + +*/ + + + + + + + + } \ No newline at end of file diff --git a/src/fgt/edit_quality/qualitymapperdialog.h b/src/fgt/edit_quality/qualitymapperdialog.h index e95d16c2a..d37bd1615 100644 --- a/src/fgt/edit_quality/qualitymapperdialog.h +++ b/src/fgt/edit_quality/qualitymapperdialog.h @@ -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: diff --git a/src/fgt/edit_quality/transferfunction.h b/src/fgt/edit_quality/transferfunction.h index a2ed4a3f1..b956809a9 100644 --- a/src/fgt/edit_quality/transferfunction.h +++ b/src/fgt/edit_quality/transferfunction.h @@ -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 result ) + result = _channels[i].size(); + + return result; + } }; #endif \ No newline at end of file diff --git a/src/fgt/edit_quality/ui_qualitymapperdialog.h b/src/fgt/edit_quality/ui_qualitymapperdialog.h index a64eb9685..1651e023f 100644 --- a/src/fgt/edit_quality/ui_qualitymapperdialog.h +++ b/src/fgt/edit_quality/ui_qualitymapperdialog.h @@ -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!