const_types.h:

updated some constants

EqHandle.h\cpp:
- minor changes

qualitymapperdialog.h\cpp:
- updated drawChartsBasics signature and implementation
- updated drawTransferFunction method (now working)
- fixed bug in drawEqualizerHistogram: now the hadles are drawn correctly

qualitymapperdialog.ui:
- minor changes

transferfunction.h\cpp:
- fixed bug in random keys generation method (uesd for test)
- removed enumeration to index lower\upper y values for a key. 3 defines have been used.
- other minor changes
This commit is contained in:
Paolo Cignoni cignoni 2008-01-23 16:15:43 +00:00
parent 62bc21b84b
commit ff88f13995
10 changed files with 178 additions and 93 deletions

View File

@ -20,8 +20,9 @@ void EqHandle::paint ( QPainter * painter, const QStyleOptionGraphicsItem * opti
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setPen(_color);
painter->setBrush(_color);
//painter->drawLine(0, -_size/2, 0, -_barHeight);
painter->drawRect(-_size/2, -_size/2, _size, _size);
painter->drawRect(-_size/2.0f, -_size/2.0f, _size, _size);
}
void EqHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

View File

@ -6,7 +6,7 @@
#include "handle.h"
/* Specific handle for equalizerHistogramScene
It can only be dragged horizzontally */
It can only be dragged horizontally */
class EqHandle : public Handle
{
Q_OBJECT

View File

@ -1,7 +1,3 @@
12.45 15/01/2008 aggiungere i riferimenti ai nuovi files del progetto al file .pro
22.44 15/01/2008 convertire le QSpinBox per la TranferFunction in double ones
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
15.33 20/01/2008 da implementare per Transfer Function: 1. se si fa doppio click in un punto vuoto del grafico va creata una nuova key in quel punto. Se si fa doppio click in su un punto della transfer function: - se il punto è l'upper o il lower di una chiave, questa collassa. - Se upper e lower coincidono, la chiave viene completamente rimossa.
15.33 20/01/2008 da implementare per Transfer Function: 1. se si fa doppio click in un punto vuoto del grafico va creata una nuova key in quel punto. Se si fa doppio click in su un punto della transfer function: - se il punto è l'upper o il lower di una chiave, questa collassa. - Se upper e lower coincidono, la chiave viene completamente rimossa.
17.08 23/01/2008 aggiustare il layout del file ui. La view della transfer function "cade" nel pannello affianco. Lo spinbox inferiore delle opzioni della TF è smussato in basso. Allungare la colorband per allinearla con la TF.

View File

@ -12,8 +12,11 @@ typedef unsigned int UINT32;
#define COLOR_BAND_SIZE 1024
#define CANVAS_BORDER_DISTANCE 5
#define CANVAS_BORDER_DISTANCE 10.0
//da eliminare!!! MAL
#define Y_SCALE_STEP 5
#define MARKERS_RADIUS 2.0
#endif

View File

@ -4,7 +4,7 @@
Handle::Handle()
{
_size = 10;
_size = 4.0f;
_color = QColor(Qt::black);
setCursor(Qt::OpenHandCursor);

View File

@ -51,15 +51,12 @@ QualityMapperSettings QualityMapperDialog::getValues()
}
void QualityMapperDialog::drawChartBasics(QGraphicsScene& scene, QGraphicsView *view, CHART_INFO *chart_info)
void QualityMapperDialog::drawChartBasics(QGraphicsScene& scene, CHART_INFO *chart_info)
{
//a valid view must be passed!
assert(view != 0);
//a valid chart_info must be passed
assert( chart_info != 0 );
QPen p( Qt::black, 2 );
QPen p( Qt::black, 1 );
//drawing axis
//x axis
@ -91,7 +88,7 @@ void QualityMapperDialog::drawEqualizerHistogram( Histogramf& h )
}
//drawing axis and other basic items
this->drawChartBasics( _equalizerScene, ui.equalizerGraphicsView, _histogram_info );
this->drawChartBasics( _equalizerScene, _histogram_info );
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)
@ -119,17 +116,18 @@ void QualityMapperDialog::drawEqualizerHistogram( Histogramf& h )
//drawing handles
QColor colors[] = { QColor(Qt::red), QColor(Qt::green), QColor(Qt::blue) };
qreal xStart = _histogram_info->leftBorder;
qreal xPos = 0.0;
qreal yPos = _histogram_info->lowerBorder;
for (int i=0; i<3; i++)
{
xPos = xStart + _histogram_info->chartWidth/2*i;
_equalizerScene.addItem(&_equalizerHandles[i]);
_equalizerHandles[i].setColor(colors[i]);
_equalizerHandles[i].setPos(xPos, yPos);
}
qreal xStart = _histogram_info->leftBorder;
qreal xPos = 0.0;
qreal yPos = _histogram_info->lowerBorder;
for (int i=0; i<3; i++)
{
xPos = xStart + _histogram_info->chartWidth/2.0*i;
_equalizerHandles[i].setColor(colors[i]);
_equalizerHandles[i].setPos(xPos, yPos);
_equalizerScene.addItem(&_equalizerHandles[i]);
}
ui.equalizerGraphicsView->setScene(&_equalizerScene);
}
@ -139,18 +137,19 @@ void QualityMapperDialog::drawTransferFunction(TransferFunction& tf)
{
//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 );
_transferFunction_info = new CHART_INFO( ui.transferFunctionView->width(), ui.transferFunctionView->height(), tf.size(), 0.0f, 1.0f, 0.0f, 1.0f );
//drawing axis and other basic items
this->drawChartBasics( _transferFunctionScene, ui.transferFunctionView, _transferFunction_info );
this->drawChartBasics( _transferFunctionScene, _transferFunction_info );
// _transferFunctionScene.addLine(0, 0, 100, 430, QPen(Qt::green, 3));
//questo per il momento è fisso e definito quì, ma dovrà essere gestito nella classe handle
int pointMarkerRadius = 1;
QPointF pointToRepresent;
QPointF pointToRepresentLeft;
QPointF pointToRepresentRight;
QPointF previousPoint;
QRectF pointRect(0, 0, 2.0*pointMarkerRadius, 2.0*pointMarkerRadius );
QRectF pointRectLeft(0, 0, 2.0*MARKERS_RADIUS, 2.0*MARKERS_RADIUS );
QRectF pointRectRight(0, 0, 2.0*MARKERS_RADIUS, 2.0*MARKERS_RADIUS );
QColor channelColor;
QPen drawingPen(Qt::black);
@ -159,41 +158,58 @@ void QualityMapperDialog::drawTransferFunction(TransferFunction& tf)
//drawing chart points
// TfChannel *tf_c = 0;
TF_KEY *key = 0;
for(int i=0; i<NUMBER_OF_CHANNELS; i++)
TF_CHANNEL_VALUE val;
for(int c=0; c<NUMBER_OF_CHANNELS; c++)
{
// tf_c = tf[i];
for (int j=0; j<tf[i].size(); j++)
TYPE_2_COLOR(tf[c].getType(), channelColor);
drawingPen.setColor( channelColor );
drawingBrush.setColor( channelColor );
for (int i=0; i<tf[c].size(); i++)
{
key = tf[i][j];
}
}
/*
for (int i = 0; i < values.Length; i++)
{
pointToRepresent.setX(_transferFunction_info->lowerBorder - (float)_transferFunction_info->chartHeight * values[i].yValue / _transferFunction_info->maxRoundedY);
pointToRepresent.setY(_transferFunction_info->leftBorder + (_transferFunction_info->dX * i));
val = tf[c][i];
pointToRepresentLeft.setX( _transferFunction_info->leftBorder + relative2AbsoluteValf( (* val.x), (float)_transferFunction_info->chartWidth ) );
pointToRepresentLeft.setY( _transferFunction_info->lowerBorder - relative2AbsoluteValf( val.y->getLeftJunctionPoint(), (float)_transferFunction_info->chartHeight ) /*/ _transferFunction_info->maxRoundedY*/ );
pointToRepresentRight.setX( pointToRepresentLeft.x() );
pointToRepresentRight.setY( _transferFunction_info->lowerBorder - relative2AbsoluteValf( val.y->getRightJunctionPoint(), (float)_transferFunction_info->chartHeight ) /*/ _transferFunction_info->maxRoundedY*/ );
//drawing single current point
pointRect.setX(pointToRepresent.x() - pointMarkerRadius );
pointRect.setY(pointToRepresent.y() - pointMarkerRadius );
_transferFunctionScene.addEllipse( pointRect, drawingPen, drawingBrush );
// _transferFunctionScene.FillEllipse( drawingBrush, pointRect );
pointRectLeft.setX(pointToRepresentLeft.x() - MARKERS_RADIUS );
pointRectLeft.setY(pointToRepresentLeft.y() - MARKERS_RADIUS );
pointRectLeft.setWidth(2.0*MARKERS_RADIUS);
pointRectLeft.setHeight(2.0*MARKERS_RADIUS);
_transferFunctionScene.addEllipse( pointRectLeft, drawingPen, drawingBrush );
if ( pointToRepresentLeft.y() != pointToRepresentRight.y() )
{
pointRectRight.setX(pointToRepresentRight.x() - MARKERS_RADIUS );
pointRectRight.setY(pointToRepresentRight.y() - MARKERS_RADIUS );
pointRectRight.setWidth(pointRectLeft.width());
pointRectRight.setHeight(pointRectLeft.height());
_transferFunctionScene.addEllipse( pointRectRight, drawingPen, drawingBrush );
}
//sostituire con disegno della TfHandle
// _transferFunctionScene.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)
_transferFunctionScene.addLine(drawingPen, previousPoint, pointToRepresent);
{
_transferFunctionScene.addLine(previousPoint.x(), previousPoint.y(), pointToRepresentLeft.x(), pointToRepresentLeft.y(), drawingPen);
if ( pointToRepresentLeft.y() != pointRectRight.y() )
_transferFunctionScene.addLine( pointToRepresentLeft.x(), pointToRepresentLeft.y(), pointToRepresentRight.x(), pointToRepresentRight.y(), drawingPen );
}
//refresh of previous point.
//So, it's possible to interpolate linearly the current point with the previous one
previousPoint = pointToRepresent;
// //if the point is too low...
// if (lowerBorderForCartesians - pointToRepresent.Y < (valuesStringSize.Height + chartRectangleThickness))
// pointToRepresent.Y -= (valuesStringSize.Height + chartRectangleThickness);
}*/
previousPoint = pointToRepresentRight;
}
}
ui.transferFunctionView->setScene( &_transferFunctionScene );
}

