Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VtkQtViewer.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25
26#include "G4VtkQtViewer.hh"
27
28#include "G4LogicalVolume.hh"
29#include "G4Qt.hh"
30#include "G4UIQt.hh"
31#include "G4UImanager.hh"
32#include "G4VSceneHandler.hh"
35#include "G4VtkUtility.hh"
36
37#include <qcoreapplication.h>
38#include <qlabel.h>
39#include <qlayout.h>
40#include <qlineedit.h>
41#include <qopenglcontext.h>
42#include <qpushbutton.h>
43#include <qthread.h>
44#include <qtreewidget.h>
45#include <vtkActor.h>
46#include <vtkCamera.h>
47#include <vtkCylinderSource.h>
48#include <vtkGenericOpenGLRenderWindow.h>
49#include <vtkNamedColors.h>
50#include <vtkNew.h>
51#include <vtkPolyDataMapper.h>
52#include <vtkProperty.h>
53#include <vtkRenderer.h>
54#include <vtkVersion.h>
55
56#include <array>
57
58namespace
59{
60G4Mutex mWaitForVisSubThreadQtOpenGLContextMoved = G4MUTEX_INITIALIZER;
61G4Mutex mWaitForVisSubThreadQtOpenGLContextInitialized = G4MUTEX_INITIALIZER;
62// avoid unused variable warning
63#ifdef G4MULTITHREADED
64G4Condition c1_VisSubThreadQtOpenGLContextInitialized = G4CONDITION_INITIALIZER;
65G4Condition c2_VisSubThreadQtOpenGLContextMoved = G4CONDITION_INITIALIZER;
66#endif
67} // namespace
68
70 : G4VtkViewer(sceneHandler, name)
71{
72 lWaitForVisSubThreadQtOpenGLContextInitialized =
73 new G4AutoLock(mWaitForVisSubThreadQtOpenGLContextInitialized, std::defer_lock);
74 lWaitForVisSubThreadQtOpenGLContextMoved =
75 new G4AutoLock(mWaitForVisSubThreadQtOpenGLContextMoved, std::defer_lock);
76
78 //this->setFormat(QVTKOpenGLNativeWidget::defaultFormat());
79}
80
82{
83 delete lWaitForVisSubThreadQtOpenGLContextInitialized;
84 delete lWaitForVisSubThreadQtOpenGLContextMoved;
85}
86
88{
89 CreateMainWindow(this, QString(GetName()));
90
91 // Specific GL render window and interactor for Qt
92 _renderWindow = vtkGenericOpenGLRenderWindow::New();
93
94 _renderWindow->AddRenderer(renderer);
95 this->setRenderWindow(_renderWindow);
96
97 // Set callback to match VTK parameters to Geant4
98 geant4Callback->SetGeant4ViewParameters(&fVP);
99 renderer->AddObserver(vtkCommand::EndEvent, geant4Callback);
100
101 // Hidden line removal
102 renderer->SetUseHiddenLineRemoval(0);
103
104 // Shadows
105 renderer->SetUseShadows(0);
106
109 this->interactor()->SetInteractorStyle(style);
110}
111
112void G4VtkQtViewer::CreateMainWindow(QVTKOpenGLNativeWidget* vtkWidget, const QString& name)
113{
115 fUiQt = static_cast<G4UIQt*>(UI->GetG4UIWindow());
116 fUiQt->AddTabWidget((QWidget*)vtkWidget, name);
117 vtkWidget->setAttribute(Qt::WA_AcceptTouchEvents, false);
118 fGLWidget = vtkWidget;
120}
121
122#ifdef G4MULTITHREADED
123
124void G4VtkQtViewer::DoneWithMasterThread()
125{
126 // Called by Main Thread !
127
128 // Useful to avoid two vis thread at the same time
129 // G4MUTEXLOCK(&mWaitForVisSubThreadQtOpenGLContextInitialized);
130 if (!lWaitForVisSubThreadQtOpenGLContextInitialized->owns_lock())
131 lWaitForVisSubThreadQtOpenGLContextInitialized->lock();
132}
133
134void G4VtkQtViewer::SwitchToVisSubThread()
135{
136 // Called by VisSub Thread !
137
138 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
139 if (qGLW == nullptr) {
140 return;
141 }
142
143 // Set the current QThread to its static variable
144 SetQGLContextVisSubThread(QThread::currentThread());
145
146 // - Wait for the vis thread to set its QThread
147 G4CONDITIONBROADCAST(&c1_VisSubThreadQtOpenGLContextInitialized);
148 // a condition without a locked mutex is an undefined behavior.
149 // we check if the mutex owns the lock, and if not, we lock it
150 if (!lWaitForVisSubThreadQtOpenGLContextMoved->owns_lock())
151 lWaitForVisSubThreadQtOpenGLContextMoved->lock();
152
153 // Unlock the vis thread if it is Qt Viewer
154 G4CONDITIONWAIT(&c2_VisSubThreadQtOpenGLContextMoved, lWaitForVisSubThreadQtOpenGLContextMoved);
155
156 // make context current
157 qGLW->makeCurrent();
158}
159
160void G4VtkQtViewer::DoneWithVisSubThread()
161{
162 // Called by vis sub thread
163 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
164 if (qGLW == nullptr) {
165 return;
166 }
167
168 // finish with this vis sub thread context
169 qGLW->doneCurrent();
170
171 // and move it back to the main thread
172 qGLW->context()->moveToThread(fQGLContextMainThread);
173}
174
175void G4VtkQtViewer::SwitchToMasterThread()
176{
177 // Called by VisSub Thread !
178
179 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
180 if (qGLW == nullptr) {
181 return;
182 }
183
184 // Useful to avoid two vis thread at the same time
185 // G4MUTEXUNLOCK(&mWaitForVisSubThreadQtOpenGLContextInitialized);
186 if (lWaitForVisSubThreadQtOpenGLContextInitialized->owns_lock())
187 lWaitForVisSubThreadQtOpenGLContextInitialized->unlock();
188
189 qGLW->makeCurrent();
190}
191
192void G4VtkQtViewer::MovingToVisSubThread()
193{
194 // Called by Main Thread !
195
196 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
197 if (qGLW == nullptr) {
198 return;
199 }
200
201 // a condition without a locked mutex is an undefined behavior.
202 // we check if the mutex owns the lock, and if not, we lock it
203 if (!lWaitForVisSubThreadQtOpenGLContextInitialized->owns_lock())
204 lWaitForVisSubThreadQtOpenGLContextInitialized->lock();
205
206 // - Wait for the vis sub thread to set its QThread
207 G4CONDITIONWAIT(&c1_VisSubThreadQtOpenGLContextInitialized,
208 lWaitForVisSubThreadQtOpenGLContextInitialized);
209
210 // Set current QThread for the way back
211 SetQGLContextMainThread(QThread::currentThread());
212
213 // finish with this main thread context
214 qGLW->doneCurrent();
215 qGLW->context()->moveToThread(fQGLContextVisSubThread);
216 G4CONDITIONBROADCAST(&c2_VisSubThreadQtOpenGLContextMoved);
217}
218#endif
219
221{
222 auto& fVtkSceneHandler = dynamic_cast<G4VtkSceneHandler&>(fSceneHandler);
223 fVtkSceneHandler.Modified();
224
225 _renderWindow->Render();
226
227 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
228 qGLW->interactor()->Initialize();
229 qGLW->interactor()->Start();
230}
231
233
235
236QTreeWidgetItem*
237G4VtkQtViewer::createTreeWidgetItem(const PVPath& /*fullPath*/, const QString& /*name*/,
238 int /*copyNb*/, int /*POIndex*/, const QString& /*logicalName*/,
239 Qt::CheckState /*state*/, QTreeWidgetItem* /*parentTreeNode*/,
240 const G4Colour& /*color*/)
241{
242 QTreeWidgetItem* newItem = nullptr;
243 return newItem;
244}
245
247 int /*currentPOIndex*/)
248{}
249
251 G4PhysicalVolumeModel* /*pPVModel*/,
252 int /*currentPOIndex*/)
253{}
254
256{
257 QString modelShortName;
258 return modelShortName;
259}
260
261bool G4VtkQtViewer::parseAndInsertInSceneTree(QTreeWidgetItem* /*parentItem*/,
262 G4PhysicalVolumeModel* /*pPVModel*/,
263 unsigned int /*fullPathIndex*/,
264 const QString& /*parentRoot*/,
265 unsigned int /*currentIndexInTreeSceneHandler*/,
266 int /*currentPVPOIndex*/)
267{
268 return false;
269}
270
272{
274 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
275 qGLW->interactor()->Initialize();
276}
277
278void G4VtkQtViewer::SetWidgetInteractor(vtkAbstractWidget* widget)
279{
280 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
281 widget->SetInteractor(qGLW->interactor());
282}
G4TemplateAutoLock< G4Mutex > G4AutoLock
#define G4CONDITION_INITIALIZER
#define G4MUTEX_INITIALIZER
#define G4CONDITIONWAIT(cond, mutex)
G4int G4Condition
#define G4CONDITIONBROADCAST(cond)
std::mutex G4Mutex
static G4Qt * getInstance()
Definition G4Qt.cc:51
bool owns_lock() const noexcept
G4bool AddTabWidget(QWidget *, QString)
Definition G4UIQt.cc:2283
G4UIsession * GetG4UIWindow() const
static G4UImanager * GetUIpointer()
const G4String & GetName() const
G4VSceneHandler & fSceneHandler
Definition G4VViewer.hh:253
G4ViewParameters fVP
Definition G4VViewer.hh:257
void addNonPVSceneTreeElement(const G4String &model, G4Visible &visible, int currentPOIndex)
void createSceneTreeWidget()
~G4VtkQtViewer() override
virtual void CreateMainWindow(QVTKOpenGLNativeWidget *, const QString &)
bool parseAndInsertInSceneTree(QTreeWidgetItem *parentItem, G4PhysicalVolumeModel *pPVModel, unsigned int fullPathIndex, const QString &parentRoot, unsigned int currentIndexInTreeSceneHandler, int currentPVPOIndex)
QString getModelShortName(const G4String &model)
void Initialise() override
G4VtkQtViewer(G4VSceneHandler &, const G4String &name)
std::vector< PVNodeID > PVPath
void SetWidgetInteractor(vtkAbstractWidget *widget) override
void EnableClipperWidget() override
void createSceneTreeComponent()
void addPVSceneTreeElement(const G4String &model, G4PhysicalVolumeModel *pPVModel, int currentPOIndex)
void FinishView() override
QTreeWidgetItem * createTreeWidgetItem(const PVPath &fullPath, const QString &name, int copyNb, int POIndex, const QString &logicalName, Qt::CheckState state, QTreeWidgetItem *parentTreeNode, const G4Colour &color)
vtkNew< vtkGeant4Callback > geant4Callback
virtual void EnableClipperWidget()
vtkNew< vtkRenderer > renderer
vtkRenderWindow * _renderWindow