Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/OpenGL/src/G4OpenGLStoredQtViewer.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 ]

  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 //
 27 //
 28 //
 29 // Class G4OpenGLStoredQtViewer : a class derived from G4OpenGLQtViewer and
 30 //                                G4OpenGLStoredViewer.
 31 
 32 #include "G4OpenGLStoredQtViewer.hh"
 33 
 34 #include "G4OpenGLStoredSceneHandler.hh"
 35 #include "G4ios.hh"
 36 #include "G4Threading.hh"
 37 #include "G4UIQt.hh"
 38 #if 0x060000 <= QT_VERSION
 39 #include "G4Qt.hh"
 40 #endif
 41 
 42 #include <qapplication.h>
 43 #include <qtabwidget.h>
 44 
 45 G4OpenGLStoredQtViewer::G4OpenGLStoredQtViewer
 46 (G4OpenGLStoredSceneHandler& sceneHandler,
 47  const G4String&  name):
 48   G4VViewer (sceneHandler, sceneHandler.IncrementViewCount (), name),
 49   G4OpenGLViewer (sceneHandler),
 50   G4OpenGLQtViewer (sceneHandler),
 51   G4OpenGLStoredViewer (sceneHandler),             // FIXME : gerer le pb du parent !
 52   G4QGLWidgetType()
 53 {
 54   if (fViewId < 0) return;  // In case error in base class instantiation.
 55 
 56 #if QT_VERSION < 0x060000
 57   fQGLWidgetInitialiseCompleted = false;
 58 
 59     // Indicates that the widget has no background, i.e. when the widget receives paint events, the background is not automatically repainted. Note: Unlike WA_OpaquePaintEvent, newly exposed areas are never filled with the background (e.g., after showing a window for the first time the user can see "through" it until the application processes the paint events). This flag is set or cleared by the widget's author.
 60   G4QGLWidgetType::setAttribute (Qt::WA_NoSystemBackground);
 61 
 62   setFocusPolicy(Qt::StrongFocus); // enable keybord events
 63   fHasToRepaint = false;
 64   fPaintEventLock = false;
 65   fUpdateGLLock = false;
 66 #else
 67   // Indicates that the widget has no background, i.e. when the widget receives paint events, the background is not automatically repainted. Note: Unlike WA_OpaquePaintEvent, newly exposed areas are never filled with the background (e.g., after showing a window for the first time the user can see "through" it until the application processes the paint events). This flag is set or cleared by the widget's author.
 68   G4QGLWidgetType::setAttribute (Qt::WA_NoSystemBackground);
 69 
 70   setFocusPolicy(Qt::StrongFocus); // enable keybord events
 71 #endif
 72 }
 73 
 74 G4OpenGLStoredQtViewer::~G4OpenGLStoredQtViewer() {}
 75 
 76 void G4OpenGLStoredQtViewer::Initialise() {
 77 #if QT_VERSION < 0x060000
 78 
 79   fQGLWidgetInitialiseCompleted = false;
 80   CreateMainWindow (this,QString(GetName()));
 81 
 82   makeCurrent();
 83   glDrawBuffer (GL_BACK);
 84 
 85    // set the good tab active
 86   if (G4QGLWidgetType::parentWidget()) {
 87     auto *parentTab = dynamic_cast<QTabWidget*> (G4QGLWidgetType::parentWidget()->parent()) ;
 88     if (parentTab) {
 89       parentTab->setCurrentIndex(parentTab->count()-1);
 90     }
 91   }
 92   
 93   fQGLWidgetInitialiseCompleted = true;
 94 #else
 95   CreateMainWindow (this,QString(GetName()));
 96   // Set jpg as default export format for Qt viewer
 97   setExportImageFormat("jpg");
 98 #endif
 99 }
