qml vtk integration issue

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

  1. qt with qml frontend
  2. qt with qt fronted
  3. 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

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