I am presently porting my application from qt5 to qt 6 which uses vtk 9.3.1.
Facing issue during loading of dicom images into qt window. White screen appears with blank display of image but having no issues in vs 2019.
I have 4 points to discuss:
During investigation found out that vtk have GUISupport module which internally have qt module (that have qt6/qt5 support )but does not get configured by default even though cmakelist.txt in vtk include GUISupport folder.
While adding GUISupport/Qt folder explicitly through top level cmakelist.txt getting error while cmake configure step - “vtk_module_find_package”- tag not recognized. Why this tags are present if not supported in cmake?
After few round of research found that VTK_MODULE_ENABLE_VTK_GUISupportQt and VTK_MODULE_ENABLE_VTK_RenderingQt variables needs to be set in cmake configure. But just setting these variables would be enough to instruct vtk build that application needs qt6 support?
What is the right way to add qt6 paths during vtk configure and later on in vtk compilation?
After few round of research found that VTK_MODULE_ENABLE_VTK_GUISupportQt and VTK_MODULE_ENABLE_VTK_RenderingQt variables needs to be set in cmake configure. But just setting these variables would be enough to instruct vtk build that application needs qt6 support?
Yes
What is the right way to add qt6 paths during vtk configure and later on in vtk compilation?
Thanks for the reply.
I can include Qt::GUISupportQt module in vtk build . but still unable to render images which uses vtk libraries.
I am using QGraphicsWidget as container widget of the image which uses QVTKOpenGLNativeWidget iternally and vtkGenericOpenGLRenderWindow as the render window which uses QVTKRenderWindowAdapter which render the image from the image data.
Any changes needs to be done for qt 6 ? The same apis were being used in qt5 .
Also why do we need guisupportQT module for qt 6? any special api from that we need to use?
Also when trying with vtk 9.3.1 / examples folder , getting below errors.
vtkAlgorithm.cxx:940 ERR| vtkDataReader (000001DC7667C730): FillOutputPortInformation is not implemented.
vtkDemandDrivenPipeline:642 ERR| vtkCompositeDataPipeline (000001DC7661DE60): Algorithm vtkDataReader (000001DC7667C730) did not create output for port 0 when asked by REQUEST_DATA_OBJECT and does not specify any DATA_TYPE_NAME.
This makes look like something needs to be modified during the implementation.
@ataban I just tested it and the examples seem to work fine irrespective of the Qt version (5 or 6).
Could you please share code samples that reproduce the error you’re seeing?
It loads the image mentioned in below example but in this case it is loading blank.
source
// Create the renderer, the render window, and the interactor. The renderer
// draws into the render window, the interactor enables mouse- and
// keyboard-based interaction with the data within the render window.
//
vtkSmartPointer aRenderer = vtkSmartPointer::New();
vtkSmartPointer renWin = vtkSmartPointer::New();
renWin->AddRenderer(aRenderer);
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
// The following reader is used to read a series of 2D slices (images)
// that compose the volume. The slice dimensions are set, and the
// pixel spacing. The data Endianness must also be specified. The reader
// uses the FilePrefix in combination with the slice number to construct
// filenames using the format FilePrefix.%d. (In this case the FilePrefix
// is the root name of the file: quarter.)
vtkSmartPointer<vtkVolume16Reader> v16 = vtkSmartPointer<vtkVolume16Reader>::New();
v16->SetDataDimensions(64, 64);
v16->SetImageRange(1, 93);
v16->SetDataByteOrderToLittleEndian();
std::string dir = "C:/ci/projects/mediseen-data/osirix/brebix/Uncompressed/1.2.840.113704.1.111.2864.1161868417.2891.dcm";
v16->SetFilePrefix(dir.c_str());
v16->SetDataSpacing(3.2, 3.2, 1.5);
// An isosurface, or contour value of 500 is known to correspond to the
// skin of the patient. Once generated, a vtkPolyDataNormals filter is
// is used to create normals for smooth surface shading during rendering.
vtkSmartPointer<vtkContourFilter> skinExtractor = vtkSmartPointer<vtkContourFilter>::New();
skinExtractor->SetInputConnection(v16->GetOutputPort());
skinExtractor->SetValue(0, 500);
vtkSmartPointer<vtkPolyDataNormals> skinNormals = vtkSmartPointer<vtkPolyDataNormals>::New();
skinNormals->SetInputConnection(skinExtractor->GetOutputPort());
skinNormals->SetFeatureAngle(60.0);
vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
skinMapper->SetInputConnection(skinNormals->GetOutputPort());
skinMapper->ScalarVisibilityOff();
vtkSmartPointer<vtkActor> skin = vtkSmartPointer<vtkActor>::New();
skin->SetMapper(skinMapper);
// An outline provides context around the data.
//
vtkSmartPointer<vtkOutlineFilter> outlineData = vtkSmartPointer<vtkOutlineFilter>::New();
outlineData->SetInputConnection(v16->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> mapOutline = vtkSmartPointer<vtkPolyDataMapper>::New();
mapOutline->SetInputConnection(outlineData->GetOutputPort());
vtkSmartPointer<vtkActor> outline = vtkSmartPointer<vtkActor>::New();
outline->SetMapper(mapOutline);
outline->GetProperty()->SetColor(0, 0, 0);
// It is convenient to create an initial view of the data. The FocalPoint
// and Position form a vector direction. Later on (ResetCamera() method)
// this vector is used to position the camera to look at the data in
// this direction.
vtkSmartPointer<vtkCamera> aCamera = vtkSmartPointer<vtkCamera>::New();
aCamera->SetViewUp(0, 0, -1);
aCamera->SetPosition(0, 1, 0);
aCamera->SetFocalPoint(0, 0, 0);
aCamera->ComputeViewPlaneNormal();
aCamera->Azimuth(30.0);
aCamera->Elevation(30.0);
// Actors are added to the renderer. An initial camera view is created.
// The Dolly() method moves the camera towards the FocalPoint,
// thereby enlarging the image.
aRenderer->AddActor(outline);
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera();
aCamera->Dolly(1.5);
// Set a background color for the renderer and set the size of the
// render window (expressed in pixels).
aRenderer->SetBackground(.2, .3, .4);
renWin->SetSize(640, 480);
// Note that when camera movement occurs (as it does in the Dolly()
// method), the clipping planes often need adjusting. Clipping planes
// consist of two planes: near and far along the view direction. The
// near plane clips out objects in front of the plane; the far plane
// clips out objects behind the plane. This way only what is drawn
// between the planes is actually rendered.
aRenderer->ResetCameraClippingRange();
// For testing, check if "-V" is used to provide a regression test image
/*if (argc >= 4 && strcmp(argv[2], "-V") == 0)
{
renWin->Render();
int retVal = vtkRegressionTestImage(renWin);
if (retVal == vtkTesting::FAILED)
{
return EXIT_FAILURE;
}
else if (retVal != vtkTesting::DO_INTERACTOR)
{
return EXIT_SUCCESS;
}
}*/
// Initialize the event loop and then start it.
iren->Initialize();
iren->Start();
QVTKInteractor.cxx:131 ERR| QVTKInteractor (0000023E6C587790): QVTKInteractor cannot control the event loop.
This is appearing when i am trying to load dicom image in qt6/qt5 without using any qtWidget . Using VTKIMAGEVIEWER, QVTKNativeOpenGLWidget, QVTKOpenGLRenderer, and interactor.
@ataban For loading DICOM data, please use the vtkDICOMImageReader. See the ReadDICOM example for reference.
Those classes need a Qt application as they’re written with Qt widgets. Without a Qt application running, the interaction associated with those classes fails to create an event loop and hence the error.