[vtkusers] Using VTK and QT on Linux

myk myk321 at gmail.com
Thu Apr 28 09:09:33 EDT 2016


I've been trying to get VTK and Qt working on Linux.  I happened on a
setup the other day and thought I would share what worked for me.  To
cut to the chase what worked is: VTK 6.1 + Qt 5.3 + QVTKWidget2 +
OpenGL (not OpenGL2) on a non intel-graphics stack.  I've tried this
successfully on AMD graphics cards and unsuccessfully on intel graphics
running open source drivers under MESA (Gallium).  I tried VTK7.0 in
about 8 combinations (on intel) without success.

I got to this solution based partly with google and of course piles of
experimentation.  The rules, as I understand them, are as follows:

(a) QVTKWidget does not work on intel i915 drivers because it does not
return a depth buffer
-> Supposedly using QVTKWidget2 works around this but in my experience
that also does not work - so if you have intel graphics it seems you
need to either add some AMD or Nvidia (aahh!) graphics hardware or get
windows (double aaah!!!)
Ref: http://public.kitware.com/pipermail/vtk-developers/2014-May/014998
.html

(b) When compiling with OpenGL2, the QVTKWidget2 object is not included
in the .so, so you can't link.  So to get the object created you need
to build with OpenGL and NOT OpenGL2
http://comments.gmane.org/gmane.comp.lib.vtk.user/78123

(c) QVTKWidget2 requires Qt version of 5.3 or lower
http://stackoverflow.com/questions/26944831/using-qvtkwidget-and-qopeng
lwidget-in-the-same-ui

(d) QVTKWidget2 was broken in VTK 6.2 onwards and thus you need to
build with vtk 6.1.  Refer to GitHub to get it.
Ref: http://vtk.1045678.n5.nabble.com/QVTKWidget2-status-td5732729.html

(e) For VTK 6.1 you need to build it special command line parameters
Ref: http://stackoverflow.com/questions/28761702/getting-error-glintptr
-has-not-been-declared-when-building-vtk-on-linux

On Fedora 23 on amd64, I download:
Qt to the default ~/Qt/5.3
VTK 6.1 to ~/VTK-6.1.0
I build in ~/vtk61-qt53
where 
	~ = /home/myk
I completed the one-off VTK build with following commands:
	cd ~/vtk61-qt53
	cmake -DVTK_QT_VERSION:STRING=5 \
       -DCMAKE_BUILD_TYPE=Release \
      -DQT_QMAKE_EXECUTABLE:PATH=/home/myk/Qt/5.3/gcc_64/bin/qmake \
      -DVTK_Group_Qt:BOOL=ON \
      -DCMAKE_PREFIX_PATH:PATH=/home/myk/Qt/5.3/gcc_64/lib/cmake \
      -DBUILD_SHARED_LIBS:BOOL=ON \
      -DCMAKE_C_FLAGS=-DGLX_GLXEXT_LEGACY \
      -DCMAKE_CXX_FLAGS=-DGLX_GLXEXT_LEGACY \
      -Wno-dev \
      ../VTK-6.1.0
	make -j4
	sudo make install

For the 'make -j4' replace the '4' with the number of cores on your
machine - in my experience this is worth the effort!

I then use cmake in a .../build directory with the following command:
cmake -DVTK_QT_VERSION:STRING="5"
-DCMAKE_PREFIX_PATH=/home/myk/Qt/5.3/gcc_64/
-DCMAKE_PREFIX_PATH=/home/myk/Qt/5.3/gcc_64/lib/cmake/Qt5Widgets/
-DVTK_DIR=/usr/local/include/vtk-6.1/ -DCMAKE_BUILD_TYPE=Debug ..
make

Finally I've inserted some very basic Qt + VTK code below that creates
a QVKWidget2 so you can test the results (my apologies for my funny c
style programming with C++ comments).

Please call out if you have another combination which works on linux or
have found a way around any of these issues.

Kind regards,
Michael

PS: Some additional pointers:
(1) In my experience you can't have both a QVTKWidget and a QVTKWidget2
displayed on the same window at the same time - the QVTKWidget will
display but not the QVTKWidget2, so you need to be consistent.
(2) If you create two VTKWidget2's and give them both the same
renderer, the first QVTKWidget2 one will display junk and generate
OpenGL errors when you interact with it, while the second QVTKWidget
will work just fine. 
(3) If you try any of this with Intel graphics hardware under MESA
expect to just get OpenGL errors.


-------------------Widget2.cxx
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QToolBar>
#include <QDesktopWidget>

#include <QVTKWidget.h>
#include <QVTKWidget2.h>

#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkNew.h>
#include <vtkSphereSource.h>
#include <vtkAppendPolyData.h>
#include <vtkCamera.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkGenericOpenGLRenderWindow.h>

