Consider the following snippet:
// standard boiler plate code for creating actors. renderer, etc
vtkNew<vtkCallbackCommand> callback;
callback->SetCallback(CallbackFunction);
renderer->AddObserver(vtkCommand::EndEvent, callback);
and
void CallbackFunction(vtkObject *caller, long unsigned int eventId,
void *vtkNotUsed(clientData),
void *vtkNotUsed(callData)) {
vtkRenderer *renderer = static_cast<vtkRenderer *>(caller);
double timeInSeconds = renderer->GetLastRenderTimeInSeconds();
double fps = 1.0 / timeInSeconds;
std::cout << "FPS: " << fps << std::endl;
std::cout << "Callback" << std::endl;
std::cout << "eventId: " << eventId << std::endl;
}
I have use this code in
qt with qml frontend
qt with qt fronted
VTK window manager
In 2 and3 If user has no interaction with GUI, nothing will be called so you don’t see FPS and eventId (which 4) but in qml, there is constant call to the observer (even if there is not interaction with GUI), this will slow down the code when you are dealing with huge number of points, does anyone have any idea? @John Stone
jaswantp
(Jaswant Panchumarti (Kitware))
August 12, 2024, 2:38pm
2
Hello @Behnam_Asadi
I understand what you mean. It may be trigerred because someone is invalidating the state of qml item causing it to repaint. Can you share a callstack so we know where the function call vtkRenderer::Render()
comes from?
Thanks for quick reply, I paste here the entire code so you can experiment it:
cmake:
add_executable(vtk_forum_snippet src/vtk_forum_snippet.cpp qml.qrc )
target_link_libraries(vtk_forum_snippet PRIVATE ${VTK_LIBRARIES} ${PDAL_LIBRARIES} Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick Qt5::Widgets Qt${QT_VERSION_MAJOR}::Concurrent)
vtk_module_autoinit(TARGETS vtk_forum_snippet MODULES ${VTK_LIBRARIES})
cpp
#include <QQuickVTKItem.h>
#include <QQuickWindow>
#include <QVTKRenderWindowAdapter.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QSurfaceFormat>
#include <QtQml/QQmlApplicationEngine>
#include <QtQuick/QQuickWindow>
#include <vtkActor.h>
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkMinimalStandardRandomSequence.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPropPicker.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkSliderWidget.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkVertexGlyphFilter.h>
void CallbackFunction(vtkObject *caller, long unsigned int eventId,
void *vtkNotUsed(clientData),
void *vtkNotUsed(callData)) {
vtkRenderer *renderer = static_cast<vtkRenderer *>(caller);
double timeInSeconds = renderer->GetLastRenderTimeInSeconds();
double fps = 1.0 / timeInSeconds;
std::cout << "FPS: " << fps << std::endl;
std::cout << "Callback" << std::endl;
std::cout << "eventId: " << eventId << std::endl;
}
struct MyVtkItem : public QQuickVTKItem {
vtkUserData initializeVTK(vtkRenderWindow *renderWindow) override {
// Create a cone pipeline and add it to the view
vtkNew<vtkConeSource> cone;
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(cone->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor);
renderer->ResetCamera();
renderWindow->AddRenderer(renderer);
vtkNew<vtkCallbackCommand> callback;
callback->SetCallback(CallbackFunction);
renderer->AddObserver(vtkCommand::EndEvent, callback);
return nullptr;
}
bool event(QEvent *event) override {
qDebug() << "-------------------------";
QEvent::Type type = event->type();
switch (type) {
case QEvent::None:
qDebug() << "None";
case QEvent::Timer:
qDebug() << "Timer";
case QEvent::MouseButtonPress:
qDebug() << "MouseButtonPress";
case QEvent::MouseButtonRelease:
qDebug() << "MouseButtonRelease";
case QEvent::MouseButtonDblClick:
qDebug() << "MouseButtonDblClick";
case QEvent::MouseMove:
qDebug() << "MouseMove";
case QEvent::KeyPress:
qDebug() << "KeyPress";
case QEvent::KeyRelease:
qDebug() << "KeyRelease";
case QEvent::FocusIn:
qDebug() << "FocusIn";
case QEvent::FocusOut:
qDebug() << "FocusOut";
case QEvent::Enter:
qDebug() << "Enter";
case QEvent::Leave:
qDebug() << "Leave";
case QEvent::Paint:
qDebug() << "Paint";
case QEvent::Move:
qDebug() << "Move";
case QEvent::Resize:
qDebug() << "Resize";
case QEvent::Close:
qDebug() << "Close";
// Add other cases as needed
default:
qDebug() << QString("Unknown(%1)").arg(static_cast<int>(type));
}
return QQuickVTKItem::event(event);
}
QSGNode *updatePaintNode(QSGNode *q, UpdatePaintNodeData *u) override {
std::cout << "updatePaintNode" << std::endl;
return QQuickVTKItem::updatePaintNode(q, u);
}
bool isTextureProvider() const override {
std::cout << "isTextureProvider" << std::endl;
return QQuickVTKItem::isTextureProvider();
}
// QSGTextureProvider* textureProvider() const override{}
// void releaseResources() override{}
};
int main(int argc, char *argv[]) {
QQuickVTKItem::setGraphicsApi();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterType<MyVtkItem>("com.vtk.example", 1, 0, "MyVtkItem");
QQmlApplicationEngine engine;
engine.addImportPath("/home/behnam/usr/lib/qml");
engine.load(QUrl("qrc:/qml/vtk_basic.qml"));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
qml (vtk_basic.qml):
import QtQuick 2.9
import QtQuick.Window 2.2
import com.vtk.example 1.0
Window {
id: win
visible: true
width: 640
height: 640
title: qsTr("Hello World")
Rectangle {
anchors.fill: parent
color: "darkseagreen"
}
Rectangle {
id: r
border { width: 5; color: "steelblue" }
radius: 5
color: "hotpink"
anchors.fill: parent
anchors.margins: 100
MyVtkItem {
id: vtk
anchors.fill: parent
anchors.margins: 5
opacity: 0.7
}
}
}
qml.qrc
<RCC>
<qresource prefix="/">
<file>qml/vtk_basic.qml</file>
</qresource>
</RCC>
BTW, Qt5.15 and VTK9.3