Преглед изворни кода

COMP: Support building against VTK version introducing QVTKOpenGLNativeWidget

Related Slicer issue https://issues.slicer.org/view.php?id=4598

Following VTK commit kitware/VTK@45704131f, QVTKOpenGLWidget was renamed
to QVTKOpenGLSimpleWidget and the QVTKOpenGLWidget class was updated to be
able to work with a  Qt OpenGL context (though the use of a new class named
QVTKOpenGLWindow).

These changes were initially motivated to support creating stereo-capable
applications that needs multiple framebuffers. The updated class also provides
a better management of OpenGL resources (check for valid resources, reduces
flickering ...) and also adds support for HiDPI. But there are some gotchas
discussed below.

Then, following VTK commit kitware/VTK@fd9cdefeb, QVTKOpenGLSimpleWidget
was renamed to QVTKOpenGLNativeWidget


Why not keep using QVTKOpenGLWidget ?
-------------------------------------

It turns out that using the "new" QVTKOpenGLWidget is not possible when
it is the child of a QScrollArea or QMdiArea. In that case, the widget
will be changed into a "Native" one, and this is not supported.

Waiting the QVTKOpenGLWidget is improved to gracefully handle the different
use cases, this commit simply make use of QVTKOpenGLNativeWidget when it
is available.


Note about "black" screen issue
-------------------------------

An issue impacting using of older QVTKOpenGLWidget or newer QVTKOpenGLSimpleWidget
was fixed in 1c33914aa (Fix issue where picking happened with a bad context).
This was causing the entire application to turn black when the user
attempted to using picking in a render window. Regression originally
introduced in kitware/VTK@1eb083a80 (use hardwareselector to perform picking)

See https://gitlab.kitware.com/vtk/vtk/issues/17370


Which version of VTK are supported ?
------------------------------------

The renaming of QVTKOpenGLSimpleWidget to QVTKOpenGLNativeWidget and the
fix for the "back screen" issue means that using VTK version between
kitware/VTK@1eb083a80~1 and kitware/VTK@fd9cdefeb~1 will most result
in broken CTK build or improperly working application.
Jean-Christophe Fillion-Robin пре 7 година
родитељ
комит
ced0f1b6d6

+ 31 - 0
Libs/Visualization/VTK/Widgets/CMakeLists.txt

@@ -206,10 +206,33 @@ if(CTK_QT_VERSION VERSION_LESS "5"
   OR (NOT VTK_RENDERING_BACKEND STREQUAL "OpenGL2"))
   OR (NOT VTK_RENDERING_BACKEND STREQUAL "OpenGL2"))
   set(_use_qvtkopenglwidget 0)
   set(_use_qvtkopenglwidget 0)
 endif()
 endif()
+
 if(_use_qvtkopenglwidget)
 if(_use_qvtkopenglwidget)
   add_definitions(-DCTK_USE_QVTKOPENGLWIDGET)
   add_definitions(-DCTK_USE_QVTKOPENGLWIDGET)
 endif()
 endif()
 
 
+# Detect if QVTKOpenGLNativeWidget.h is available
+set(_has_QVTKOpenGLNativeWidget_h 0)
+if(_use_qvtkopenglwidget)
+  set(_msg "Checking if QVTKOpenGLNativeWidget.h exists")
+  message(STATUS "${_msg}")
+  foreach(include_dir IN ITEMS ${vtkGUISupportQt_INCLUDE_DIRS})
+    if(EXISTS "${include_dir}/QVTKOpenGLNativeWidget.h")
+      set(_has_QVTKOpenGLNativeWidget_h 1)
+      break()
+    endif()
+  endforeach()
+  if(_has_QVTKOpenGLNativeWidget_h)
+    message(STATUS "${_msg} - found")
+  else()
+    message(STATUS "${_msg} - not found")
+  endif()
+endif()
+
+if(_has_QVTKOpenGLNativeWidget_h)
+  add_definitions(-DCTK_HAS_QVTKOPENGLNATIVEWIDGET_H)
+endif()
+
 ctkMacroBuildLib(
 ctkMacroBuildLib(
   NAME ${PROJECT_NAME}
   NAME ${PROJECT_NAME}
   EXPORT_DIRECTIVE ${KIT_export_directive}
   EXPORT_DIRECTIVE ${KIT_export_directive}
@@ -229,6 +252,14 @@ if(_use_qvtkopenglwidget)
     )
     )
 endif()
 endif()
 
 