100 
101 #if QT_VERSION < 0x060000
102 void G4OpenGLStoredQtViewer::initializeGL () {
103 
104   InitializeGLView ();
105 
106   if (fSceneHandler.GetScene() == 0) {
107     fHasToRepaint =false;
108   } else {
109     fHasToRepaint =true;
110   }
111   
112    // Set the component visible
113   //   setVisible(true) ;
114 
115   // Set jpg as default export format for Qt viewer
116   setExportImageFormat("jpg");
117 }
118 #endif
119 
120 G4bool G4OpenGLStoredQtViewer::CompareForKernelVisit(G4ViewParameters& lastVP)
121 {
122   // Identical to G4OpenGLStoredViewer::CompareForKernelVisit except
123   // for checking of VisAttributesModifiers, because
124   // G4OpenGLStoredQtViewer keeps track of its own touchable
125   // modifiers (fTreeItemModels, etc.).
126   if (
127       (lastVP.GetDrawingStyle ()    != fVP.GetDrawingStyle ())    ||
128       (lastVP.GetNumberOfCloudPoints()  != fVP.GetNumberOfCloudPoints())  ||
129       (lastVP.IsAuxEdgeVisible ()   != fVP.IsAuxEdgeVisible ())   ||
130       (lastVP.IsCulling ()          != fVP.IsCulling ())          ||
131       (lastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
132       (lastVP.IsDensityCulling ()   != fVP.IsDensityCulling ())   ||
133       (lastVP.IsCullingCovered ()   != fVP.IsCullingCovered ())   ||
134       (lastVP.GetCBDAlgorithmNumber() !=
135        fVP.GetCBDAlgorithmNumber())                               ||
136       // Note: Section and Cutaway can reveal back-facing faces. If
137       // backface culling is implemented, the image can look strange because
138       // the back-facing faces are not there. For the moment, we have disabled
139       // (commented out) backface culling (it seems not to affect performance -
140       // in fact, performance seems to improve), so there is no problem.
141       (lastVP.IsSection ()          != fVP.IsSection ())          ||
142       // Section (DCUT) is NOT implemented locally so we need to visit the kernel.
143       // (lastVP.IsCutaway ()          != fVP.IsCutaway ())          ||
144       // Cutaways are implemented locally so we do not need to visit the kernel.
145       (lastVP.IsExplode ()          != fVP.IsExplode ())          ||
146       (lastVP.GetNoOfSides ()       != fVP.GetNoOfSides ())       ||
147       (lastVP.GetGlobalMarkerScale()    != fVP.GetGlobalMarkerScale())    ||
148       (lastVP.GetGlobalLineWidthScale() != fVP.GetGlobalLineWidthScale()) ||
149       (lastVP.IsMarkerNotHidden ()  != fVP.IsMarkerNotHidden ())  ||
150       (lastVP.GetDefaultVisAttributes()->GetColour() !=
151        fVP.GetDefaultVisAttributes()->GetColour())                ||
152       (lastVP.GetDefaultTextVisAttributes()->GetColour() !=
153        fVP.GetDefaultTextVisAttributes()->GetColour())            ||
154       (lastVP.GetBackgroundColour ()!= fVP.GetBackgroundColour ())||
155       (lastVP.IsPicking ()          != fVP.IsPicking ())          ||
156       (lastVP.IsSpecialMeshRendering() != fVP.IsSpecialMeshRendering()) ||
157       (lastVP.GetSpecialMeshRenderingOption() != fVP.GetSpecialMeshRenderingOption()))
158     return true;
159 
160   // Don't check VisAttributesModifiers if this comparison has been
161   // initiated by a mouse interaction on the scene tree.
162   if (fMouseOnSceneTree) {
163     // Reset the flag.
164     fMouseOnSceneTree = false;
165   } else {
166     // Not initiated by a mouse so compare for kernel visit.
167     if (lastVP.GetVisAttributesModifiers() != fVP.GetVisAttributesModifiers()) {
168       return true;
169     }
170   }
171 
172   if (lastVP.IsDensityCulling () &&
173       (lastVP.GetVisibleDensity () != fVP.GetVisibleDensity ()))
174     return true;
175 
176 //  /**************************************************************
177 //   If section (DCUT) is implemented locally, comment this out.
178   if (lastVP.IsSection () &&
179       (lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
180     return true;
181 //   ***************************************************************/
182 
183   /**************************************************************
184    If cutaways are implemented locally, comment this out.
185    if (lastVP.IsCutaway ()) {
186    if (vp.GetCutawayMode() != fVP.GetCutawayMode()) return true;
187    if (lastVP.GetCutawayPlanes ().size () !=
188    fVP.GetCutawayPlanes ().size ()) return true;
189    for (size_t i = 0; i < lastVP.GetCutawayPlanes().size(); ++i)
190    if (lastVP.GetCutawayPlanes()[i] != fVP.GetCutawayPlanes()[i])
191    return true;
192    }
193    ***************************************************************/
194 
195   if (lastVP.GetCBDAlgorithmNumber() > 0) {
196     if (lastVP.GetCBDParameters().size() != fVP.GetCBDParameters().size()) return true;
197     else if (lastVP.GetCBDParameters() != fVP.GetCBDParameters()) return true;
198   }
199 
200   if (lastVP.IsExplode () &&
201       (lastVP.GetExplodeFactor () != fVP.GetExplodeFactor ()))
202     return true;
203 
204   if (lastVP.IsSpecialMeshRendering() &&
205       (lastVP.GetSpecialMeshVolumes() != fVP.GetSpecialMeshVolumes()))
206     return true;
207 
208   return false;
209 }
210 
211 G4bool G4OpenGLStoredQtViewer::POSelected(size_t POListIndex)
212 {
213   return isTouchableVisible((int)POListIndex);
214 }
215 
216 G4bool G4OpenGLStoredQtViewer::TOSelected(size_t)
217 {
218   return true;
219 }
220 
221 void G4OpenGLStoredQtViewer::DrawView () {
222 #if QT_VERSION < 0x060000
223 #else
224   if(IsGettingPickInfos()) {
225     paintGL();
226     return;
227   }
228 #endif
229 #if (QT_VERSION < 0x060000) || !defined(G4MULTITHREADED)
230   updateQWidget();
231 #else
232   if (G4Threading::IsMasterThread()) {
233     updateQWidget();
234   } else {
235     update(); //G.Barrand: updateQWidget() induces a crash on run beamOn.
236   }
237 #endif
238 }
239 
240 void G4OpenGLStoredQtViewer::ComputeView () {
241 
242 #if QT_VERSION < 0x060000
243   makeCurrent();
244 #endif
245 
246   G4ViewParameters::DrawingStyle dstyle = GetViewParameters().GetDrawingStyle();
247 
248   //Make sure current viewer is attached and clean...
249 
250   //See if things have changed from last time and remake if necessary...
251   // The fNeedKernelVisit flag might have been set by the user in
252   // /vis/viewer/rebuild, but if not, make decision and set flag only
253   // if necessary...
254   if (!fNeedKernelVisit) {
255     KernelVisitDecision ();
256   }
257   fLastVP = fVP;
258   G4bool kernelVisitWasNeeded = fNeedKernelVisit; // Keep (ProcessView resets).
259   ProcessView ();
260    
261   if (kernelVisitWasNeeded) {
262     displaySceneTreeComponent();
263   }
264 
265   if(dstyle!=G4ViewParameters::hlr &&
266      haloing_enabled) {
267 
268     HaloingFirstPass ();
269     DrawDisplayLists ();
270     glFlush ();
271 
272     HaloingSecondPass ();
273 
274     DrawDisplayLists ();
275     FinishView ();
276 
277   } else {
278      
279     // If kernel visit was needed, drawing and FinishView will already
280     // have been done, so...
281     if (!kernelVisitWasNeeded) {
282       DrawDisplayLists ();
283       FinishView ();
284     } else {
285       // However, union cutaways are implemented in DrawDisplayLists, so make
286       // an extra pass...
287       if (fVP.IsCutaway() &&
288           fVP.GetCutawayMode() == G4ViewParameters::cutawayUnion) {
289         ClearView();
290         DrawDisplayLists ();
291         FinishView ();
292       } else { // ADD TO AVOID KernelVisit=1 and nothing to display
293         DrawDisplayLists ();
294         FinishView ();
295       }
296     }
297   }
298 
299   if (isRecording()) {
300     savePPMToTemp();
301   }
302 
303 #if QT_VERSION < 0x060000
304   fHasToRepaint = true;
305 #endif
306 }
307 
308 
309 /**
310    - Lors du resize de la fenetre, on doit non pas redessiner le detecteur, mais aussi les evenements
311 */
312 void G4OpenGLStoredQtViewer::resizeGL(
313                                       int aWidth
314                                       ,int aHeight)
315 {  
316   // Set new size, it will be update when next Repaint()->SetView() called
317   if ((aWidth > 0) && (aHeight > 0)) {
318 #if QT_VERSION < 0x060000
319     ResizeWindow(aWidth,aHeight);
320     fHasToRepaint = sizeHasChanged();
321 #else
322     ResizeWindow(devicePixelRatio()*aWidth,devicePixelRatio()*aHeight);
323 #endif
324   }
325 }
326 
327 
328 // We have to get several case :
329 // - Only activate the windows (mouse click for example) -> Do not redraw
330 // - resize window -> redraw
331 // - try to avoid recompute everything if we do not rescale picture (side is the same)
332  
333 void G4OpenGLStoredQtViewer::paintGL()
334 {
335 #if QT_VERSION < 0x060000
336   updateToolbarAndMouseContextMenu();
337 #else
338   //G.Barrand: don't do any change in the GUI here, just "paint" this widget!
339 #endif
340 
341 #if QT_VERSION < 0x060000
342   if (fPaintEventLock) {
343 //    return ;
344   }
345   fPaintEventLock = true;
346   if ((getWinWidth() == 0) && (getWinHeight() == 0)) {
347     return;
348   }
349 
350   if (!fQGLWidgetInitialiseCompleted) {
351     fPaintEventLock = false;
352     return;
353   }
354 
355   // DO NOT RESIZE IF SIZE HAS NOT CHANGE :
356   //    WHEN CLICK ON THE FRAME FOR EXAMPLE
357   //    EXECEPT WHEN MOUSE MOVE EVENT
358   if ( !fHasToRepaint) {
359     // L. Garnier : Trap to get the size with mac OSX 10.6 and Qt 4.6(devel)
360     // Tested on Qt4.5 on mac, 4.4 on windows, 4.5 on unbuntu
361     int sw = 0;
362     int sh = 0;
363     if (!isMaximized() && !isFullScreen()) {
364       sw = normalGeometry().width();
365       sh = normalGeometry().height();
366     } else {
367       sw = frameGeometry().width();
368       sh = frameGeometry().height();
369     }
370     if ((getWinWidth() == (unsigned int)sw) &&(getWinHeight() == (unsigned int)sh)) {
371       return;
372     }
373   }
374 #else
375   if ((getWinWidth() == 0) && (getWinHeight() == 0)) return;  //G.Barrand: needed?
376 #endif
377 
378 #if QT_VERSION < 0x060000
379 #else
380   InitializeGLView ();
381 #endif
382 
383   // Ensure that we really draw the BACK buffer
384   glDrawBuffer (GL_BACK);
385 
386   SetView();
387   
388   ClearView (); //ok, put the background correct
389   ComputeView();
390 
391 #if QT_VERSION < 0x060000
392   fHasToRepaint = false;
393 
394   fPaintEventLock = false;
395 #endif
396 }
397 
398 #if QT_VERSION < 0x060000
399 void G4OpenGLStoredQtViewer::paintEvent(QPaintEvent *) {
400   if (! fQGLWidgetInitialiseCompleted) {
401     return;
402   }
403   // Force a repaint next time if the FRAMEBUFFER is not READY
404   fHasToRepaint = isFramebufferReady();
405   if ( fHasToRepaint) {
406     // Will really update the widget by calling CGLFlushDrawable
407     // The widget's rendering context will become the current context and initializeGL()
408     // will be called if it hasn't already been called.
409     // Copies the back buffer of a double-buffered context to the front buffer.
410 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
411     updateGL();
412 #else
413     // Not sure this is correct....
414     paintGL();
415 #endif
416   }
417 }
418 #endif
419 
420 void G4OpenGLStoredQtViewer::mousePressEvent(QMouseEvent *event)
421 {
422   G4MousePressEvent(event);
423 }
424 
425 void G4OpenGLStoredQtViewer::keyPressEvent (QKeyEvent * event) 
426 {
427   G4keyPressEvent(event);
428 }
429 
430 void G4OpenGLStoredQtViewer::keyReleaseEvent (QKeyEvent * event)
431 {
432   G4keyReleaseEvent(event);
433 }
434 
435 void G4OpenGLStoredQtViewer::wheelEvent (QWheelEvent * event)
436 {
437   G4wheelEvent(event);
438 }
439 
440 #if QT_VERSION < 0x060000
441 void G4OpenGLStoredQtViewer::showEvent (QShowEvent *)
442 {
443   if (fQGLWidgetInitialiseCompleted) {
444     fHasToRepaint = true;
445   }
446 }
447 #endif
448 
449 /**
450  * This function was build in order to make a zoom on double clic event.
451  * It was think to build a rubberband on the zoom area, but never work fine
452  */
453 void G4OpenGLStoredQtViewer::mouseDoubleClickEvent(QMouseEvent *)
454 {
455   G4MouseDoubleClickEvent();
456 }
457 
458 void G4OpenGLStoredQtViewer::mouseReleaseEvent(QMouseEvent *event)
459 {
460   G4MouseReleaseEvent(event);
461 }
462 
463 void G4OpenGLStoredQtViewer::mouseMoveEvent(QMouseEvent *event)
464 {
465   G4MouseMoveEvent(event);
466 }
467 
468 
469 void G4OpenGLStoredQtViewer::contextMenuEvent(QContextMenuEvent *e)
470 {
471   G4manageContextMenuEvent(e);
472 }
473 
474 void G4OpenGLStoredQtViewer::updateQWidget() {
475 #if QT_VERSION < 0x060000
476   if (fUpdateGLLock) {
477     return;
478   }
479   
480   if (! isCurrentWidget()){
481     return;
482   }
483 
484   fUpdateGLLock = true;
485   fHasToRepaint= true;
486   // Will really update the widget by calling CGLFlushDrawable
487   // The widget's rendering context will become the current context and initializeGL()
488   // will be called if it hasn't already been called.
489   // Copies the back buffer of a double-buffered context to the front buffer.
490   repaint(); // will read scene tree state
491   // updateGL() // From J.Allison picking branch
492   updateViewerPropertiesTableWidget();
493   updateSceneTreeWidget();
494   fUpdateGLLock = false;
495 #else
496   //if (!isCurrentWidget()) return; //G.Barrand: Qt must know if it has to activate paintGL() if the widget is not visible.
497   //G.Barrand: don't do any change in the GUI here, just ask to "paint" this widget!
498   update();
499 #endif
500 }
501 
502 void G4OpenGLStoredQtViewer::ShowView ()
503 {
504   activateWindow();
505 #if 0x060000 <= QT_VERSION
506   ((QApplication*)G4Qt::getInstance ())->processEvents();
507 #endif
508 }
509 
510 
511 void G4OpenGLStoredQtViewer::DisplayTimePOColourModification (
512 G4Colour& c,
513 size_t poIndex) {
514   c = getColorForPoIndex((int)poIndex);
515 }
516