View File

@ -113,7 +113,7 @@ public:
void setValues(const QualityMapperSettings& qms);
QualityMapperSettings getValues();
void drawChartBasics(QGraphicsScene& scene, QGraphicsView *view, CHART_INFO *current_chart_info ); //controllare il puntatore alla vista (!!) MAL
void drawChartBasics(QGraphicsScene& scene, CHART_INFO *current_chart_info ); //controllare il puntatore alla vista (!!) MAL
void drawEqualizerHistogram( vcg::Histogramf& h );
void drawTransferFunction( TransferFunction& tf);

View File

@ -37,7 +37,14 @@
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QGraphicsView" name="transferFunctionView" />
<widget class="QGraphicsView" name="transferFunctionView" >
<property name="minimumSize" >
<size>
<width>260</width>
<height>180</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QGroupBox" name="transferFunctionEditBox" >
@ -267,12 +274,6 @@
<height>200</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>200</height>
</size>
</property>
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>

View File

@ -1,5 +1,11 @@
#include "transferfunction.h"
//da eliminare!! MAL
#ifdef NOW_TESTING
#include <cmath>
using namespace std;
#endif
//TRANSFER FUNCTION CHANNEL
TfChannel::TfChannel()
@ -171,40 +177,60 @@ UINT8 TfChannel::getChannelValueb(float x_position)
// return (UINT8)(this->getChannelValuef(x_position) * 255.0f);
}
TF_KEY* TfChannel::operator [](int i)
TF_CHANNEL_VALUE& TfChannel::operator [](float idx)
{
KEY_LISTiterator it= KEYS.find(idx);
if (it!=KEYS.end())
{
_ret_val.x=(float*)&(it->first);
_ret_val.y=&(it->second);
}
else
{
_ret_val.x = 0;
_ret_val.y = 0;
}
return _ret_val;
}
TF_CHANNEL_VALUE& TfChannel::operator [](int i)
{
assert((i>=0) && (i<=this->size()));
if ( i == 0)
{
//indexing the first item of the list
idx_it=KEYS.begin();
_idx_it=KEYS.begin();
}
else
{
//now indexing the successive item in the list respect to the previous one
if ( old_iterator_idx == i-1 )
{
idx_it ++;
_idx_it ++;
}
else
{
//now indexing the previous item in the list respect to the previous one
if ( old_iterator_idx == i+1 )
{
idx_it --;
_idx_it --;
}
else
{
idx_it = KEYS.begin();
_idx_it = KEYS.begin();
for(int k=0; k<i; k++)
idx_it ++;
_idx_it ++;
}
}
}
old_iterator_idx = i;
_ret_val.x = (float*)&(_idx_it->first);
_ret_val.y = &(_idx_it->second);
return &(idx_it->second);
return _ret_val;
}
@ -214,6 +240,7 @@ void TfChannel::testInitChannel()
int num_of_keys = (rand() % 10) + 1;
float rand_x = 0.0f;
float rand_y = 0.0f;
float offset = 0.0f;
//first node\key = 0
this->addKey(0.0f, 0.0f, 0.0f);
@ -221,9 +248,14 @@ void TfChannel::testInitChannel()
{
rand_x = ((rand() % 100) + 1) / 100.0f;
rand_y = ((rand() % 100) + 1) / 100.0f;
this->addKey(rand_x, rand_y+1.0f, rand_y);
offset = ((rand() % 100) + 1) / 100.0f;
if (offset > (1.0f-rand_y))
offset = (1.0f-rand_y);
this->addKey(rand_x,
rand_y + offset,
rand_y);
}
//last node\key = 0
this->addKey(1.0f, 0.0f, 0.0f);
}
#endif

