lynchkp
8th March 2011, 20:11
Hello,
I'm trying to display a dense vector field (at times >10,000 vectors) over an image. My primary problem is that when scrolling across the image, the performance is quite laggy and the drawing time is quite substantial. I've looked online for a number of qgraphicsscene optimizations, but I haven't noticed too big of a performance improvement. Perhaps I'm missing something quite minor, I'm pretty new at using these graphics objects. I've attached images of the display. The current drawing time is around 300 msec.
I've implemented each of these as a QGraphicsItem. The class is given below:
VectorItem::VectorItem(const qpiv_vector &vec,
const qpiv_settings &settings,
int idx_i)
{
idx = idx_i;
scale_max = settings.scale_max;
snr = vec.snr;
vec_color_type = settings.vec_color_type;
highlight_flag = settings.highlight_flag;
interp = vec.interp;
dmag = sqrt( pow(vec.dx-settings.subtract_x,2) + pow(vec.dy-settings.subtract_y,2) );
x2 = dmag*settings.vec_scale_factor;
y2 = 0;
upper_x = x2 - 0.15*x2;
lower_x = upper_x;
upper_y = y2 + 0.07*x2;
lower_y = y2 - 0.07*x2;
this->setPos(vec.x,vec.y);
this->setRotation(atan2(vec.dy-settings.subtract_y,vec.dx-settings.subtract_x)*180/M_PI);
this->setAcceptHoverEvents(true);
// Pen definition.
findColor();
textPen.setWidth(2);
textPen.setCapStyle(Qt::RoundCap);
textPen.setColor(color);
// BoundingRect definition.
points.resize(3);
points[0] = QLineF(0,0,x2,y2);
points[1] = QLineF(upper_x,upper_y,x2,y2);
points[2] = QLineF(lower_x,lower_y,x2,y2);
// Shape definition.
points2.resize(8);
points2[0] = QPointF(-1,-1);
points2[1] = QPointF(-1,1);
points2[2] = QPointF(upper_x -1, 1);
points2[3] = QPointF(upper_x -1, upper_y +1);
points2[4] = QPointF(x2 + 1 , 0);
points2[5] = QPointF(lower_x -1, lower_y -1);
points2[6] = QPointF(lower_x -1, -1);
points2[7] = QPointF(-1,-1);
QPolygonF polygon(points2);
path.addPolygon(polygon);
}
QRectF VectorItem::boundingRect() const {
return QRectF(-x2-2,-x2-2,2*x2+2,2*x2+2);
}
QPainterPath VectorItem::shape() const {
return path;
}
void VectorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
painter->setPen(textPen);
painter->drawLines(points);
}
void VectorItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) {
textPen.setWidth(4);
this->update(this->boundingRect());
}
void VectorItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ) {
textPen.setWidth(2);
this->update(this->boundingRect());
}
void VectorItem::mousePressEvent ( QGraphicsSceneMouseEvent * event ) {
openInfoDialog(idx);
}
void VectorItem::findColor() {
int idx;
if (vec_color_type == COLOR_VMAG) {
idx = floor((dmag/scale_max)*COLORMAP_SIZE);
} else if (vec_color_type == COLOR_SNR) {
idx = floor(((snr-0.5)/2.5)*COLORMAP_SIZE);
}
if (idx > COLORMAP_SIZE) {
idx = COLORMAP_SIZE;
}
if ((highlight_flag == true) && (interp == false)) {
color = Qt::white;
} else {
color = qRgb(jet_colormap[idx][1],jet_colormap[idx][2],jet_colormap[idx][3]);
}
}
And the implementation of the class:
for (int idx = 0; idx < grid.n; idx++) {
VectorItem *newarrow =
new VectorItem(vec.at(idx),settings,idx);
connect(newarrow,SIGNAL(openInfoDialog(int)),this, SLOT(openInfoDialog(int)));
scene->addItem(newarrow);
}
Any help would be greatly appreciated!!!
I'm trying to display a dense vector field (at times >10,000 vectors) over an image. My primary problem is that when scrolling across the image, the performance is quite laggy and the drawing time is quite substantial. I've looked online for a number of qgraphicsscene optimizations, but I haven't noticed too big of a performance improvement. Perhaps I'm missing something quite minor, I'm pretty new at using these graphics objects. I've attached images of the display. The current drawing time is around 300 msec.
I've implemented each of these as a QGraphicsItem. The class is given below:
VectorItem::VectorItem(const qpiv_vector &vec,
const qpiv_settings &settings,
int idx_i)
{
idx = idx_i;
scale_max = settings.scale_max;
snr = vec.snr;
vec_color_type = settings.vec_color_type;
highlight_flag = settings.highlight_flag;
interp = vec.interp;
dmag = sqrt( pow(vec.dx-settings.subtract_x,2) + pow(vec.dy-settings.subtract_y,2) );
x2 = dmag*settings.vec_scale_factor;
y2 = 0;
upper_x = x2 - 0.15*x2;
lower_x = upper_x;
upper_y = y2 + 0.07*x2;
lower_y = y2 - 0.07*x2;
this->setPos(vec.x,vec.y);
this->setRotation(atan2(vec.dy-settings.subtract_y,vec.dx-settings.subtract_x)*180/M_PI);
this->setAcceptHoverEvents(true);
// Pen definition.
findColor();
textPen.setWidth(2);
textPen.setCapStyle(Qt::RoundCap);
textPen.setColor(color);
// BoundingRect definition.
points.resize(3);
points[0] = QLineF(0,0,x2,y2);
points[1] = QLineF(upper_x,upper_y,x2,y2);
points[2] = QLineF(lower_x,lower_y,x2,y2);
// Shape definition.
points2.resize(8);
points2[0] = QPointF(-1,-1);
points2[1] = QPointF(-1,1);
points2[2] = QPointF(upper_x -1, 1);
points2[3] = QPointF(upper_x -1, upper_y +1);
points2[4] = QPointF(x2 + 1 , 0);
points2[5] = QPointF(lower_x -1, lower_y -1);
points2[6] = QPointF(lower_x -1, -1);
points2[7] = QPointF(-1,-1);
QPolygonF polygon(points2);
path.addPolygon(polygon);
}
QRectF VectorItem::boundingRect() const {
return QRectF(-x2-2,-x2-2,2*x2+2,2*x2+2);
}
QPainterPath VectorItem::shape() const {
return path;
}
void VectorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
painter->setPen(textPen);
painter->drawLines(points);
}
void VectorItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) {
textPen.setWidth(4);
this->update(this->boundingRect());
}
void VectorItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ) {
textPen.setWidth(2);
this->update(this->boundingRect());
}
void VectorItem::mousePressEvent ( QGraphicsSceneMouseEvent * event ) {
openInfoDialog(idx);
}
void VectorItem::findColor() {
int idx;
if (vec_color_type == COLOR_VMAG) {
idx = floor((dmag/scale_max)*COLORMAP_SIZE);
} else if (vec_color_type == COLOR_SNR) {
idx = floor(((snr-0.5)/2.5)*COLORMAP_SIZE);
}
if (idx > COLORMAP_SIZE) {
idx = COLORMAP_SIZE;
}
if ((highlight_flag == true) && (interp == false)) {
color = Qt::white;
} else {
color = qRgb(jet_colormap[idx][1],jet_colormap[idx][2],jet_colormap[idx][3]);
}
}
And the implementation of the class:
for (int idx = 0; idx < grid.n; idx++) {
VectorItem *newarrow =
new VectorItem(vec.at(idx),settings,idx);
connect(newarrow,SIGNAL(openInfoDialog(int)),this, SLOT(openInfoDialog(int)));
scene->addItem(newarrow);
}
Any help would be greatly appreciated!!!