You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.7 KiB
C++
110 lines
2.7 KiB
C++
|
2 weeks ago
|
|
||
|
|
|
||
|
|
#include "QVTKPaintEngine.h"
|
||
|
|
#include "QVTKWidget.h"
|
||
|
|
|
||
|
|
#include "vtkRenderWindow.h"
|
||
|
|
#include "vtkRenderer.h"
|
||
|
|
#include "vtkImageData.h"
|
||
|
|
#include "vtkSmartPointer.h"
|
||
|
|
|
||
|
|
#include <QCache>
|
||
|
|
#include <QPainterPath>
|
||
|
|
|
||
|
|
class QVTKPaintEngineInternal
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
// cache of pixmaps
|
||
|
|
QCache<qint64, vtkSmartPointer<vtkImageData> > mImageCache;
|
||
|
|
};
|
||
|
|
|
||
|
|
QVTKPaintEngine::QVTKPaintEngine()
|
||
|
|
: QPaintEngine(QPaintEngine::PaintOutsidePaintEvent |
|
||
|
|
QPaintEngine::AlphaBlend)
|
||
|
|
{
|
||
|
|
this->Internal = new QVTKPaintEngineInternal;
|
||
|
|
}
|
||
|
|
|
||
|
|
QVTKPaintEngine::~QVTKPaintEngine()
|
||
|
|
{
|
||
|
|
delete this->Internal;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool QVTKPaintEngine::begin(QPaintDevice* dev)
|
||
|
|
{
|
||
|
|
Widget = static_cast<QVTKWidget*>(dev);
|
||
|
|
//Widget->GetRenderWindow()->MakeCurrent();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool QVTKPaintEngine::end()
|
||
|
|
{
|
||
|
|
//Widget->GetRenderWindow()->Frame();
|
||
|
|
Widget = NULL;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
QPaintEngine::Type QVTKPaintEngine::type() const
|
||
|
|
{
|
||
|
|
return QPaintEngine::OpenGL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void QVTKPaintEngine::updateState(const QPaintEngineState&)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
// at a minimum, we only need to re-implement this drawPixmap function.
|
||
|
|
// Qt can do all other drawing to create a pixmap and then we draw it here.
|
||
|
|
void QVTKPaintEngine::drawPixmap(const QRectF& r, const QPixmap& pm, const QRectF& sr)
|
||
|
|
{
|
||
|
|
if(!this->Widget)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
QRect ri = r.toRect();
|
||
|
|
QRect sri = sr.toRect();
|
||
|
|
|
||
|
|
QPixmap pix = pm.copy(sri);
|
||
|
|
if(sri.size() != ri.size())
|
||
|
|
{
|
||
|
|
pix = pix.scaled(ri.size());
|
||
|
|
}
|
||
|
|
|
||
|
|
QImage img = pix.toImage().mirrored().rgbSwapped();
|
||
|
|
|
||
|
|
// blend the pixels from QImage into the vtkRenderWindow's buffer
|
||
|
|
vtkRenderWindow* renWin = this->Widget->GetRenderWindow();
|
||
|
|
renWin->SetRGBACharPixelData(ri.left(), this->Widget->height() - ri.top() - ri.height(),
|
||
|
|
ri.left()+img.width() - 1,
|
||
|
|
this->Widget->height() - ri.top() - 1,
|
||
|
|
img.bits(),
|
||
|
|
renWin->GetDoubleBuffer() ? 0 : 1,
|
||
|
|
1);
|
||
|
|
|
||
|
|
// NOTE: this would perform much better if textures were used and caching of those
|
||
|
|
// textures was done (probably vtkActor2D and vtkImageMapper)
|
||
|
|
}
|
||
|
|
|
||
|
|
void QVTKPaintEngine::drawPath(const QPainterPath& path)
|
||
|
|
{
|
||
|
|
// drawPath in base class does nothing so here we make it do something
|
||
|
|
QRectF box = path.boundingRect();
|
||
|
|
QPixmap img((int)box.width(), (int)box.height());
|
||
|
|
img.fill(Qt::transparent);
|
||
|
|
QPainter p(&img);
|
||
|
|
p.translate(-box.left(), -box.right());
|
||
|
|
p.drawPath(path);
|
||
|
|
this->drawPixmap(QRectF(QPoint(0,0), img.size()), img, box);
|
||
|
|
}
|
||
|
|
|
||
|
|
void QVTKPaintEngine::drawPolygon(const QPointF* /*points*/, int /*pointCount*/,
|
||
|
|
PolygonDrawMode /*mode*/)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void QVTKPaintEngine::drawPolygon(const QPoint* /*points*/, int /*pointCount*/,
|
||
|
|
PolygonDrawMode /*mode*/)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|