+if(_has_QVTKOpenGLNativeWidget_h)
+  target_compile_definitions(
+    ${PROJECT_NAME}
+    INTERFACE
+      CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+    )
+endif()
+
 if(CTK_WRAP_PYTHONQT_LIGHT)
 if(CTK_WRAP_PYTHONQT_LIGHT)
   ctkMacroBuildLibWrapper(
   ctkMacroBuildLibWrapper(
     TARGET ${PROJECT_NAME}
     TARGET ${PROJECT_NAME}

+ 12 - 4
Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.cpp

@@ -48,7 +48,7 @@ int ctkVTKAbstractViewPrivate::MultiSamples = 0;  // Default for static var
 ctkVTKAbstractViewPrivate::ctkVTKAbstractViewPrivate(ctkVTKAbstractView& object)
 ctkVTKAbstractViewPrivate::ctkVTKAbstractViewPrivate(ctkVTKAbstractView& object)
   : q_ptr(&object)
   : q_ptr(&object)
 {
 {
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
   this->RenderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
   this->RenderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
 #else
 #else
   this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
   this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
@@ -69,8 +69,12 @@ void ctkVTKAbstractViewPrivate::init()
 
 
   this->setParent(q);
   this->setParent(q);
 
 
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+  this->VTKWidget = new QVTKOpenGLNativeWidget;
+# else
   this->VTKWidget = new QVTKOpenGLWidget;
   this->VTKWidget = new QVTKOpenGLWidget;
+# endif
   this->VTKWidget->setEnableHiDPI(true);
   this->VTKWidget->setEnableHiDPI(true);
   QObject::connect(this->VTKWidget, SIGNAL(resized()),
   QObject::connect(this->VTKWidget, SIGNAL(resized()),
                    q, SLOT(forceRender()));
                    q, SLOT(forceRender()));
@@ -296,8 +300,12 @@ vtkCornerAnnotation* ctkVTKAbstractView::cornerAnnotation() const
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+QVTKOpenGLNativeWidget * ctkVTKAbstractView::VTKWidget() const
+# else
 QVTKOpenGLWidget * ctkVTKAbstractView::VTKWidget() const
 QVTKOpenGLWidget * ctkVTKAbstractView::VTKWidget() const
+# endif
 #else
 #else
 QVTKWidget * ctkVTKAbstractView::VTKWidget() const
 QVTKWidget * ctkVTKAbstractView::VTKWidget() const
 #endif
 #endif
@@ -480,7 +488,7 @@ void ctkVTKAbstractView::setUseDepthPeeling(bool useDepthPeeling)
     }
     }
   this->renderWindow()->SetMultiSamples(useDepthPeeling ? 0 : nSamples);
   this->renderWindow()->SetMultiSamples(useDepthPeeling ? 0 : nSamples);
   renderer->SetUseDepthPeeling(useDepthPeeling ? 1 : 0);
   renderer->SetUseDepthPeeling(useDepthPeeling ? 1 : 0);
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
   renderer->SetUseDepthPeelingForVolumes(useDepthPeeling);
   renderer->SetUseDepthPeelingForVolumes(useDepthPeeling);
 #endif
 #endif
 }
 }

+ 11 - 3
Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.h

@@ -25,8 +25,12 @@
 #include <QWidget>
 #include <QWidget>
 
 
 // VTK includes
 // VTK includes
-#if CTK_USE_QVTKOPENGLWIDGET
-#include <QVTKOpenGLWidget.h>
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+#  include <QVTKOpenGLNativeWidget.h>
+# else
+#  include <QVTKOpenGLWidget.h>
+# endif
 #else
 #else
 #include <QVTKWidget.h>
 #include <QVTKWidget.h>
 #endif
 #endif
