add Qt viewport
This commit is contained in:
@@ -9,6 +9,8 @@ endif()
|
||||
|
||||
cmake_minimum_required (VERSION 3.26)
|
||||
|
||||
set(QT_NO_VERSION_CHECK TRUE)
|
||||
|
||||
if(POLICY CMP0167)
|
||||
cmake_policy(SET CMP0167 NEW)
|
||||
endif()
|
||||
@@ -125,18 +127,12 @@ find_package(ROOT CONFIG REQUIRED)
|
||||
include(${ROOT_USE_FILE})
|
||||
|
||||
find_package(VTK REQUIRED)
|
||||
# include(${VTK_USE_FILE})
|
||||
|
||||
set(GEANT4_USE_HDF5 OFF CACHE BOOL "Use HDF5" FORCE)
|
||||
find_package(Geant4 REQUIRED)
|
||||
|
||||
find_package(pybind11 REQUIRED)
|
||||
|
||||
|
||||
option(CENTOS_SUPPORT "VTK definitions for CentOS" OFF)
|
||||
if(CENTOS_SUPPORT)
|
||||
find_package(VTK CONFIG REQUIRED)
|
||||
include(${VTK_USE_FILE})
|
||||
# include(${VTK_USE_FILE})
|
||||
else()
|
||||
find_package(VTK REQUIRED
|
||||
COMPONENTS CommonColor
|
||||
@@ -157,7 +153,25 @@ else()
|
||||
RenderingGL2PSOpenGL2
|
||||
RenderingOpenGL2
|
||||
RenderingVolumeOpenGL2
|
||||
IOGeometry)
|
||||
IOGeometry
|
||||
GUISupportQt)
|
||||
endif()
|
||||
|
||||
find_package(Qt6 COMPONENTS Widgets REQUIRED)
|
||||
|
||||
find_package(Geant4 REQUIRED)
|
||||
message(STATUS "Geant4 libs: ${Geant4_LIBRARIES}")
|
||||
|
||||
# Sanitize Geant4 targets to remove Qt5 dependencies that conflict with VTK/Qt6
|
||||
if(TARGET Geant4::G4interfaces)
|
||||
set_target_properties(Geant4::G4interfaces PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "Geant4::G4global;Geant4::G4graphics_reps;Geant4::G4intercoms"
|
||||
)
|
||||
endif()
|
||||
if(TARGET Geant4::G4OpenGL)
|
||||
set_target_properties(Geant4::G4OpenGL PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "Geant4::G4vis_management;Geant4::G4graphics_reps;Geant4::G4geometry;Geant4::G4materials;Geant4::G4intercoms;Geant4::G4global;OpenGL::GL;OpenGL::GLU"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES CMAKE_REQUIRED_INCLUDES math.h)
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
|
||||
add_executable(gcompose src/main.cpp)
|
||||
add_executable(gcompose
|
||||
src/main.cpp
|
||||
src/MainWindow.h
|
||||
src/MainWindow.cpp
|
||||
)
|
||||
|
||||
set_target_properties(gcompose PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTOUIC ON
|
||||
AUTORCC ON
|
||||
)
|
||||
|
||||
target_include_directories(gcompose PRIVATE
|
||||
${SRC_DIR}
|
||||
@@ -8,13 +18,21 @@ target_include_directories(gcompose PRIVATE
|
||||
${VTK_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Filter Geant4 libraries to remove Qt-dependent ones
|
||||
set(Geant4_LIBS_FILTERED ${Geant4_LIBRARIES})
|
||||
if(Geant4_LIBS_FILTERED)
|
||||
list(REMOVE_ITEM Geant4_LIBS_FILTERED Geant4::G4interfaces Geant4::G4OpenGL Geant4::G4visQt3D)
|
||||
endif()
|
||||
|
||||
target_link_libraries(gcompose
|
||||
mutomCore
|
||||
mutomMath
|
||||
mutomGeant
|
||||
mutomVtk
|
||||
${Geant4_LIBRARIES}
|
||||
${Geant4_LIBS_FILTERED}
|
||||
${VTK_LIBRARIES}
|
||||
Qt6::Widgets
|
||||
VTK::GUISupportQt
|
||||
)
|
||||
|
||||
install(TARGETS gcompose RUNTIME DESTINATION bin)
|
||||
|
||||
15
app/gcompose/src/MainWindow.cpp
Normal file
15
app/gcompose/src/MainWindow.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "MainWindow.h"
|
||||
#include <Vtk/vtkQViewport.h>
|
||||
|
||||
using namespace uLib;
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
|
||||
m_viewport = new Vtk::QViewport(this);
|
||||
setCentralWidget(m_viewport);
|
||||
|
||||
setWindowTitle("gcompose - Qt VTK Interface");
|
||||
resize(1200, 800);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
}
|
||||
25
app/gcompose/src/MainWindow.h
Normal file
25
app/gcompose/src/MainWindow.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QVTKOpenGLNativeWidget.h>
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
class QViewport;
|
||||
}
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow(QWidget* parent = nullptr);
|
||||
virtual ~MainWindow();
|
||||
|
||||
uLib::Vtk::QViewport* getViewport() { return m_viewport; }
|
||||
|
||||
private:
|
||||
uLib::Vtk::QViewport* m_viewport;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,13 @@
|
||||
#include <QApplication>
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include "Math/ContainerBox.h"
|
||||
#include <HEP/Geant/Scene.h>
|
||||
#include "HEP/Detectors/DetectorChamber.h"
|
||||
#include "Vtk/HEP/Detectors/vtkDetectorChamber.h"
|
||||
|
||||
#include <Vtk/uLibVtkViewer.h>
|
||||
#include <Vtk/vtkContainerBox.h>
|
||||
#include <Vtk/vtkQViewport.h>
|
||||
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkCubeSource.h>
|
||||
@@ -14,12 +16,15 @@
|
||||
#include <vtkRenderer.h>
|
||||
|
||||
|
||||
#include "Math/Units.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace uLib;
|
||||
using namespace uLib::literals;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::cout << "Starting gcompose application..." << std::endl;
|
||||
QApplication app(argc, argv);
|
||||
std::cout << "Starting gcompose Qt application..." << std::endl;
|
||||
|
||||
ContainerBox world_box(Vector3f(1, 1, 1));
|
||||
world_box.Scale(Vector3f(20_mm, 20_mm, 20_mm));
|
||||
@@ -40,29 +45,23 @@ int main(int argc, char** argv) {
|
||||
scene.ConstructWorldBox(&world_box, "G4_AIR");
|
||||
scene.Initialize();
|
||||
|
||||
// 2. Initialize VTK Viewer
|
||||
Vtk::Viewer viewer;
|
||||
// 2. Initialize MainWindow (contains embedded VTK QViewport)
|
||||
MainWindow window;
|
||||
Vtk::QViewport* viewport = window.getViewport();
|
||||
|
||||
|
||||
Vtk::vtkDetectorChamber vtk_d1(&d1);
|
||||
viewer.AddPuppet(vtk_d1);
|
||||
|
||||
Vtk::vtkDetectorChamber vtk_d2(&d2);
|
||||
viewer.AddPuppet(vtk_d2);
|
||||
|
||||
Vtk::vtkContainerBox vtk_box(&world_box);
|
||||
viewer.AddPuppet(vtk_box);
|
||||
viewport->AddPuppet(vtk_d1);
|
||||
|
||||
viewer.GetRenderer()->Render();
|
||||
Vtk::vtkDetectorChamber vtk_d2(&d2);
|
||||
viewport->AddPuppet(vtk_d2);
|
||||
|
||||
Vtk::vtkContainerBox vtk_box(&world_box);
|
||||
viewport->AddPuppet(vtk_box);
|
||||
|
||||
viewport->ZoomAuto();
|
||||
|
||||
std::cout << "Geant4 and VTK scenes are ready." << std::endl;
|
||||
std::cout << "Starting VTK Interactor..." << std::endl;
|
||||
|
||||
// 3. Start VTK interactor (blocks until window is closed)
|
||||
viewer.Start();
|
||||
|
||||
// 4. Clean up
|
||||
std::cout << "Shutting down..." << std::endl;
|
||||
|
||||
return 0;
|
||||
|
||||
window.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -119,8 +119,8 @@ public:
|
||||
void AddAdapter(AdapterInterface &ad) { m_a.push_back(Adapter(ad)); }
|
||||
|
||||
void Update() {
|
||||
foreach(Adapter &ad, m_a) {
|
||||
foreach(DItem &item, m_v) {
|
||||
for(Adapter &ad : m_a) {
|
||||
for(DItem &item : m_v) {
|
||||
item.m_adapter->operator()(ad, item.m_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,16 @@ target_link_libraries(${libname}
|
||||
${PACKAGE_LIBPREFIX}Core
|
||||
${PACKAGE_LIBPREFIX}Math
|
||||
${PACKAGE_LIBPREFIX}Detectors
|
||||
${Geant4_LIBRARIES}
|
||||
)
|
||||
|
||||
# Filter Geant4 libraries to remove Qt-dependent ones
|
||||
set(Geant4_LIBS_FILTERED ${Geant4_LIBRARIES})
|
||||
if(Geant4_LIBS_FILTERED)
|
||||
list(REMOVE_ITEM Geant4_LIBS_FILTERED Geant4::G4interfaces Geant4::G4OpenGL Geant4::G4visQt3D)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${libname}
|
||||
${Geant4_LIBS_FILTERED}
|
||||
)
|
||||
|
||||
install(TARGETS ${libname}
|
||||
|
||||
@@ -2,12 +2,14 @@ set(HEADERS uLibVtkInterface.h
|
||||
uLibVtkViewer.h
|
||||
vtkContainerBox.h
|
||||
vtkHandlerWidget.h
|
||||
vtkQViewport.h
|
||||
)
|
||||
|
||||
set(SOURCES uLibVtkInterface.cxx
|
||||
uLibVtkViewer.cpp
|
||||
vtkContainerBox.cpp
|
||||
vtkHandlerWidget.cpp
|
||||
vtkQViewport.cpp
|
||||
)
|
||||
|
||||
## Pull in Math VTK wrappers (sets MATH_SOURCES / MATH_HEADERS)
|
||||
@@ -42,9 +44,11 @@ set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} Vtk PARENT_SCOPE)
|
||||
|
||||
add_library(${libname} SHARED ${SOURCES})
|
||||
set_target_properties(${libname} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_SOVERSION})
|
||||
target_link_libraries(${libname} ${LIBRARIES})
|
||||
SOVERSION ${PROJECT_SOVERSION}
|
||||
AUTOMOC ON
|
||||
AUTOUIC ON
|
||||
AUTORCC ON)
|
||||
target_link_libraries(${libname} ${LIBRARIES} Qt6::Widgets)
|
||||
|
||||
install(TARGETS ${libname}
|
||||
EXPORT "uLibTargets"
|
||||
|
||||
@@ -166,6 +166,8 @@ vtkCornerAnnotation *Viewer::GetAnnotation() { return m_Annotation; }
|
||||
|
||||
vtkRenderer *Viewer::GetRenderer() { return m_Renderer; }
|
||||
|
||||
vtkRenderWindow *Viewer::GetRenderWindow() { return m_RenderWindow; }
|
||||
|
||||
vtkRenderWindowInteractor *Viewer::GetInteractor() {
|
||||
return m_RenderWindow->GetInteractor();
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
vtkCornerAnnotation *GetAnnotation();
|
||||
|
||||
vtkRenderer *GetRenderer();
|
||||
|
||||
vtkRenderWindow *GetRenderWindow();
|
||||
vtkRenderWindowInteractor *GetInteractor();
|
||||
|
||||
vtkCameraOrientationWidget *GetCameraWidget();
|
||||
|
||||
150
src/Vtk/vtkQViewport.cpp
Normal file
150
src/Vtk/vtkQViewport.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "vtkQViewport.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <vtkAxesActor.h>
|
||||
#include <vtkCamera.h>
|
||||
#include <vtkCameraOrientationWidget.h>
|
||||
#include <vtkInteractorStyleTrackballCamera.h>
|
||||
#include <vtkObjectFactory.h>
|
||||
#include <vtkRenderWindowInteractor.h>
|
||||
#include <vtkTextProperty.h>
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
QViewport::QViewport(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_VtkWidget(nullptr)
|
||||
, m_Renderer(vtkRenderer::New())
|
||||
, m_Annotation(vtkCornerAnnotation::New())
|
||||
, m_Marker(vtkOrientationMarkerWidget::New())
|
||||
, m_CameraWidget(nullptr)
|
||||
{
|
||||
// Build the layout – zero margins so VTK fills the entire widget
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
m_VtkWidget = new QVTKOpenGLNativeWidget(this);
|
||||
layout->addWidget(m_VtkWidget);
|
||||
|
||||
// After the Qt widget exists but before the first paint,
|
||||
// attach the renderer and configure the pipeline.
|
||||
SetupPipeline();
|
||||
}
|
||||
|
||||
QViewport::~QViewport()
|
||||
{
|
||||
m_Renderer->RemoveAllViewProps();
|
||||
m_Renderer->Clear();
|
||||
|
||||
m_Annotation->Delete();
|
||||
m_Marker->Delete();
|
||||
if (m_CameraWidget)
|
||||
m_CameraWidget->Delete();
|
||||
m_Renderer->Delete();
|
||||
}
|
||||
|
||||
void QViewport::SetupPipeline()
|
||||
{
|
||||
// Add our renderer to the QVTKOpenGLNativeWidget's render window
|
||||
vtkRenderWindow* rw = m_VtkWidget->renderWindow();
|
||||
rw->AddRenderer(m_Renderer);
|
||||
|
||||
// Qt will supply its own interactor – grab it
|
||||
vtkRenderWindowInteractor* iren = rw->GetInteractor();
|
||||
|
||||
// Trackball-camera interaction style
|
||||
vtkNew<vtkInteractorStyleTrackballCamera> style;
|
||||
iren->SetInteractorStyle(style);
|
||||
|
||||
// Corner annotation
|
||||
m_Annotation->GetTextProperty()->SetColor(1, 1, 1);
|
||||
m_Annotation->GetTextProperty()->SetFontFamilyToArial();
|
||||
m_Annotation->GetTextProperty()->SetOpacity(0.5);
|
||||
m_Annotation->SetMaximumFontSize(10);
|
||||
m_Annotation->SetText(0, "uLib VTK Viewer - OpenCMT all right reserved.");
|
||||
m_Renderer->AddViewProp(m_Annotation);
|
||||
|
||||
// Orientation axes marker (bottom-left corner)
|
||||
vtkNew<vtkAxesActor> axes;
|
||||
m_Marker->SetInteractor(iren);
|
||||
m_Marker->SetOrientationMarker(axes);
|
||||
m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
|
||||
m_Marker->SetEnabled(true);
|
||||
m_Marker->InteractiveOff();
|
||||
|
||||
// Camera-orientation widget (VTK ≥ 9)
|
||||
#if VTK_MAJOR_VERSION >= 9
|
||||
m_CameraWidget = vtkCameraOrientationWidget::New();
|
||||
m_CameraWidget->SetParentRenderer(m_Renderer);
|
||||
m_CameraWidget->SetInteractor(iren);
|
||||
m_CameraWidget->On();
|
||||
#endif
|
||||
|
||||
m_Renderer->SetBackground(0.15, 0.15, 0.15);
|
||||
m_Renderer->ResetCamera();
|
||||
}
|
||||
|
||||
// ── Public API ────────────────────────────────────────────────────────────────
|
||||
|
||||
void QViewport::Render()
|
||||
{
|
||||
m_VtkWidget->renderWindow()->Render();
|
||||
}
|
||||
|
||||
void QViewport::Reset()
|
||||
{
|
||||
ZoomAuto();
|
||||
Render();
|
||||
}
|
||||
|
||||
void QViewport::ZoomAuto()
|
||||
{
|
||||
m_Renderer->ResetCameraClippingRange();
|
||||
m_Renderer->ResetCamera();
|
||||
}
|
||||
|
||||
void QViewport::AddPuppet(Puppet& prop)
|
||||
{
|
||||
prop.ConnectRenderer(m_Renderer);
|
||||
prop.ConnectInteractor(GetInteractor());
|
||||
Render();
|
||||
}
|
||||
|
||||
void QViewport::RemovePuppet(Puppet& prop)
|
||||
{
|
||||
prop.DisconnectRenderer(m_Renderer);
|
||||
Render();
|
||||
}
|
||||
|
||||
void QViewport::addProp(vtkProp* prop)
|
||||
{
|
||||
m_Renderer->AddActor(prop);
|
||||
Render();
|
||||
}
|
||||
|
||||
void QViewport::RemoveProp(vtkProp* prop)
|
||||
{
|
||||
m_Renderer->RemoveViewProp(prop);
|
||||
Render();
|
||||
}
|
||||
|
||||
void QViewport::AddWidget(vtk3DWidget* /*widget*/)
|
||||
{
|
||||
// vtk3DWidget integration can be added here if needed
|
||||
}
|
||||
|
||||
vtkRenderWindow* QViewport::GetRenderWindow()
|
||||
{
|
||||
return m_VtkWidget->renderWindow();
|
||||
}
|
||||
|
||||
vtkRenderWindowInteractor* QViewport::GetInteractor()
|
||||
{
|
||||
return m_VtkWidget->renderWindow()->GetInteractor();
|
||||
}
|
||||
|
||||
} // namespace Vtk
|
||||
} // namespace uLib
|
||||
69
src/Vtk/vtkQViewport.h
Normal file
69
src/Vtk/vtkQViewport.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef ULIB_VTK_QVIEWPORT_H
|
||||
#define ULIB_VTK_QVIEWPORT_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVTKOpenGLNativeWidget.h>
|
||||
|
||||
#include <vtkCornerAnnotation.h>
|
||||
#include <vtkOrientationMarkerWidget.h>
|
||||
#include <vtkRenderer.h>
|
||||
#include <vtkRenderWindow.h>
|
||||
#include <vtkSmartPointer.h>
|
||||
|
||||
#include "uLibVtkInterface.h"
|
||||
|
||||
class vtkProp;
|
||||
class vtk3DWidget;
|
||||
class vtkRenderWindowInteractor;
|
||||
class vtkCameraOrientationWidget;
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
/**
|
||||
* QViewport is a self-contained Qt widget that embeds a VTK renderer
|
||||
* directly into the Qt application (no separate VTK window).
|
||||
* Puppets and actors are added to the embedded renderer.
|
||||
*/
|
||||
class QViewport : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QViewport(QWidget* parent = nullptr);
|
||||
virtual ~QViewport();
|
||||
|
||||
// Render scene
|
||||
void Render();
|
||||
void Reset();
|
||||
void ZoomAuto();
|
||||
|
||||
// Puppet / prop management
|
||||
void AddPuppet(Puppet &prop);
|
||||
void RemovePuppet(Puppet &prop);
|
||||
void addProp(vtkProp *prop);
|
||||
void RemoveProp(vtkProp *prop);
|
||||
|
||||
// Widget integration
|
||||
void AddWidget(vtk3DWidget *widget);
|
||||
|
||||
// Direct access to VTK internals
|
||||
vtkRenderer* GetRenderer() { return m_Renderer; }
|
||||
vtkRenderWindow* GetRenderWindow();
|
||||
vtkRenderWindowInteractor* GetInteractor();
|
||||
vtkCornerAnnotation* GetAnnotation() { return m_Annotation; }
|
||||
vtkCameraOrientationWidget* GetCameraWidget(){ return m_CameraWidget; }
|
||||
QVTKOpenGLNativeWidget* GetWidget() { return m_VtkWidget; }
|
||||
|
||||
private:
|
||||
void SetupPipeline();
|
||||
|
||||
QVTKOpenGLNativeWidget* m_VtkWidget;
|
||||
vtkRenderer* m_Renderer;
|
||||
vtkCornerAnnotation* m_Annotation;
|
||||
vtkOrientationMarkerWidget* m_Marker;
|
||||
vtkCameraOrientationWidget* m_CameraWidget;
|
||||
};
|
||||
|
||||
} // namespace Vtk
|
||||
} // namespace uLib
|
||||
|
||||
#endif // ULIB_VTK_QVIEWPORT_H
|
||||
Reference in New Issue
Block a user