Geant4 Cross Reference |
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" 33 #include "G4VtkInteractorStyle.hh" 34 #include "G4VtkQtSceneHandler.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 58 G4VtkQtViewer::G4VtkQtViewer(G4VSceneHandler& sceneHandler, const G4String& name) 59 : G4VtkViewer(sceneHandler, name) 60 { 61 G4Qt::getInstance(); 62 //this->setFormat(QVTKOpenGLNativeWidget::defaultFormat()); 63 } 64 65 G4VtkQtViewer::~G4VtkQtViewer() 66 { 67 } 68 69 void G4VtkQtViewer::Initialise() 70 { 71 CreateMainWindow(this, QString(GetName())); 72 73 // Specific GL render window and interactor for Qt 74 _renderWindow = vtkGenericOpenGLRenderWindow::New(); 75 76 _renderWindow->AddRenderer(renderer); 77 this->setRenderWindow(_renderWindow); 78 79 // Set callback to match VTK parameters to Geant4 80 geant4Callback->SetGeant4ViewParameters(&fVP); 81 renderer->AddObserver(vtkCommand::EndEvent, geant4Callback); 82 83 // Hidden line removal 84 renderer->SetUseHiddenLineRemoval(0); 85 86 // Shadows 87 renderer->SetUseShadows(0); 88 89 vtkSmartPointer<G4VtkInteractorStyle> style = 90 vtkSmartPointer<G4VtkInteractorStyle>::New(); 91 this->interactor()->SetInteractorStyle(style); 92 } 93 94 void G4VtkQtViewer::CreateMainWindow(QVTKOpenGLNativeWidget* vtkWidget, const QString& name) 95 { 96 G4UImanager* UI = G4UImanager::GetUIpointer(); 97 fUiQt = static_cast<G4UIQt*>(UI->GetG4UIWindow()); 98 fUiQt->AddTabWidget((QWidget*)vtkWidget, name); 99 vtkWidget->setAttribute(Qt::WA_AcceptTouchEvents, false); 100 fGLWidget = vtkWidget; 101 createSceneTreeWidget(); 102 } 103 104 #ifdef G4MULTITHREADED 105 106 namespace { 107 G4Mutex visSubThreadMutex = G4MUTEX_INITIALIZER; 108 G4Condition waitForVisSubThreadInitialized = G4CONDITION_INITIALIZER; 109 G4bool visSubThreadEstablished = false; 110 G4bool qObjectsSwitched = false; 111 QVTKOpenGLNativeWidget* qVtkW = nullptr; 112 } 113 114 void G4VtkQtViewer::DoneWithMasterThread() 115 { 116 // Called by Main Thread ! 117 118 // Initialise and check qVtkW - no need to check in subsequent functions 119 qVtkW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget); 120 if (qVtkW == nullptr) return; 121 122 // Done with master thread 123 qVtkW->doneCurrent(); 124 125 // Set current QThread for the way back 126 fQVtkContextMainThread = QThread::currentThread(); 127 } 128 129 void G4VtkQtViewer::MovingToVisSubThread() 130 { 131 // Still on master thread but vis thread has been launched 132 133 if (qVtkW == nullptr) return; 134 135 // Wait until SwitchToVisSubThread has found vis sub-thread QThread 136 { 137 G4AutoLock lock(&visSubThreadMutex); 138 G4CONDITIONWAITLAMBDA(&waitForVisSubThreadInitialized, &lock, []{return visSubThreadEstablished;}) 139 } 140 141 // Move stuff to sub-thread 142 if(qVtkW->context()) qVtkW->context()->moveToThread(fQVtkContextVisSubThread); 143 144 // Inform sub-thread 145 G4AutoLock lock(&visSubThreadMutex); 146 qObjectsSwitched = true; 147 lock.unlock(); 148 G4CONDITIONBROADCAST(&waitForVisSubThreadInitialized); 149 } 150 151 void G4VtkQtViewer::SwitchToVisSubThread() 152 { 153 // Called by VisSub Thread ! 154 155 if (qVtkW == nullptr) return; 156 157 fQVtkContextVisSubThread = QThread::currentThread(); 158 159 // Let MovingToVisSubThread know we have the QThread 160 { 161 G4AutoLock lock(&visSubThreadMutex); 162 visSubThreadEstablished = true; 163 G4CONDITIONBROADCAST(&waitForVisSubThreadInitialized); 164 } 165 166 // Wait until MovingToVisSubThread has moved stuff 167 { 168 G4AutoLock lock(&visSubThreadMutex); 169 G4CONDITIONWAITLAMBDA(&waitForVisSubThreadInitialized, &lock, []{return qObjectsSwitched;}) 170 } 171 172 // make context current 173 qVtkW->makeCurrent(); 174 } 175 176 void G4VtkQtViewer::DoneWithVisSubThread() 177 { 178 // Called by vis sub thread 179 180 if (qVtkW == nullptr) return; 181 182 // finish with this vis sub thread context 183 qVtkW->doneCurrent(); 184 185 // and move it back to the main thread 186 if(qVtkW->context()) qVtkW->context()->moveToThread(fQVtkContextMainThread); 187 } 188 189 void G4VtkQtViewer::SwitchToMasterThread() 190 { 191 // Called by VisSub Thread ! 192 193 if (qVtkW == nullptr) return; 194 195 qVtkW->makeCurrent(); 196 197 visSubThreadEstablished = false; 198 qObjectsSwitched = false; 199 } 200 201 #endif 202 203 void G4VtkQtViewer::FinishView() 204 { 205 auto& fVtkSceneHandler = dynamic_cast<G4VtkSceneHandler&>(fSceneHandler); 206 fVtkSceneHandler.Modified(); 207 208 _renderWindow->Render(); 209 210 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget); 211 qGLW->interactor()->Initialize(); 212 qGLW->interactor()->Start(); 213 } 214 215 void G4VtkQtViewer::createSceneTreeWidget() {} 216 217 void G4VtkQtViewer::createSceneTreeComponent() {} 218 219 QTreeWidgetItem* 220 G4VtkQtViewer::createTreeWidgetItem(const PVPath& /*fullPath*/, const QString& /*name*/, 221 int /*copyNb*/, int /*POIndex*/, const QString& /*logicalName*/, 222 Qt::CheckState /*state*/, QTreeWidgetItem* /*parentTreeNode*/, 223 const G4Colour& /*color*/) 224 { 225 QTreeWidgetItem* newItem = nullptr; 226 return newItem; 227 } 228 229 void G4VtkQtViewer::addNonPVSceneTreeElement(const G4String& /*model*/, G4Visible& /*visible*/, 230 int /*currentPOIndex*/) 231 {} 232 233 void G4VtkQtViewer::addPVSceneTreeElement(const G4String& /*model*/, 234 G4PhysicalVolumeModel* /*pPVModel*/, 235 int /*currentPOIndex*/) 236 {} 237 238 QString G4VtkQtViewer::getModelShortName(const G4String& /*model*/) 239 { 240 QString modelShortName; 241 return modelShortName; 242 } 243 244 bool G4VtkQtViewer::parseAndInsertInSceneTree(QTreeWidgetItem* /*parentItem*/, 245 G4PhysicalVolumeModel* /*pPVModel*/, 246 unsigned int /*fullPathIndex*/, 247 const QString& /*parentRoot*/, 248 unsigned int /*currentIndexInTreeSceneHandler*/, 249 int /*currentPVPOIndex*/) 250 { 251 return false; 252 } 253 254 void G4VtkQtViewer::EnableClipperWidget() 255 { 256 G4VtkViewer::EnableClipperWidget(); 257 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget); 258 qGLW->interactor()->Initialize(); 259 } 260 261 void G4VtkQtViewer::SetWidgetInteractor(vtkAbstractWidget* widget) 262 { 263 auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget); 264 widget->SetInteractor(qGLW->interactor()); 265 } 266