Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/Qt3D/src/G4Qt3DViewer.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /visualization/Qt3D/src/G4Qt3DViewer.cc (Version 11.3.0) and /visualization/Qt3D/src/G4Qt3DViewer.cc (Version 9.4.p2)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // John Allison  17th June 2019                   
 27                                                   
 28 #include "G4Qt3DViewer.hh"                        
 29                                                   
 30 #include "G4Qt3DSceneHandler.hh"                  
 31 #include "G4Qt3DUtils.hh"                         
 32                                                   
 33 #include "G4Scene.hh"                             
 34 #include "G4UImanager.hh"                         
 35 #include "G4UIQt.hh"                              
 36 #include "G4SystemOfUnits.hh"                     
 37                                                   
 38 #define G4warn G4cout                             
 39                                                   
 40 G4Qt3DViewer::G4Qt3DViewer                        
 41 (G4Qt3DSceneHandler& sceneHandler, const G4Str    
 42 : G4VViewer(sceneHandler, sceneHandler.Increme    
 43 , fQt3DSceneHandler(sceneHandler)                 
 44 , fKeyPressed(false)                              
 45 , fMousePressed(false)                            
 46 , fMousePressedX(0.)                              
 47 , fMousePressedY(0.)                              
 48 {}                                                
 49                                                   
 50 void G4Qt3DViewer::Initialise()                   
 51 {                                                 
 52   setObjectName(fName.c_str());                   
 53                                                   
 54   fVP.SetAutoRefresh(true);                       
 55   fDefaultVP.SetAutoRefresh(true);                
 56                                                   
 57   auto UI = G4UImanager::GetUIpointer();          
 58   auto uiQt = dynamic_cast<G4UIQt*>(UI->GetG4U    
 59   if (!uiQt) {                                    
 60     fViewId = -1;  // This flags an error.        
 61     G4warn << "G4Qt3DViewer::G4Qt3DViewer requ    
 62          << G4endl;                               
 63     return;                                       
 64   }                                               
 65   fUIWidget = QWidget::createWindowContainer(t    
 66   uiQt->AddTabWidget(fUIWidget,QString(fName))    
 67                                                   
 68   setRootEntity(fQt3DSceneHandler.fpQt3DScene)    
 69 }                                                 
 70                                                   
 71 G4Qt3DViewer::~G4Qt3DViewer()                     
 72 {                                                 
 73   setRootEntity(nullptr);                         
 74 }                                                 
 75                                                   
 76 void G4Qt3DViewer::resizeEvent(QResizeEvent*)     
 77   SetView();                                      
 78 }                                                 
 79                                                   
 80 void G4Qt3DViewer::SetView()                      
 81 {                                                 
 82   // Background colour                            
 83   defaultFrameGraph()->setClearColor(G4Qt3DUti    
 84                                                   
 85   // Get radius of scene, etc.                    
 86   // Note that this procedure properly takes i    
 87   const G4Point3D targetPoint                     
 88     = fSceneHandler.GetScene()->GetStandardTar    
 89     + fVP.GetCurrentTargetPoint ();               
 90   G4double radius = fSceneHandler.GetScene()->    
 91   if(radius<=0.) radius = 1.;                     
 92   const G4double cameraDistance = fVP.GetCamer    
 93   const G4Point3D cameraPosition =                
 94     targetPoint + cameraDistance * fVP.GetView    
 95   const GLdouble pnear  = fVP.GetNearDistance     
 96   const GLdouble pfar   = fVP.GetFarDistance      
 97   const GLdouble right  = fVP.GetFrontHalfHeig    
 98   const GLdouble left   = -right;                 
 99   const GLdouble top    = fVP.GetFrontHalfHeig    
100   const GLdouble bottom = -top;                   
101                                                   
102   camera()->setObjectName((fName + " camera").    
103   camera()->setViewCenter(G4Qt3DUtils::Convert    
104   camera()->setPosition(G4Qt3DUtils::ConvertTo    
105   camera()->setUpVector(G4Qt3DUtils::ConvertTo    
106                                                   
107 //  auto lightEntity = new Qt3DCore::QEntity(f    
108 //  auto directionalLight = new Qt3DRender::QD    
109 ////  directionalLight->setColor("white");        
110 ////  directionalLight->setIntensity(1.);         
111 //  directionalLight->setWorldDirection(G4Qt3D    
112 //  lightEntity->addComponent(directionalLight    
113                                                   
114   const auto& size = fUIWidget->size();           
115   G4double w = size.width();                      
116   G4double h = size.height();                     
117 #ifdef G4QT3DDEBUG                                
118   // Curiously w,h are wrong first time - 640,    
119   G4cout << "W,H: " << w << ',' << h << G4endl    
120 #endif                                            
121   const G4double aspectRatio = w/h;               
122   if (fVP.GetFieldHalfAngle() == 0.) {            
123     camera()->lens()->setOrthographicProjectio    
124     (left*aspectRatio,right*aspectRatio,bottom    
125   } else {                                        
126     camera()->lens()->setPerspectiveProjection    
127     (2.*fVP.GetFieldHalfAngle()/deg,aspectRati    
128   }                                               
129 }                                                 
130                                                   
131 void G4Qt3DViewer::ClearView()                    
132 {}                                                
133                                                   
134 void G4Qt3DViewer::DrawView()                     
135 {                                                 
136   // First, a view should decide when to re-vi    
137   // Sometimes it might not be necessary, e.g.    
138   // in a graphical database (e.g., OpenGL's d    
139   // the viewing angle has changed.  But graph    
140   // graphical database will always need to vi    
141                                                   
142   // The fNeedKernelVisit flag might have been    
143   // /vis/viewer/rebuild, but if not, make dec    
144   // if necessary...                              
145   if (!fNeedKernelVisit) KernelVisitDecision()    
146   G4bool kernelVisitWasNeeded = fNeedKernelVis    
147   fLastVP = fVP;                                  
148                                                   
149   ProcessView ();  // Clears store and process    
150                                                   
151   if (kernelVisitWasNeeded) {                     
152     // We might need to do something if the ke    
153   } else {                                        
154   }                                               
155                                                   
156   // ...before finally...                         
157   FinishView ();       // Flush streams and/or    
158 }                                                 
159                                                   
160 void G4Qt3DViewer::ShowView()                     
161 {                                                 
162 #if QT_VERSION < 0x060000                         
163   // show() may only be called from master thr    
164   if (G4Threading::IsMasterThread()) {            
165     show();                                       
166   }                                               
167   // The way Qt seems to work, we don't seem t    
168   // we'll leave it in - it seems not to have     
169 #endif                                            
170 }                                                 
171                                                   
172 void G4Qt3DViewer::FinishView()                   
173 {                                                 
174 #if QT_VERSION < 0x060000                         
175   if (G4Threading::IsMasterThread()) {            
176     show();                                       
177   }                                               
178 #endif                                            
179 }                                                 
180                                                   
181 // Note: the order of calling of MovingToVisSu    
182 // is undefined. The order of calling is          
183 //   DoneWithMasterThread                         
184 //   MovingToVisSubThread ) or ( SwitchToVisSu    
185 //   SwitchToVisSubThread )    ( MovingToVisSu    
186 //   DoneWithVisSubThread                         
187 //   MovingToMasterThread                         
188 //   SwitchToMasterThread                         
189 // So regarding the move/switch to the vis sub    
190 // If the viewer wishes to accept drawing from    
191 // But at this point we are still on the maste    
192 // not known. So it has to wait - a conditiona    
193 // and the provision of a pointer to the QThre    
194 // sub-thread has to wait until the QObjects h    
195                                                   
196 namespace {                                       
197   QThread* masterQThread = nullptr;               
198   QThread* visSubThreadQThread = nullptr;         
199                                                   
200   G4Mutex visSubThreadMutex = G4MUTEX_INITIALI    
201   G4Condition waitForVisSubThreadInitialized =    
202   G4bool visSubThreadEstablished = false;         
203   G4bool qObjectsSwitched = false;                
204 }                                                 
205                                                   
206 void G4Qt3DViewer::MovingToVisSubThread()         
207 // Still on master thread but vis thread has b    
208 {                                                 
209   // Make note of master QThread                  
210   masterQThread = QThread::currentThread();       
211                                                   
212   // Wait until SwitchToVisSubThread has found    
213   {                                               
214   G4AutoLock lock(&visSubThreadMutex);            
215   G4CONDITIONWAITLAMBDA(&waitForVisSubThreadIn    
216   }                                               
217                                                   
218   // Move relevant stuff to vis sub-thread QTh    
219   auto p1 = fQt3DSceneHandler.fpQt3DScene->par    
220   if(p1) {                                        
221     auto p2 = p1->parent();                       
222     if(p2) {                                      
223       p2->moveToThread(visSubThreadQThread);      
224     } else {                                      
225       p1->moveToThread(visSubThreadQThread);      
226     }                                             
227   }                                               
228                                                   
229   // Inform sub-thread                            
230   G4AutoLock lock(&visSubThreadMutex);            
231   qObjectsSwitched = true;                        
232   lock.unlock();                                  
233   G4CONDITIONBROADCAST(&waitForVisSubThreadIni    
234 }                                                 
235                                                   
236 void G4Qt3DViewer::SwitchToVisSubThread()         
237 // On vis sub-thread before any drawing           
238 {                                                 
239   // Make note of vis-subthread QThread for Mo    
240   visSubThreadQThread = QThread::currentThread    
241                                                   
242   // Let MovingToVisSubThread know we have the    
243   {                                               
244   G4AutoLock lock(&visSubThreadMutex);            
245   visSubThreadEstablished = true;                 
246   G4CONDITIONBROADCAST(&waitForVisSubThreadIni    
247   }                                               
248                                                   
249   // Wait until MovingToVisSubThread has moved    
250   {                                               
251   G4AutoLock lock(&visSubThreadMutex);            
252   G4CONDITIONWAITLAMBDA(&waitForVisSubThreadIn    
253   }                                               
254 }                                                 
255                                                   
256 void G4Qt3DViewer::MovingToMasterThread()         
257 // On vis sub-thread just before exit             
258 {                                                 
259   // Move relevant stuff to master QThread.       
260   auto p1 = fQt3DSceneHandler.fpQt3DScene->par    
261   if(p1) {                                        
262     auto p2 = p1->parent();                       
263     if(p2) {                                      
264       p2->moveToThread(masterQThread);            
265     } else {                                      
266       p1->moveToThread(masterQThread);            
267     }                                             
268   }                                               
269                                                   
270   // Reset                                        
271   visSubThreadQThread = nullptr;                  
272   qObjectsSwitched = false;                       
273 }                                                 
274                                                   
275 void G4Qt3DViewer::SwitchToMasterThread()         
276 // On master thread after vis sub-thread has t    
277 {                                                 
278   visSubThreadEstablished = false;                
279 }                                                 
280                                                   
281 void G4Qt3DViewer::KernelVisitDecision () {       
282                                                   
283   // If there's a significant difference with     
284   // of either the scene handler or this viewe    
285                                                   
286   if (CompareForKernelVisit(fLastVP)) {           
287     NeedKernelVisit ();  // Sets fNeedKernelVi    
288   }                                               
289 }                                                 
290                                                   
291 G4bool G4Qt3DViewer::CompareForKernelVisit(G4V    
292 {                                                 
293   // Typical comparison.  Taken from OpenInven    
294   if (                                            
295      (vp.GetDrawingStyle ()    != fVP.GetDrawi    
296      (vp.GetNumberOfCloudPoints()  != fVP.GetN    
297      (vp.IsAuxEdgeVisible ()   != fVP.IsAuxEdg    
298      (vp.IsCulling ()          != fVP.IsCullin    
299      (vp.IsCullingInvisible () != fVP.IsCullin    
300      (vp.IsDensityCulling ()   != fVP.IsDensit    
301      (vp.IsCullingCovered ()   != fVP.IsCullin    
302      (vp.GetCBDAlgorithmNumber() !=               
303       fVP.GetCBDAlgorithmNumber())                
304      (vp.IsSection ()          != fVP.IsSectio    
305      (vp.IsCutaway ()          != fVP.IsCutawa    
306      // This assumes use of generic clipping (    
307      // DCUT, cutaway).  If a decision is made    
308      // this will need changing.  See G4OpenGL    
309      // G4OpenGLStoredViewer.cc::CompareForKer    
310      // G4OpenGLStoredSceneHander::CreateSecti    
311      (vp.IsExplode ()          != fVP.IsExplod    
312      (vp.GetNoOfSides ()       != fVP.GetNoOfS    
313      (vp.GetGlobalMarkerScale()    != fVP.GetG    
314      (vp.GetGlobalLineWidthScale() != fVP.GetG    
315      (vp.IsMarkerNotHidden ()  != fVP.IsMarker    
316      (vp.GetDefaultVisAttributes()->GetColour(    
317       fVP.GetDefaultVisAttributes()->GetColour    
318      (vp.GetDefaultTextVisAttributes()->GetCol    
319       fVP.GetDefaultTextVisAttributes()->GetCo    
320      (vp.GetBackgroundColour ()!= fVP.GetBackg    
321      (vp.IsPicking ()          != fVP.IsPickin    
322      // Scaling for Open Inventor is done by t    
323      // needs a kernel visit.  (In this respec    
324      // OpenGL drivers, where it's done in Set    
325      (vp.GetScaleFactor ()     != fVP.GetScale    
326      (vp.GetVisAttributesModifiers() !=           
327       fVP.GetVisAttributesModifiers())            
328      (vp.IsSpecialMeshRendering() !=              
329       fVP.IsSpecialMeshRendering())               
330      (vp.GetSpecialMeshRenderingOption() !=       
331       fVP.GetSpecialMeshRenderingOption())        
332      )                                            
333   return true;                                    
334                                                   
335   if (vp.IsDensityCulling () &&                   
336       (vp.GetVisibleDensity () != fVP.GetVisib    
337     return true;                                  
338                                                   
339   if (vp.GetCBDAlgorithmNumber() > 0) {           
340     if (vp.GetCBDParameters().size() != fVP.Ge    
341     else if (vp.GetCBDParameters() != fVP.GetC    
342   }                                               
343                                                   
344   if (vp.IsSection () &&                          
345       (vp.GetSectionPlane () != fVP.GetSection    
346     return true;                                  
347                                                   
348   if (vp.IsCutaway ()) {                          
349     if (vp.GetCutawayMode() != fVP.GetCutawayM    
350     if (vp.GetCutawayPlanes ().size () !=         
351         fVP.GetCutawayPlanes ().size ()) retur    
352     for (size_t i = 0; i < vp.GetCutawayPlanes    
353     if (vp.GetCutawayPlanes()[i] != fVP.GetCut    
354       return true;                                
355   }                                               
356                                                   
357   if (vp.IsExplode () &&                          
358       (vp.GetExplodeFactor () != fVP.GetExplod    
359     return true;                                  
360                                                   
361   if (vp.IsSpecialMeshRendering() &&              
362       (vp.GetSpecialMeshVolumes() != fVP.GetSp    
363     return true;                                  
364                                                   
365   return false;                                   
366 }                                                 
367                                                   
368 void G4Qt3DViewer::keyPressEvent(QKeyEvent* ev    
369 {                                                 
370   fKeyPressed = true;                             
371   fKey = ev->key();                               
372 }                                                 
373                                                   
374 void G4Qt3DViewer::keyReleaseEvent(QKeyEvent*     
375 {                                                 
376   fKeyPressed = false;                            
377 }                                                 
378                                                   
379 void G4Qt3DViewer::mouseDoubleClickEvent(QMous    
380                                                   
381 void G4Qt3DViewer::mouseMoveEvent(QMouseEvent*    
382 {                                                 
383   // I think we only want these if a mouse but    
384   // But they come even when not pressed (on m    
385   // Documentation says:                          
386   /* Mouse move events will occur only when a     
387    unless mouse tracking has been enabled with    
388   // But this is a window not a widget.           
389   // As a workaround we maintain a flag change    
390 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))      
391   G4double x = ev->x();                           
392   G4double y = ev->y();                           
393 #else                                             
394   G4double x = ev->position().x();                
395   G4double y = ev->position().y();                
396 #endif                                            
397   G4double dx = x-fMousePressedX;                 
398   G4double dy = y-fMousePressedY;                 
399   fMousePressedX = x;                             
400   fMousePressedY = y;                             
401                                                   
402   if (fMousePressed) {                            
403                                                   
404     if (fKeyPressed && fKey == Qt::Key_Shift)     
405                                                   
406       const G4double sceneRadius = fQt3DSceneH    
407       const G4double scale = 300;  // Roughly     
408       const G4double dxScene = dx*sceneRadius/    
409       const G4double dyScene = dy*sceneRadius/    
410       fVP.IncrementPan(-dxScene,dyScene);         
411                                                   
412     } else {  // Rotation                         
413                                                   
414       // Simple ad-hoc algorithms                 
415       const G4Vector3D& x_prime = fVP.GetViewp    
416       const G4Vector3D& y_prime = x_prime.cros    
417       const G4double scale = 200;  // Roughly     
418       G4Vector3D newViewpointDirection = fVP.G    
419       newViewpointDirection += dx*x_prime/scal    
420       newViewpointDirection += dy*y_prime/scal    
421       fVP.SetViewpointDirection(newViewpointDi    
422                                                   
423       if (fVP.GetRotationStyle() == G4ViewPara    
424         G4Vector3D newUpVector = fVP.GetUpVect    
425         newUpVector += dx*x_prime/scale;          
426         newUpVector += dy*y_prime/scale;          
427         fVP.SetUpVector(newUpVector.unit());      
428       }                                           
429     }                                             
430   }                                               
431                                                   
432   SetView();                                      
433   DrawView();                                     
434 }                                                 
435                                                   
436 void G4Qt3DViewer::mousePressEvent(QMouseEvent    
437 {                                                 
438   fMousePressed = true;                           
439 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))      
440   fMousePressedX = ev->x();                       
441   fMousePressedY = ev->y();                       
442 #else                                             
443   fMousePressedX = ev->position().x();            
444   fMousePressedY = ev->position().y();            
445 #endif                                            
446 }                                                 
447                                                   
448 void G4Qt3DViewer::mouseReleaseEvent(QMouseEve    
449 {                                                 
450   fMousePressed = false;                          
451 }                                                 
452                                                   
453 void G4Qt3DViewer::wheelEvent(QWheelEvent* ev)    
454 {                                                 
455   // Take note of up-down motion only             
456   const G4double angleY = ev->angleDelta().y()    
457                                                   
458   if (fVP.GetFieldHalfAngle() == 0.) {  // Ort    
459     const G4double scale = 500;  // Empiricall    
460     fVP.MultiplyZoomFactor(1.+angleY/scale);      
461   } else {                              // Per    
462     const G4double delta = fSceneHandler.GetEx    
463     fVP.SetDolly(fVP.GetDolly()+angleY*delta);    
464   }                                               
465                                                   
466   SetView();                                      
467   DrawView();                                     
468 }                                                 
469