int main(int argc,char* argv[]) {

        QApplication app(argc,argv); 
        QMainWindow MainWindow;

	//Give the window a reasonable initial size
	QDesktopWidget Desktop;
	MainWindow.setFixedSize(Desktop.width()*0.7,
Desktop.height()*0.5);

        //Create the VTK widgets
	QVTKWidget* widget = new QVTKWidget();
	QVTKWidget2* widget2 = new QVTKWidget2();
        
	//Layout the VTK widgets in a horizontal format
    	QHBoxLayout *HorLayout = new QHBoxLayout();
        //HorLayout->addWidget(widget);
	HorLayout->addWidget(widget2);

	QWidget *LayoutWidget = new QWidget();
        LayoutWidget->setLayout(HorLayout);
	MainWindow.setCentralWidget(LayoutWidget);

	//Create the spheres to display
	vtkSmartPointer<vtkAppendPolyData> translucentGeometry =
vtkSmartPointer<vtkAppendPolyData>::New();
	for (int i = 0; i < 5; i++) {
		vtkSmartPointer<vtkSphereSource> sphereSource =	
vtkSmartPointer<vtkSphereSource>::New();
		sphereSource->SetThetaResolution(100);
		sphereSource->SetPhiResolution(100);
		sphereSource->SetRadius(0.5); // all spheres except the
center one should have radius = 0.5
		switch (i) {
		case 0:
			sphereSource->SetRadius(1);
			sphereSource->SetCenter(0, 0, 0); break;
		case 1:
			sphereSource->SetCenter(1, 0, 0); break;
		case 2:
			sphereSource->SetCenter(-1, 0, 0); break;
		case 3:
			sphereSource->SetCenter(0, 1, 0); break;
		case 4:
			sphereSource->SetCenter(0, -1, 0); break;
		}
		sphereSource->Update();
		translucentGeometry->AddInputConnection(sphereSource-
>GetOutputPort());
	}

	//Create the mapper
	vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(translucentGeometry-
>GetOutputPort());


	//Create the actor
	vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);
    	actor->GetProperty()->SetOpacity(1);		//1=
Spheres are fully opaque; 0 = spheres are fully transparent; 0.5 =
transparent
	actor->GetProperty()->SetColor(1, 0, 0);	//Red spheres
	actor->RotateX(-72); // put the objects in a position where it
is easy to see 

	//Create the renderer
	vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(actor);
	renderer->SetBackground(1, 1, 1);	//white background

	//Create the renderer2
	vtkSmartPointer<vtkRenderer> renderer2 =
vtkSmartPointer<vtkRenderer>::New();
	renderer2->AddActor(actor);
	renderer2->SetBackground(1, 1, 1);	//white background

	//Add the renderer to the VTK widget
	widget->GetRenderWindow()->AddRenderer(renderer);
	widget2->GetRenderWindow()->AddRenderer(renderer2);

	//Format everything nicely
	renderer->ResetCamera();
	renderer->GetActiveCamera()->Zoom(2.2); //zoom-in

	renderer2->ResetCamera();
	renderer2->GetActiveCamera()->Zoom(2.2); //zoom-in

	//Display the Qt window
        MainWindow.show(); 

        return app.exec(); 

} 
-------------End Widget2.cxx
-------------Start CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
 
if(POLICY CMP0020)
  cmake_policy(SET CMP0020 NEW)
endif()

PROJECT(widget2)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

if(${VTK_VERSION} VERSION_GREATER "6" AND VTK_QT_VERSION
VERSION_GREATER "4")
  # Instruct CMake to run moc automatically when needed.
  set(CMAKE_AUTOMOC ON)
  #find_package(Qt5Widgets REQUIRED QUIET)
  find_package(Qt5Widgets CONFIG REQUIRED COMPONENTS X11Extras)
else()
  find_package(Qt4 REQUIRED)
  include(${QT_USE_FILE})
endif()

include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})

file(GLOB UI_FILES *.ui)
file(GLOB QT_WRAP *.h)
file(GLOB CXX_FILES *.cxx)

if(${VTK_VERSION} VERSION_GREATER "6" AND VTK_QT_VERSION
VERSION_GREATER "4")
  qt5_wrap_ui(UISrcs ${UI_FILES} )
  # CMAKE_AUTOMOC in ON so the MocHdrs will be automatically wrapped.
  add_executable(widget2 MACOSX_BUNDLE
    ${CXX_FILES} ${UISrcs} ${QT_WRAP})
  qt5_use_modules(widget2 Core Gui)
  target_link_libraries(widget2 ${VTK_LIBRARIES})
else()
  QT4_WRAP_UI(UISrcs ${UI_FILES})
  QT4_WRAP_CPP(MOCSrcs ${QT_WRAP})
  add_executable(vtkdemo MACOSX_BUNDLE ${CXX_FILES} ${UISrcs}
${MOCSrcs})

  if(VTK_LIBRARIES)
    if(${VTK_VERSION} VERSION_LESS "6")
      target_link_libraries(widget2 ${VTK_LIBRARIES} QVTK)
    else()
      target_link_libraries(widget2 ${VTK_LIBRARIES})
    endif()
  else()
    target_link_libraries(widget2 vtkHybrid QVTK vtkViews
${QT_LIBRARIES})
  endif()
endif()

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11
support. Please use a different C++ compiler.")
endif()

----------------End CMakeLists.txt




More information about the vtkusers mailing list