@@ -149,8 +153,12 @@ public:
   Q_INVOKABLE vtkCornerAnnotation* cornerAnnotation()const;
   Q_INVOKABLE vtkCornerAnnotation* cornerAnnotation()const;
 
 
   /// Get the underlying QVTKWidget
   /// Get the underlying QVTKWidget
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+  Q_INVOKABLE QVTKOpenGLNativeWidget * VTKWidget() const;
+# else
   Q_INVOKABLE QVTKOpenGLWidget * VTKWidget() const;
   Q_INVOKABLE QVTKOpenGLWidget * VTKWidget() const;
+# endif
 #else
 #else
   Q_INVOKABLE QVTKWidget * VTKWidget() const;
   Q_INVOKABLE QVTKWidget * VTKWidget() const;
 #endif
 #endif

+ 5 - 1
Libs/Visualization/VTK/Widgets/ctkVTKAbstractView_p.h

@@ -57,8 +57,12 @@ public:
   QList<vtkRenderer*> renderers()const;
   QList<vtkRenderer*> renderers()const;
   vtkRenderer* firstRenderer()const;
   vtkRenderer* firstRenderer()const;
 
 
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+  QVTKOpenGLNativeWidget*                       VTKWidget;
+# else
   QVTKOpenGLWidget*                             VTKWidget;
   QVTKOpenGLWidget*                             VTKWidget;
+# endif
   vtkSmartPointer<vtkGenericOpenGLRenderWindow> RenderWindow;
   vtkSmartPointer<vtkGenericOpenGLRenderWindow> RenderWindow;
 #else
 #else
   QVTKWidget*                                   VTKWidget;
   QVTKWidget*                                   VTKWidget;

+ 3 - 3
Libs/Visualization/VTK/Widgets/ctkVTKChartView.cpp

@@ -52,7 +52,7 @@ public:
   void init();
   void init();
   void chartBounds(double* bounds)const;
   void chartBounds(double* bounds)const;
 
 
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
   vtkSmartPointer<vtkGenericOpenGLRenderWindow> RenderWindow;
   vtkSmartPointer<vtkGenericOpenGLRenderWindow> RenderWindow;
 #endif
 #endif
   vtkSmartPointer<vtkContextView> ContextView;
   vtkSmartPointer<vtkContextView> ContextView;