View File

@ -44,25 +44,35 @@ using namespace std;
using namespace vcg;
#define LOWER_Y 0
#define UPPER_Y 1
#define NUMBER_OF_JUNCTION_Y 2
//struct used to represent each point in the transfer function.
//It's composed of a position on x axis and two values on the y axis (potentially the same)
struct TF_KEY
{
enum
{
LOWER_Y = 0,
UPPER_Y
};
float y_upper;
float y_lower;
bool left_junction_point_code;
bool right_junction_point_code;
int left_junction_point_code;
int right_junction_point_code;
float getLeftJunctionPoint() { return left_junction_point_code == LOWER_Y ? y_lower : y_upper; }
float getRightJunctionPoint() { return right_junction_point_code == LOWER_Y ? y_lower : y_upper; }
void setLeftJunctionPoint( bool j_p ) { left_junction_point_code = j_p; right_junction_point_code = 1-left_junction_point_code; }
void setRightJunctionPoint( bool j_p ) { right_junction_point_code = j_p; left_junction_point_code = 1-right_junction_point_code; }
float getLeftJunctionPoint()
{
if (left_junction_point_code == LOWER_Y)
return y_lower;
else
return y_upper;
}
float getRightJunctionPoint()
{
if (right_junction_point_code == LOWER_Y)
return y_lower;
else
return y_upper;
}
inline void setLeftJunctionPoint( int j_p ) { left_junction_point_code = j_p; right_junction_point_code = NUMBER_OF_JUNCTION_Y-left_junction_point_code-1; }
inline void setRightJunctionPoint( int j_p ) { right_junction_point_code = j_p; left_junction_point_code = NUMBER_OF_JUNCTION_Y-right_junction_point_code-1; }
TF_KEY( float y_up=0.0f, float y_low=0.0f )
{
@ -73,12 +83,20 @@ struct TF_KEY
this->setLeftJunctionPoint(LOWER_Y);
}
void swapY() { float tmp=y_lower; y_lower=y_upper; y_upper=tmp; }
inline void swapY() { float tmp=y_lower; y_lower=y_upper; y_upper=tmp; this->setLeftJunctionPoint(right_junction_point_code); }
bool operator == (TF_KEY k) { return ( (y_lower == k.y_lower) && (y_upper == k.y_upper) ); }
};
#define TF_KEYsize sizeof(TF_KEY)
struct TF_CHANNEL_VALUE
{
float *x;
TF_KEY *y;
TF_CHANNEL_VALUE(float *x_val=0, TF_KEY *y_val=0)
{ x=x_val; y=y_val; }
};
//list of channels
enum TF_CHANNELS
@ -89,6 +107,23 @@ enum TF_CHANNELS
NUMBER_OF_CHANNELS
};
#define TYPE_2_COLOR(TYPE, COLOR) \
switch(TYPE) \
{ \
case RED_CHANNEL: \
COLOR = Qt::red; \
break; \
case GREEN_CHANNEL: \
COLOR = Qt::green; \
break; \
case BLUE_CHANNEL: \
COLOR = Qt::blue; \
break; \
default: \
COLOR = Qt::black; \
break; \
}
//defines a to class to menage the keys for a single channel
class TfChannel
{
@ -112,8 +147,8 @@ public:
float getChannelValuef(float x_position);
UINT8 getChannelValueb(float x_position);
TF_KEY* operator [](float i) { KEY_LISTiterator it= KEYS.find(i); if (it!=KEYS.end()) return &it->second; else return 0;}
TF_KEY* operator [](int i);
TF_CHANNEL_VALUE& operator [](float idx);
TF_CHANNEL_VALUE& operator [](int idx);
inline int size() { return KEYS.size(); }
#ifdef NOW_TESTING
@ -123,11 +158,12 @@ public:
private:
TF_CHANNELS _type;
int old_iterator_idx;
TF_CHANNEL_VALUE _ret_val;
//list of keys
KEY_LIST KEYS;
KEY_LISTiterator idx_it;
KEY_LISTiterator _idx_it;
};