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 // Frederick Jones TRIUMF 07 November 2017 27 28 // this : 29 #include "G4OpenInventorQtViewer.hh" 30 31 #include "G4OpenInventorQtExaminerViewer.hh" 32 33 #include <Inventor/nodes/SoSelection.h> 34 35 #include <Inventor/Qt/SoQt.h> 36 // FWJ these are needed (why?) to use flags in SoQtExaminerViewer constr. 37 #include <Inventor/Qt/viewers/SoQtViewer.h> 38 #include <Inventor/Qt/viewers/SoQtFullViewer.h> 39 #include <Inventor/Qt/viewers/SoQtExaminerViewer.h> 40 41 //#include <QMenuBar> 42 #include <QMenu> 43 #include <QAction> 44 #include <QFont> 45 46 #include "HEPVis/actions/SoGL2PSAction.h" 47 48 #include "G4OpenInventor.hh" 49 #include "G4OpenInventorSceneHandler.hh" 50 #include "G4VInteractorManager.hh" 51 #include "G4VisManager.hh" 52 #include "G4UImanager.hh" 53 #include "G4UIQt.hh" 54 55 #include "G4SoQt.hh" 56 57 #ifndef G4GMAKE 58 #include "moc_G4OpenInventorQtViewer.cpp" 59 #endif 60 61 G4OpenInventorQtViewer::G4OpenInventorQtViewer( 62 G4OpenInventorSceneHandler& sceneHandler, const G4String& name) 63 : G4OpenInventorViewer(sceneHandler, name), fViewer(0) 64 #if 0x060000 <= QT_VERSION 65 ,fDestroyCallback(0) 66 #endif 67 { 68 #if 0x060000 <= QT_VERSION 69 fDestroyCallback = new G4OpenInventorQtDestroyCallback(this); 70 #endif 71 // FWJ fName is in G4VViewer parent of G4OpenInventorViewer 72 if (G4VisManager::GetVerbosity() >= G4VisManager::confirmations) 73 G4cout << "Window name: " << fName << G4endl; 74 } 75 76 77 void G4OpenInventorQtViewer::Initialise() 78 { 79 80 #if QT_VERSION < 0x060000 81 QWidget* parent = SoQt::getTopLevelWidget(); 82 #else 83 QWidget* parent = new QWidget; 84 QObject::connect(parent,SIGNAL(destroyed()),fDestroyCallback,SLOT(execute())); 85 #endif 86 87 // FWJ DEBUG 88 // G4cout << "G4OIQtViewer: Creating G4OIQtExaminerViewer with parent " << 89 // parent << G4endl; 90 91 fViewer = new G4OpenInventorQtExaminerViewer(parent, fName, TRUE); 92 93 #if 0x060000 <= QT_VERSION 94 fViewer->addInTab(); 95 #endif 96 97 // FWJ tried this to replace sensors, but it misses some camera changes. 98 // fGroupCameraSensor->detach(); 99 // fCameraSensor->detach(); 100 // fViewer->addFinishCallback(FinishCB); 101 102 auto UI = G4UImanager::GetUIpointer(); 103 auto uiQt = dynamic_cast<G4UIQt*>(UI->GetG4UIWindow()); 104 105 // Moved this to G4OpenInventorQtExaminerViewer::afterRealizeHook() 106 /////////////////////////////////////////////////////////// 107 // 108 // This explicitly sets the TabWidget as parent before addTab(): 109 // if (uiQt) uiQt->AddTabWidget(parent, QString(fName)); 110 /////////////////////////////////////////////////////////// 111 112 // Simpler: calls addTab(), but causes viewer parts to show (temporarily) 113 // in the "Useful tips" page !! 114 // if (uiQt) uiQt->AddViewerTab(parent, fName); 115 // Leaves an empty viewer window frame hanging around: 116 // if (uiQt) uiQt->AddTabWidget(fViewer->getWidget(), QString(fName)); 117 118 // G4String wName = fName; 119 // 120 // QWidget parent = (QWidget)fInteractorManager->GetParentInteractor(); 121 122 #if QT_VERSION < 0x060000 123 int width = fVP.GetWindowSizeHintX(); 124 int height = fVP.GetWindowSizeHintY(); 125 126 // FWJ not sure what this is for 127 // fInteractorManager->AddShell(fShell); 128 129 // FWJ or this: 130 // } else { 131 // char* str = fInteractorManager->GetCreationString(); 132 // if(str!=0) wName = str; 133 // fViewer = new SoQtExaminerViewer(parent,wName.c_str(),TRUE); 134 // } 135 136 fViewer->setSize(SbVec2s(width, height)); 137 fViewer->setOrigWindowSize(width, height); 138 #else 139 //G.Barrand: if in a QTabViewer, it is better to let the QTabWidget and 140 // SoQt set the size and position of the fViewer SoQtExaminerViewer. 141 #endif 142 143 // Add common menu items... 144 145 // QMenuBar* menubar = fViewer->getMenubar(); 146 QMenu* filemenu = fViewer->getFileMenu(); 147 QMenu* etcmenu = fViewer->getEtcMenu(); 148 QFont* font = fViewer->getFont(); 149 150 // File menu 151 152 FileWritePS = new QAction("Write PostScript (gl2ps)", this); 153 FileWritePS->setFont(*font); 154 connect(FileWritePS, SIGNAL(triggered()), this, 155 SLOT(FileWritePSCB())); 156 filemenu->addAction(FileWritePS); 157 158 FileWritePDF = new QAction("Write PDF (gl2ps)", this); 159 FileWritePDF->setFont(*font); 160 connect(FileWritePDF, SIGNAL(triggered()), this, 161 SLOT(FileWritePDFCB())); 162 filemenu->addAction(FileWritePDF); 163 164 FileWriteIV = new QAction("Write IV", this); 165 FileWriteIV->setFont(*font); 166 connect(FileWriteIV, SIGNAL(triggered()), this, 167 SLOT(FileWriteIVCB())); 168 filemenu->addAction(FileWriteIV); 169 170 FileEscape = new QAction("Escape", this); 171 FileEscape->setFont(*font); 172 connect(FileEscape, SIGNAL(triggered()), this, 173 SLOT(FileEscapeCB())); 174 filemenu->addAction(FileEscape); 175 176 // G4cout << "G4OIQtViewer: externalApp = " << 177 // static_cast<G4SoQt*>(fInteractorManager)->IsExternalApp() << G4endl; 178 if (static_cast<G4SoQt*>(fInteractorManager)->IsExternalApp()) 179 fViewer->setExternalQtApp(); 180 181 // Register escape CB with viewer, allowing E key escape 182 // fViewer->addEscapeCallback(FileEscapeCB); 183 // fViewer->addEscapeCallback(FileEscapeCB, (void*)this); 184 185 // Etc menu 186 187 EtcEraseDetector = new QAction("Erase detector", this); 188 EtcEraseDetector->setFont(*font); 189 connect(EtcEraseDetector, SIGNAL(triggered()), this, 190 SLOT(EtcEraseDetectorCB())); 191 etcmenu->addAction(EtcEraseDetector); 192 193 EtcEraseEvent = new QAction("Erase event", this); 194 EtcEraseEvent->setFont(*font); 195 connect(EtcEraseEvent, SIGNAL(triggered()), this, 196 SLOT(EtcEraseEventCB())); 197 etcmenu->addAction(EtcEraseEvent); 198 199 EtcSetSolid = new QAction("Set solid", this); 200 EtcSetSolid->setFont(*font); 201 connect(EtcSetSolid, SIGNAL(triggered()), this, SLOT(EtcSetSolidCB())); 202 etcmenu->addAction(EtcSetSolid); 203 204 EtcSetReducedWireframe = new QAction("Set (G4) reduced wireframe", this); 205 EtcSetReducedWireframe->setFont(*font); 206 connect(EtcSetReducedWireframe, SIGNAL(triggered()), this, 207 SLOT(EtcSetReducedWireframeCB())); 208 etcmenu->addAction(EtcSetReducedWireframe); 209 210 EtcSetFullWireframe = new QAction("Set full wireframe", this); 211 EtcSetFullWireframe->setFont(*font); 212 connect(EtcSetFullWireframe, SIGNAL(triggered()), this, 213 SLOT(EtcSetFullWireframeCB())); 214 etcmenu->addAction(EtcSetFullWireframe); 215 216 EtcVisibMInvisibD = new QAction("Visible mothers + invisible daughters", 217 this); 218 EtcVisibMInvisibD->setFont(*font); 219 connect(EtcVisibMInvisibD, SIGNAL(triggered()), this, 220 SLOT(EtcVisibMInvisibDCB())); 221 etcmenu->addAction(EtcVisibMInvisibD); 222 223 EtcVisibMVisibD = new QAction("Visible mothers + visible daughters", this); 224 EtcVisibMVisibD->setFont(*font); 225 connect(EtcVisibMVisibD, SIGNAL(triggered()), this, 226 SLOT(EtcVisibMVisibDCB())); 227 etcmenu->addAction(EtcVisibMVisibD); 228 229 EtcUpdateScene = new QAction("Update scene", this); 230 EtcUpdateScene->setFont(*font); 231 connect(EtcUpdateScene, SIGNAL(triggered()), this, 232 SLOT(EtcUpdateSceneCB())); 233 etcmenu->addAction(EtcUpdateScene); 234 235 EtcSceneGraphStats = new QAction("Scene graph stats", this); 236 EtcSceneGraphStats->setFont(*font); 237 connect(EtcSceneGraphStats, SIGNAL(triggered()), this, 238 SLOT(EtcSceneGraphStatsCB())); 239 etcmenu->addAction(EtcSceneGraphStats); 240 241 242 // Have a GL2PS render action : 243 const SbViewportRegion& vpRegion = fViewer->getViewportRegion(); 244 fGL2PSAction = new SoGL2PSAction(vpRegion); 245 fViewer->setGLRenderAction(fGL2PSAction); 246 247 // Else : 248 249 // FWJ DEBUG 250 // G4cout << "G4OpenInventorQtViewer: setting scene graph " << 251 // fSoSelection << G4endl; 252 // G4cout << "G4OpenInventorQtViewer: getNumChildren " << 253 // fSoSelection->getNumChildren() << G4endl; 254 255 fViewer->setSceneGraph(fSoSelection); 256 fViewer->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_ADD); 257 fViewer->viewAll(); 258 fViewer->saveHomePosition(); 259 // SOMEHOW this also the OIQt main window title 260 if (!uiQt) fViewer->setTitle(fName); 261 #if QT_VERSION < 0x060000 262 fViewer->show(); 263 264 // This SHOULD invoke the event loop: 265 // if(fShell) { 266 267 QWidget* mainWin = SoQt::getTopLevelWidget(); 268 269 // FWJ DEBUG 270 // G4cout << "G4OIQtViewer: calling SoQt::show on mainWin = " << mainWin 271 // << G4endl; 272 273 SoQt::show(mainWin); 274 fInteractorManager->FlushAndWaitExecution(); 275 276 // } 277 fInteractorManager->SetCreatedInteractor(fViewer->getWidget()); 278 #else 279 fViewer->setupSceneGraph(); 280 #endif 281 } 282 283 284 G4OpenInventorQtViewer::~G4OpenInventorQtViewer() 285 { 286 // if(fShell) fInteractorManager->RemoveShell(fShell); 287 if(fViewer) { 288 fViewer->setSceneGraph(0); 289 //FIXME : SGI : the below "delete" block things. 290 #if 0x060000 <= QT_VERSION 291 delete fViewer; 292 #endif 293 } 294 #if 0x060000 <= QT_VERSION 295 delete fDestroyCallback; 296 #endif 297 } 298 299 void G4OpenInventorQtViewer::FinishView() 300 { 301 if(!fViewer) return; 302 fViewer->viewAll(); 303 fViewer->saveHomePosition(); 304 } 305 306 void G4OpenInventorQtViewer::SetView() 307 { 308 G4OpenInventorViewer::SetView(); 309 if(!fViewer) return; 310 // Background. 311 G4Colour b = fVP.GetBackgroundColour(); 312 fViewer->setBackgroundColor 313 (SbColor((float)b.GetRed(),(float)b.GetGreen(),(float)b.GetBlue())); 314 } 315 316 void G4OpenInventorQtViewer::ViewerRender() 317 { 318 if(!fViewer) return; 319 fViewer->render(); 320 } 321 322 SoCamera* G4OpenInventorQtViewer::GetCamera () { 323 if(!fViewer) return 0; 324 return fViewer->getCamera(); 325 } 326 327 328 // User interaction finished: update VPs 329 //void G4OpenInventorQtViewer::FinishCB(void* data, SoQtViewer* viewer) 330 //{ 331 // G4cout << "FINISHCB CALLED !!!!!" << G4endl; 332 //} 333 334 335 // File menu... 336 337 void G4OpenInventorQtViewer::FileWritePSCB() 338 { 339 // G4cout << "G4OIQtViewer: File: Write PS CALLBACK" << G4endl; 340 // FWJ Workaround: avoids empty 2nd page in file 341 SbBool superimpState = 342 fViewer->getSuperimpositionEnabled(fViewer->superimposition); 343 fViewer->setSuperimpositionEnabled(fViewer->superimposition, FALSE); 344 WritePostScript(); 345 if (superimpState) 346 fViewer->setSuperimpositionEnabled(fViewer->superimposition, TRUE); 347 } 348 349 void G4OpenInventorQtViewer::FileWritePDFCB() 350 { 351 // G4cout << "G4OIQtViewer: File: Write PDF CALLBACK" << G4endl; 352 // FWJ Workaround: avoids empty 2nd page in file 353 SbBool superimpState = 354 fViewer->getSuperimpositionEnabled(fViewer->superimposition); 355 fViewer->setSuperimpositionEnabled(fViewer->superimposition, FALSE); 356 WritePDF(); 357 if (superimpState) 358 fViewer->setSuperimpositionEnabled(fViewer->superimposition, TRUE); 359 } 360 361 void G4OpenInventorQtViewer::FileWriteIVCB() 362 { 363 // G4cout << "G4OIQtViewer: File: Write IV CALLBACK" << G4endl; 364 WriteInventor(); 365 } 366 367 void G4OpenInventorQtViewer::FileEscapeCB() 368 { 369 // G4cout << "G4OIQtViewer: File: Escape CALLBACK" << G4endl; 370 static_cast<G4SoQt*>(fInteractorManager)->ExitSecondaryLoop(); 371 // Escape(); 372 } 373 374 // Etc menu... 375 376 void 377 G4OpenInventorQtViewer::EtcEraseDetectorCB() 378 { 379 // G4cout << "G4OIQtViewer: Etc: Erase Detector CALLBACK" << G4endl; 380 EraseDetector(); 381 } 382 383 void 384 G4OpenInventorQtViewer::EtcEraseEventCB() 385 { 386 // G4cout << "G4OIQtViewer: Etc: Erase Event CALLBACK" << G4endl; 387 EraseEvent(); 388 } 389 390 void G4OpenInventorQtViewer::EtcSetSolidCB() 391 { 392 // G4cout << "G4OIQtViewer: Etc: Set Solid CALLBACK" << G4endl; 393 SetSolid(); 394 } 395 396 void G4OpenInventorQtViewer::EtcSetReducedWireframeCB() 397 { 398 // G4cout << "G4OIQtViewer: Etc: Set Reduced Wireframe CALLBACK" << G4endl; 399 SetReducedWireFrame(true); 400 } 401 402 void G4OpenInventorQtViewer::EtcSetFullWireframeCB() 403 { 404 // G4cout << "G4OIQtViewer: Etc: Set Full Wireframe CALLBACK" << G4endl; 405 SetReducedWireFrame(false); 406 } 407 408 void G4OpenInventorQtViewer::EtcVisibMInvisibDCB() 409 { 410 // G4cout << "G4OIQtViewer: Etc: Visible Mothers + Invisible Daughters" 411 // " CALLBACK" << G4endl; 412 SetPreview(); 413 } 414 415 void G4OpenInventorQtViewer::EtcVisibMVisibDCB() 416 { 417 // G4cout << "G4OIQtViewer: Etc: Visible Mothers + Visible Daughters" 418 // "CALLBACK" << G4endl; 419 SetPreviewAndFull(); 420 } 421 422 void G4OpenInventorQtViewer::EtcUpdateSceneCB() 423 { 424 // G4cout << "G4OIQtViewer: Etc: Update Scene CALLBACK" << G4endl; 425 UpdateScene(); 426 } 427 428 void G4OpenInventorQtViewer::EtcSceneGraphStatsCB() 429 { 430 // G4cout << "G4OIQtViewer: Etc: Scene Graph Stats CALLBACK" << G4endl; 431 SceneGraphStatistics(); 432 } 433