@@ -69,7 +69,7 @@ ctkVTKChartViewPrivate::ctkVTKChartViewPrivate(ctkVTKChartView& object)
   :q_ptr(&object)
   :q_ptr(&object)
 {
 {
   this->ContextView = vtkSmartPointer<vtkContextView>::New();
   this->ContextView = vtkSmartPointer<vtkContextView>::New();
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
   this->RenderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
   this->RenderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
 #endif
 #endif
   this->Chart = vtkSmartPointer<vtkChartXY>::New();
   this->Chart = vtkSmartPointer<vtkChartXY>::New();
@@ -84,7 +84,7 @@ ctkVTKChartViewPrivate::ctkVTKChartViewPrivate(ctkVTKChartView& object)
 void ctkVTKChartViewPrivate::init()
 void ctkVTKChartViewPrivate::init()
 {
 {
   Q_Q(ctkVTKChartView);
   Q_Q(ctkVTKChartView);
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
   q->SetRenderWindow(this->RenderWindow);
   q->SetRenderWindow(this->RenderWindow);
   this->ContextView->SetRenderWindow(this->RenderWindow);
   this->ContextView->SetRenderWindow(this->RenderWindow);
 #endif
 #endif

+ 16 - 4
Libs/Visualization/VTK/Widgets/ctkVTKChartView.h

@@ -27,8 +27,12 @@
 class ctkVTKChartViewPrivate;
 class ctkVTKChartViewPrivate;
 
 
 // VTK includes
 // VTK includes
-#if CTK_USE_QVTKOPENGLWIDGET
-#include <QVTKOpenGLWidget.h>
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+#  include <QVTKOpenGLNativeWidget.h>
+# else
+#  include <QVTKOpenGLWidget.h>
+# endif
 #else
 #else
 #include <QVTKWidget.h>
 #include <QVTKWidget.h>
 #endif
 #endif
@@ -38,8 +42,12 @@ class vtkContextScene;
 class vtkPlot;
 class vtkPlot;
 
 
 /// \ingroup Visualization_VTK_Widgets
 /// \ingroup Visualization_VTK_Widgets
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKOpenGLNativeWidget
+# else
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKOpenGLWidget
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKOpenGLWidget
+# endif
 #else
 #else
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKWidget
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKWidget
 #endif
 #endif
@@ -49,8 +57,12 @@ class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKWidget
   Q_PROPERTY(QString title READ title WRITE setTitle)
   Q_PROPERTY(QString title READ title WRITE setTitle)
 
 
 public:
 public:
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+  typedef QVTKOpenGLNativeWidget Superclass;
+# else
   typedef QVTKOpenGLWidget Superclass;
   typedef QVTKOpenGLWidget Superclass;
+# endif
 #else
 #else
   typedef QVTKWidget Superclass;
   typedef QVTKWidget Superclass;
 #endif
 #endif

+ 17 - 5
Libs/Visualization/VTK/Widgets/ctkVTKDiscretizableColorTransferWidget.cpp

@@ -46,8 +46,12 @@
 #include <QWidgetAction>
 #include <QWidgetAction>
 
 
 // VTK includes
 // VTK includes
-#if CTK_USE_QVTKOPENGLWIDGET
-#include <QVTKOpenGLWidget.h>
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+#  include <QVTKOpenGLNativeWidget.h>
+# else
+#  include <QVTKOpenGLWidget.h>
+# endif
 #else
 #else
 #include <QVTKWidget.h>
 #include <QVTKWidget.h>
 #endif
 #endif
@@ -93,8 +97,12 @@ public:
   bool popRangesFromHistory(double* currentRange, double* visibleRange);
   bool popRangesFromHistory(double* currentRange, double* visibleRange);
   void clearUndoHistory();
   void clearUndoHistory();
 
 
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+  QVTKOpenGLNativeWidget* ScalarsToColorsView;
+# else
   QVTKOpenGLWidget* ScalarsToColorsView;
   QVTKOpenGLWidget* ScalarsToColorsView;
+# endif
 #else
 #else
   QVTKWidget* ScalarsToColorsView;
   QVTKWidget* ScalarsToColorsView;
 #endif
 #endif
@@ -160,8 +168,12 @@ void ctkVTKDiscretizableColorTransferWidgetPrivate::setupUi(QWidget* widget)
 
 
   this->Ui_ctkVTKDiscretizableColorTransferWidget::setupUi(widget);
   this->Ui_ctkVTKDiscretizableColorTransferWidget::setupUi(widget);
 
 
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
+# ifdef CTK_HAS_QVTKOPENGLNATIVEWIDGET_H
+  this->ScalarsToColorsView = new QVTKOpenGLNativeWidget;
+# else
   this->ScalarsToColorsView = new QVTKOpenGLWidget;
   this->ScalarsToColorsView = new QVTKOpenGLWidget;
+# endif
 #else
 #else
   this->ScalarsToColorsView = new QVTKWidget;
   this->ScalarsToColorsView = new QVTKWidget;
 #endif
 #endif
@@ -173,7 +185,7 @@ void ctkVTKDiscretizableColorTransferWidgetPrivate::setupUi(QWidget* widget)
 
 
   this->scalarsToColorsContextView = vtkSmartPointer<vtkContextView> ::New();
   this->scalarsToColorsContextView = vtkSmartPointer<vtkContextView> ::New();
 
 
-#if CTK_USE_QVTKOPENGLWIDGET
+#ifdef CTK_USE_QVTKOPENGLWIDGET
   vtkSmartPointer<vtkGenericOpenGLRenderWindow> renwin =
   vtkSmartPointer<vtkGenericOpenGLRenderWindow> renwin =
     vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
     vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
   this->ScalarsToColorsView->SetRenderWindow(renwin);
   this->ScalarsToColorsView->SetRenderWindow(renwin);