ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4OpenGLWtViewer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4OpenGLWtViewer.cc
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 // G4OpenGLWtViewer : Class to provide Wt specific
30 // functionality for OpenGL in GEANT4
31 //
32 // 27/06/2003 : G.Barrand : implementation (at last !).
33 
34 #ifdef G4VIS_BUILD_OPENGLWT_DRIVER
35 
36 #include "G4OpenGLWtViewer.hh"
37 #include "G4VViewer.hh"
38 #include "G4VSceneHandler.hh"
39 #include "G4OpenGLSceneHandler.hh"
40 
41 #include "G4ios.hh"
42 #include "G4VisExtent.hh"
43 #include "G4LogicalVolume.hh"
44 #include "G4VSolid.hh"
45 #include "G4Point3D.hh"
46 #include "G4Normal3D.hh"
47 #include "G4Scene.hh"
48 //#include "G4OpenGLWtExportDialog.hh"
49 //#include "G4OpenGLWtMovieDialog.hh"
50 #include "G4UnitsTable.hh"
51 #include "G4Wt.hh"
52 #include "G4UIWt.hh"
53 #include "G4UImanager.hh"
54 #include "G4UIcommandTree.hh"
55 #include <Wt/WHBoxLayout>
56 #include <Wt/WApplication>
57 #include <Wt/WTime>
58 
59 
60 
61 
63 void G4OpenGLWtViewer::CreateMainWindow (
64  Wt::WGLWidget* glWidget
65  ,Wt::WString name
66 )
67 
68 
69 {
70 #ifdef G4DEBUG_VIS_OGL
71  printf("G4OpenGLWtViewer::CreateMainWindow \n");
72 #endif
73 
74  if(fWindow) return; //Done.
75 
76  fWindow = glWidget ;
77  // fWindow->makeCurrent();
78 
79 // G4Wt* interactorManager = G4Wt::getInstance ();
80  // return false if G4UIWt was not launch
81 
83  if (UI == NULL) return;
84 
85  if (! static_cast<G4UIWt*> (UI->GetG4UIWindow())) {
86  // NO UI, should be batch mode
87  fBatchMode = true;
88  return;
89  }
90  fUiWt = static_cast<G4UIWt*> (UI->GetG4UIWindow());
91 
92  bool isTabbedView = false;
93  if ( fUiWt) {
94  if (!fBatchMode) {
95 // if (!interactorManager->IsExternalApp()) {
96 
97  // resize window to get the good size at the beginning
98  ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY());
99 
100  isTabbedView = fUiWt->AddTabWidget(fWindow->parent(),name,getWinWidth(),getWinHeight());
101  // change color
102  fWindow->parent()->decorationStyle().setBackgroundColor (Wt::WColor("blue"));
103 
104  // Have to resize !
105 #ifdef G4DEBUG_VIS_OGL
106  printf("G4OpenGLWtViewer::CreateMainWindow :: resize :%d %d\n",getWinWidth(),getWinHeight());
107 #endif
108  fWindow->resize(getWinWidth(),getWinHeight());
109 
110  fUISceneTreeComponentsTBWidget = fUiWt->GetSceneTreeComponentsTBWidget();
111  fWindow->resize(fWindow->parent()->width(),fWindow->parent()->height());
112  isTabbedView = true;
113  // }
114  }
115  }
116 #ifdef G4DEBUG_VIS_OGL
117  else {
118  printf("G4OpenGLWtViewer::CreateMainWindow :: UIWt NOt found \n");
119  }
120 #endif
121 
122 
123 /* if (!isTabbedView) { // we have to do a dialog
124 
125  Wt::WWidget *myParent = getParentWidget();
126 #ifdef G4DEBUG_VIS_OGL
127  printf("G4OpenGLWtViewer::CreateMainWindow :: getParent OK \n");
128 #endif
129  if (myParent != NULL) {
130  glWidget->setParent(myParent);
131  }
132  Wt::WHBoxLayout *mainLayout = new Wt::WHBoxLayout(fGLWindow);
133 
134  mainLayout->setMargin(0);
135  mainLayout->setSpacing(0);
136  mainLayout->addWidget(fWindow);
137  if (fGLWindow->inherits("Wt::WContainerWidget")) {
138  fGLWindow->setWindowTitle( name);
139  }
140  fGLWindow->setLayout(mainLayout);
141 
142  */
143 /*
144  //useful for MACOSX, we have to compt the menuBar height
145  int offset = QApplication::desktop()->height()
146  - QApplication::desktop()->availableGeometry().height();
147 
148  G4int YPos= fVP.GetWindowAbsoluteLocationHintY(QApplication::desktop()->height());
149  if (fVP.GetWindowAbsoluteLocationHintY(QApplication::desktop()->height())< offset) {
150  YPos = offset;
151  }
152 #ifdef G4DEBUG_VIS_OGL
153  printf("G4OpenGLQtViewer::CreateMainWindow :: resizing to %d %d \n",getWinWidth(), getWinHeight());
154 #endif
155  fGLWindow->move(fVP.GetWindowAbsoluteLocationHintX(QApplication::desktop()->width()),YPos);
156 */
157 // fGLWindow->show();
158 // } else {
159 
160  fGLWindow = fWindow;
161 // }
162 
163  if(!fWindow) return;
164 
165 #ifdef _A_FINIR_FIXME
166  if (!fContextMenu)
167  createPopupMenu();
168 #endif
169 
170 }
171 
174 // void G4OpenGLWtViewer::dialogClosed() {
175 // // fGLWindow = NULL;
176 // }
177 
179 G4OpenGLWtViewer::G4OpenGLWtViewer (
180  G4OpenGLSceneHandler& scene
181  )
182  :G4VViewer (scene, -1)
183  ,G4OpenGLViewer (scene)
184  ,fWindow(0)
185  ,fRecordFrameNumber(0)
186  //#ifdef _A_FINIR_FIXME ,fContextMenu(0)
187  ,fMouseAction(STYLE1)
188  ,fDeltaRotation(1)
189  ,fDeltaSceneTranslation(0.01)
190  ,fDeltaDepth(0.01)
191  ,fDeltaZoom(0.05)
192  ,fDeltaMove(0.05)
193  ,fHoldKeyEvent(false)
194  ,fHoldMoveEvent(false)
195  ,fHoldRotateEvent(false)
196  ,fAutoMove(false)
197  ,fEncoderPath("")
198  ,fTempFolderPath("")
199  ,fMovieTempFolderPath("")
200  ,fSaveFileName("")
201  ,fParameterFileName("mpeg_encode_parameter_file.par")
202  ,fMovieParametersDialog(NULL)
203  ,fRecordingStep(WAIT)
204  ,fProcess(NULL)
205  ,fNbMaxFramesPerSec(100)
206  ,fNbMaxAnglePerSec(360)
207  ,fLaunchSpinDelay(100)
208  ,fXRot(0)
209  ,fYRot(0)
210  ,fNoKeyPress(true)
211  ,fAltKeyPress(false)
212  ,fControlKeyPress(false)
213  ,fShiftKeyPress(false)
214  ,fBatchMode(false)
215  ,fUiWt(NULL)
216 {
217 
218  // launch Wt if not
219  G4Wt::getInstance ();
220 
221 // FIXME : all stuff with G4VIS_BUILD_OPENGL_ES_DRIVER
222  // G4OpenGLViewer::SetView(this);
223 
224 #ifdef G4DEBUG_VIS_OGL
225  printf("G4OpenGLWtViewer::Create \n");
226 #endif
227  fLastPos3 = Wt::WPoint(-1,-1);
228  fLastPos2 = Wt::WPoint(-1,-1);
229  fLastPos1 = Wt::WPoint(-1,-1);
230 
231  mMatrix.setToIdentity();
232 
233 #ifdef _A_FINIR_FIXME
234  initMovieParameters();
235 #endif
236 
237  fLastEventTime = new Wt::WTime();
238 
239 #ifdef G4DEBUG_VIS_OGL
240  printf("G4OpenGLWtViewer::G4OpenGLWtViewer END\n");
241 #endif
242 
243 }
244 
245 
246 
247 
248 
249 void G4OpenGLWtViewer::resizeGL(int width, int height)
250  {
251 #ifdef G4DEBUG_VIS_OGL
252  printf("G4OpenGLWtViewer resizeGL %d %d\n",width,height);
253 #endif
254 
255  }
256 
257 
258 
259 
261 G4OpenGLWtViewer::~G4OpenGLWtViewer (
262 )
263 
264 
265 {
266 #ifdef _A_FINIR_FIXME
267  G4cout <<removeTempFolder().toUTF8().c_str() <<G4endl;
268 #endif
269 }
270 
271 
272 
273 
274 
275 #ifdef _A_FINIR_FIXME
276 
279 void G4OpenGLWtViewer::createPopupMenu() {
280 
281  fContextMenu = new WMenu("All");
282 
283  WMenu *mMouseAction = fContextMenu->addMenu("&Mouse actions");
284 
285  fRotateAction = mMouseAction->addAction("Rotate");
286  fMoveAction = mMouseAction->addAction("Move");
287  fPickAction = mMouseAction->addAction("Pick");
288  WAction *shortcutsAction = mMouseAction->addAction("Show shortcuts");
289 
290  fRotateAction->setCheckable(true);
291  fMoveAction->setCheckable(false);
292  fPickAction->setCheckable(false);
293  shortcutsAction->setCheckable(false);
294 
295  fRotateAction->setChecked(true);
296  fMoveAction->setChecked(false);
297  fPickAction->setChecked(false);
298  shortcutsAction->setChecked(false);
299 
300  WObject ::connect(fRotateAction,
301  SIGNAL(triggered(bool)),
302  this,
303  SLOT(actionMouseRotate()));
304 
305  WObject ::connect(fMoveAction,
306  SIGNAL(triggered(bool)),
307  this,
308  SLOT(actionMouseMove()));
309 
310  WObject ::connect(fPickAction,
311  SIGNAL(triggered(bool)),
312  this,
313  SLOT(actionMousePick()));
314 
315  WObject ::connect(shortcutsAction,
316  SIGNAL(triggered(bool)),
317  this,
318  SLOT(showShortcuts()));
319 
320  // === Style Menu ===
321  WMenu *mStyle = fContextMenu->addMenu("&Style");
322 
323  WMenu *mRepresentation = mStyle->addMenu("&Representation");
324  WMenu *mProjection = mStyle->addMenu("&Projection");
325  WAction *polyhedron = mRepresentation->addAction("Polyhedron");
326  WAction *nurbs = mRepresentation->addAction("NURBS");
327 
328  WAction *ortho = mProjection->addAction("Orthographic");
329  WAction *perspective = mProjection->addAction("Persepective");
330 
331  // INIT mRepresentation
332  G4ViewParameters::RepStyle style;
333  style = fVP.GetRepStyle();
334  if (style == G4ViewParameters::polyhedron) {
335  createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),1);
336  } else if (style == G4ViewParameters::nurbs) {
337  createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),2);
338  } else {
339  mRepresentation->clear();
340  }
341 
342  // INIT mProjection
343  if (fVP.GetFieldHalfAngle() == 0) {
344  createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),1);
345  } else {
346  createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),2);
347  }
348 
349  // === Drawing Menu ===
350  WMenu *mDrawing = mStyle->addMenu("&Drawing");
351 
352  fDrawingWireframe = mDrawing->addAction("Wireframe");
353  fDrawingWireframe->setCheckable(true);
354 
355  fDrawingLineRemoval = mDrawing->addAction("Hidden line removal");
356  fDrawingLineRemoval->setCheckable(true);
357 
358  fDrawingSurfaceRemoval = mDrawing->addAction("Hidden Surface removal");
359  fDrawingSurfaceRemoval->setCheckable(true);
360 
361  fDrawingLineSurfaceRemoval = mDrawing->addAction("Hidden line and surface removal");
362  fDrawingLineSurfaceRemoval->setCheckable(true);
363 
364  // INIT Drawing
366  d_style = fVP.GetDrawingStyle();
367 
368  if (d_style == G4ViewParameters::wireframe) {
369  fDrawingWireframe->setChecked(true);
370  } else if (d_style == G4ViewParameters::hlr) {
371  fDrawingLineRemoval->setChecked(true);
372  } else if (d_style == G4ViewParameters::hsr) {
373  fDrawingSurfaceRemoval->setChecked(true);
374  } else if (d_style == G4ViewParameters::hlhsr) {
375  fDrawingLineSurfaceRemoval->setChecked(true);
376  } else {
377  mDrawing->clear();
378  }
379  WObject ::connect(fDrawingWireframe,
380  SIGNAL(triggered(bool)),
381  this,
382  SLOT(actionDrawingWireframe()));
383  WObject ::connect(fDrawingLineRemoval,
384  SIGNAL(triggered(bool)),
385  this,
386  SLOT(actionDrawingLineRemoval()));
387  WObject ::connect(fDrawingSurfaceRemoval,
388  SIGNAL(triggered(bool)),
389  this,
390  SLOT(actionDrawingSurfaceRemoval()));
391  WObject ::connect(fDrawingLineSurfaceRemoval,
392  SIGNAL(triggered(bool)),
393  this,
394  SLOT(actionDrawingLineSurfaceRemoval()));
395 
396  // Background Color
397 
398  WAction *backgroundColorChooser ;
399 
400  // === Action Menu ===
401  backgroundColorChooser = mStyle->addAction("Background color");
402  WObject ::connect(backgroundColorChooser,
403  SIGNAL(triggered()),
404  this,
405  SLOT(actionChangeBackgroundColor()));
406 
407  // Text Color
408 
409  WAction *textColorChooser ;
410  // === Action Menu ===
411  textColorChooser = mStyle->addAction("Text color");
412  WObject ::connect(textColorChooser,
413  SIGNAL(triggered()),
414  this,
415  SLOT(actionChangeTextColor()));
416 
417  // Default Color
418 
419  WAction *defaultColorChooser ;
420  // === Action Menu ===
421  defaultColorChooser = mStyle->addAction("Default color");
422  WObject ::connect(defaultColorChooser,
423  SIGNAL(triggered()),
424  this,
425  SLOT(actionChangeDefaultColor()));
426 
427 
428  // === Action Menu ===
429  WMenu *mActions = fContextMenu->addMenu("&Actions");
430  WAction *createEPS = mActions->addAction("Save as ...");
431  WObject ::connect(createEPS,
432  SIGNAL(triggered()),
433  this,
434  SLOT(actionSaveImage()));
435 
436  // === Action Menu ===
437  WAction *movieParameters = mActions->addAction("Movie parameters...");
438  WObject ::connect(movieParameters,
439  SIGNAL(triggered()),
440  this,
441  SLOT(actionMovieParameters()));
442 
443 
444 
445 
446  // === Special Menu ===
447  WMenu *mSpecial = fContextMenu->addMenu("S&pecial");
448  WMenu *mTransparency = mSpecial->addMenu("Transparency");
449  WAction *transparencyOn = mTransparency->addAction("On");
450  WAction *transparencyOff = mTransparency->addAction("Off");
451 
452  if (transparency_enabled == false) {
453  createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),2);
454  } else if (transparency_enabled == true) {
455  createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),1);
456  } else {
457  mSpecial->clear();
458  }
459 
460 
461  WMenu *mAntialiasing = mSpecial->addMenu("Antialiasing");
462  WAction *antialiasingOn = mAntialiasing->addAction("On");
463  WAction *antialiasingOff = mAntialiasing->addAction("Off");
464 
465  if (antialiasing_enabled == false) {
466  createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),2);
467  } else if (antialiasing_enabled == true) {
468  createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),1);
469  } else {
470  mAntialiasing->clear();
471  }
472 
473  WMenu *mHaloing = mSpecial->addMenu("Haloing");
474  WAction *haloingOn = mHaloing->addAction("On");
475  WAction *haloingOff = mHaloing->addAction("Off");
476 
477  if (haloing_enabled == false) {
478  createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),2);
479  } else if (haloing_enabled == true) {
480  createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),1);
481  } else {
482  mHaloing->clear();
483  }
484 
485  WMenu *mAux = mSpecial->addMenu("Auxiliary edges");
486  WAction *auxOn = mAux->addAction("On");
487  WAction *auxOff = mAux->addAction("Off");
488  if (!fVP.IsAuxEdgeVisible()) {
489  createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),1);
490  } else {
491  createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),2);
492  }
493 
494 
495 
496  WMenu *mFullScreen = mSpecial->addMenu("&Full screen");
497  fFullScreenOn = mFullScreen->addAction("On");
498  fFullScreenOff = mFullScreen->addAction("Off");
499  createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(bool)),2);
500 
501 }
502 
503 
504 void G4OpenGLWtViewer::G4manageContextMenuEvent(WContextMenuEvent *e)
505 {
506  if (!fGLWindow) {
507  G4cerr << "Visualization window not defined, please choose one before" << G4endl;
508  } else {
509 
510  if (!fContextMenu)
511  createPopupMenu();
512 
513  // launch menu
514  if ( fContextMenu ) {
515  fContextMenu->exec( e->globalPos() );
516  // delete fContextMenu;
517  }
518  }
519  e->accept();
520 }
521 
522 
531 void G4OpenGLWtViewer::createRadioAction(WAction *action1,WAction *action2, const std::string& method,unsigned int nCheck) {
532 
533  action1->setCheckable(true);
534  action2->setCheckable(true);
535 
536  if (nCheck ==1)
537  action1->setChecked (true);
538  else
539  action2->setChecked (true);
540 
541  WObject ::connect(action1, SIGNAL(triggered(bool)),action2, SLOT(toggle()));
542  WObject ::connect(action2, SIGNAL(triggered(bool)),action1, SLOT(toggle()));
543 
544  WObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
545 
546 }
547 
551 void G4OpenGLWtViewer::actionMouseRotate() {
552  emit toggleMouseAction(STYLE1);
553 }
554 
555 
559 void G4OpenGLWtViewer::actionMouseMove() {
560  emit toggleMouseAction(STYLE2);
561 }
562 
563 
567 void G4OpenGLWtViewer::actionMousePick() {
568  emit toggleMouseAction(STYLE3);
569 }
570 
571 
575 void G4OpenGLWtViewer::actionDrawingWireframe() {
576  emit toggleDrawingAction(1);
577 }
578 
582 void G4OpenGLWtViewer::actionDrawingLineRemoval() {
583  emit toggleDrawingAction(2);
584 }
585 
589 void G4OpenGLWtViewer::actionDrawingSurfaceRemoval() {
590  emit toggleDrawingAction(3);
591 }
592 
596 void G4OpenGLWtViewer::actionDrawingLineSurfaceRemoval() {
597  emit toggleDrawingAction(4);
598 }
599 
600 
605 void G4OpenGLWtViewer::toggleMouseAction(mouseActions aAction) {
606 
607  if ((aAction == STYLE1) || //initialize all
608  (aAction == STYLE2) ||
609  (aAction == STYLE3)) {
610  fRotateAction->setChecked (false);
611  fMoveAction->setChecked (false);
612  fPickAction->setChecked (false);
613  fVP.SetPicking(false);
614  fMouseAction = aAction;
615  }
616  // rotate
617  if (aAction == STYLE1) { // rotate
618  showShortcuts();
619  fRotateAction->setChecked (true);
620  } else if (aAction == STYLE2) { //move
621  fMoveAction->setChecked (true);
622  } else if (aAction == STYLE3) { //pick
623  fPickAction->setChecked (true);
624  fVP.SetPicking(true);
625  }
626 }
627 
628 #endif
629 
632 void G4OpenGLWtViewer::showShortcuts() {
633  G4cout << "========= Mouse Shortcuts =========" << G4endl;
634  if (fMouseAction == STYLE1) { // rotate
635  G4cout << "Click and move mouse to rotate volume " << G4endl;
636  G4cout << "ALT + Click and move mouse to rotate volume (View Direction)" << G4endl;
637  G4cout << "CTRL + Click and zoom mouse to zoom in/out" << G4endl;
638  G4cout << "SHIFT + Click and zoommove camera point of view" << G4endl;
639  } else if (fMouseAction == STYLE2) { //move
640  G4cout << "Move camera point of view with mouse" << G4endl;
641  } else if (fMouseAction == STYLE3) { //pick
642  G4cout << "Click and pick " << G4endl;
643  }
644  G4cout << "========= Move Shortcuts =========" << G4endl;
645  G4cout << "Press left/right arrows to move volume left/right" << G4endl;
646  G4cout << "Press up/down arrows to move volume up/down" << G4endl;
647  G4cout << "Press '+'/'-' to move volume toward/forward" << G4endl;
648  G4cout << G4endl;
649  G4cout << "========= Rotation (Theta/Phi) Shortcuts =========" << G4endl;
650  G4cout << "Press SHIFT + left/right arrows to rotate volume left/right" << G4endl;
651  G4cout << "Press SHIFT + up/down arrows to rotate volume up/down" << G4endl;
652  G4cout << G4endl;
653  G4cout << "========= Rotation (View Direction) Shortcuts =========" << G4endl;
654  G4cout << "Press ALT + left/right to rotate volume around vertical direction" << G4endl;
655  G4cout << "Press ALT + up/down to rotate volume around horizontal direction" << G4endl;
656  G4cout << G4endl;
657  G4cout << "========= Zoom View =========" << G4endl;
658  G4cout << "Press CTRL + '+'/'-' to zoom into volume" << G4endl;
659  G4cout << G4endl;
660  G4cout << "========= Misc =========" << G4endl;
661  G4cout << "Press ALT +/- to slow/speed rotation/move" << G4endl;
662  G4cout << "Press H to reset view" << G4endl;
663  G4cout << "Press Esc to exit FullScreen" << G4endl;
664  G4cout << G4endl;
665  G4cout << "========= Video =========" << G4endl;
666  G4cout << "In video mode : " << G4endl;
667  G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
668  G4cout << " Press RETURN to Stop video recording " << G4endl;
669  G4cout << G4endl;
670 }
671 
672 
673 
674 #ifdef _A_FINIR_FIXME
675 
686 void G4OpenGLWtViewer::toggleDrawingAction(int aAction) {
687 
689 
690 
691  // initialize
692  if ((aAction >0) && (aAction <5)) {
693  fDrawingWireframe->setChecked (false);
694  fDrawingLineRemoval->setChecked (false);
695  fDrawingSurfaceRemoval->setChecked (false);
696  fDrawingLineSurfaceRemoval->setChecked (false);
697  }
698  if (aAction ==1) {
699  fDrawingWireframe->setChecked (true);
700 
701  d_style = G4ViewParameters::wireframe;
702 
703  } else if (aAction ==2) {
704  fDrawingLineRemoval->setChecked (true);
705 
706  d_style = G4ViewParameters::hlr;
707 
708  } else if (aAction ==3) {
709  fDrawingSurfaceRemoval->setChecked (true);
710 
711  d_style = G4ViewParameters::hsr;
712 
713  } else if (aAction ==4) {
714  fDrawingLineSurfaceRemoval->setChecked (true);
715  d_style = G4ViewParameters::hlhsr;
716  }
717  fVP.SetDrawingStyle(d_style);
718 
719  updateWWidget();
720 }
721 
722 
733 void G4OpenGLWtViewer::toggleRepresentation(bool check) {
734 
735  G4ViewParameters::RepStyle style;
736  if (check == 1) {
737  style = G4ViewParameters::polyhedron;
738  } else {
739  style = G4ViewParameters::nurbs;
740  }
741  fVP.SetRepStyle (style);
742 
743  updateWWidget();
744 }
745 
756 void G4OpenGLWtViewer::toggleProjection(bool check) {
757 
758  if (check == 1) {
759  G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection o");
760  } else {
761  G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection p");
762  }
763  updateWWidget();
764 }
765 
766 
771 void G4OpenGLWtViewer::toggleTransparency(bool check) {
772 
773  if (check) {
774  transparency_enabled = false;
775  } else {
776  transparency_enabled = true;
777  }
778  SetNeedKernelVisit (true);
779  updateWWidget();
780 }
781 
786 void G4OpenGLWtViewer::toggleAntialiasing(bool check) {
787 
788  if (!check) {
789  antialiasing_enabled = false;
790  glDisable (GL_LINE_SMOOTH);
791  glDisable (GL_POLYGON_SMOOTH);
792  } else {
793  antialiasing_enabled = true;
794  glEnable (GL_LINE_SMOOTH);
795  glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
796  glEnable (GL_POLYGON_SMOOTH);
797  glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
798  }
799 
800  updateWWidget();
801 }
802 
807 //FIXME : I SEE NOTHING...
808 void G4OpenGLWtViewer::toggleHaloing(bool check) {
809  if (check) {
810  haloing_enabled = false;
811  } else {
812  haloing_enabled = true;
813  }
814 
815  updateWWidget();
816 
817 }
818 
823 void G4OpenGLWtViewer::toggleAux(bool check) {
824  if (check) {
825  fVP.SetAuxEdgeVisible(true);
826  } else {
827  fVP.SetAuxEdgeVisible(false);
828  }
829  SetNeedKernelVisit (true);
830  updateWWidget();
831 }
832 
836 void G4OpenGLWtViewer::toggleFullScreen(bool check) {
837  if (check != fGLWindow->isFullScreen()) { //toggle
838  fGLWindow->setWindowState(fGLWindow->windowState() ^ Wt::WindowFullScreen);
839  G4cerr << "This version of Wt could not do fullScreen. Resizing the widget is the only solution available." << G4endl;
840  }
841 }
842 #endif
843 
844 #ifdef _A_FINIR_FIXME
845 void G4OpenGLWtViewer::savePPMToTemp() {
846  if (fMovieTempFolderPath == "") {
847  return;
848  }
849  Wt::WString fileName ="Test"+Wt::WString::number(fRecordFrameNumber)+".ppm";
850  Wt::WString filePath =fMovieTempFolderPath+fileName;
851 
852  WImage image;
853  image = fWindow->grabFrameBuffer();
854  bool res = false;
855 
856  res = image.save(filePath,0);
857  if (res == false) {
858  resetRecording();
859  setRecordingInfos("Can't save tmp file "+filePath);
860  return;
861  }
862 
863  setRecordingInfos("File "+fileName+" saved");
864  fRecordFrameNumber++;
865 }
866 
867 
868 
869 void G4OpenGLWtViewer::actionSaveImage() {
870  Wt::WString filters;
871  WList<WByteArray> formats = WImageWriter::supportedImageFormats ();
872  for (int i = 0; i < formats.size(); ++i) {
873  filters +=formats.at(i) + ";;";
874  }
875  filters += "eps;;";
876  filters += "ps;;";
877  filters += "pdf";
878  Wt::WString* selectedFormat = new Wt::WString();
879  std::string name;
880  name = WFileDialog::getSaveFileName ( fGLWindow,
881  tr("Save as ..."),
882  ".",
883  filters,
884  selectedFormat ).toUTF8().c_str();
885  // bmp jpg jpeg png ppm xbm xpm
886  if (name.empty()) {
887  return;
888  }
889  name += "." + selectedFormat->toUTF8();
890  Wt::WString format = selectedFormat->toLower();
891  setPrintFilename(name.c_str(),0);
892  G4OpenGLWtExportDialog* exportDialog= new G4OpenGLWtExportDialog(fGLWindow,format,fWindow->height(),fWindow->width());
893  if( exportDialog->exec()) {
894 
895  WImage image;
896  bool res = false;
897  if ((exportDialog->getWidth() !=fWindow->width()) ||
898  (exportDialog->getHeight() !=fWindow->height())) {
899  setPrintSize(exportDialog->getWidth(),exportDialog->getHeight());
900  if ((format != Wt::WString("eps")) && (format != Wt::WString("ps"))) {
901  G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
902 
903  // rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
904  // WGLWidget* glResized = fWindow;
905 
906  // FIXME :
907  // L.Garnier : I've try to implement change size function, but the problem is
908  // the renderPixmap function call the WGLWidget to resize and it doesn't draw
909  // the content of this widget... It only draw the background.
910 
911  // fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
912 
913  // WPixmap pixmap = fWindow->renderPixmap ();
914 
915  // image = pixmap->toImage();
916  // glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
917  // image = glResized->grabFrameBuffer();
918  }
919  } else {
920  image = fWindow->grabFrameBuffer();
921  }
922  if (format == Wt::WString("eps")) {
923  fVectoredPs = exportDialog->getVectorEPS();
924  printEPS();
925  } else if (format == "ps") {
926  fVectoredPs = true;
927  printEPS();
928  } else if (format == "pdf") {
929 
930  res = printPDF(name,exportDialog->getNbColor(),image);
931 
932  } else if ((format == "tif") ||
933  (format == "tiff") ||
934  (format == "jpg") ||
935  (format == "jpeg") ||
936  (format == "png") ||
937  (format == "pbm") ||
938  (format == "pgm") ||
939  (format == "ppm") ||
940  (format == "bmp") ||
941  (format == "xbm") ||
942  (format == "xpm")) {
943  res = image.save(Wt::WString(name.c_str()),0,exportDialog->getSliderValue());
944  } else {
945  G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
946  }
947  if ((format == Wt::WString("eps")) && (format == Wt::WString("ps"))) {
948  if (res == false) {
949  G4cerr << "Error while saving file... "<<name.c_str()<< G4endl;
950  } else {
951  G4cout << "File "<<name.c_str()<<" has been saved " << G4endl;
952  }
953  }
954 
955  } else { // cancel selected
956  return;
957  }
958 
959 }
960 #endif
961 
962 
963 #ifdef _A_FINIR_FIXME
964 void G4OpenGLWtViewer::actionChangeBackgroundColor() {
965 
966  // //I need to revisit the kernel if the background colour changes and
967  // //hidden line removal is enabled, because hlr drawing utilises the
968  // //background colour in its drawing...
969  // // (Note added by JA 13/9/2005) Background now handled in view
970  // // parameters. A kernel visit is triggered on change of background.
971 
972  WColor color;
973  color = WColorDialog::getColor(Wt::black, fGLWindow);
974  if (color.isValid()) {
975  Wt::WString com = "/vis/viewer/set/background ";
976  Wt::WString num;
977  com += num.setNum(((float)color.red())/256)+" ";
978  com += num.setNum(((float)color.green())/256)+" ";
979  com += num.setNum(((float)color.blue())/256)+" ";
980  G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
981  updateWWidget();
982  }
983 }
984 
985 void G4OpenGLWtViewer::actionChangeTextColor() {
986 
987  WColor color;
988  color = WColorDialog::getColor(Wt::yellow, fGLWindow);
989  if (color.isValid()) {
990  Wt::WString com = "/vis/viewer/set/defaultTextColour ";
991  Wt::WString num;
992  com += num.setNum(((float)color.red())/256)+" ";
993  com += num.setNum(((float)color.green())/256)+" ";
994  com += num.setNum(((float)color.blue())/256)+" ";
995  G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
996  updateWWidget();
997  }
998 }
999 
1000 void G4OpenGLWtViewer::actionChangeDefaultColor() {
1001 
1002  WColor color;
1003  color = WColorDialog::getColor(Wt::white, fGLWindow);
1004  printf("actionChangeDefaultColor\n");
1005  if (color.isValid()) {
1006  Wt::WString com = "/vis/viewer/set/defaultColour ";
1007  Wt::WString num;
1008  com += num.setNum(((float)color.red())/256)+" ";
1009  com += num.setNum(((float)color.green())/256)+" ";
1010  com += num.setNum(((float)color.blue())/256)+" ";
1011  G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
1012  updateWWidget();
1013  }
1014 }
1015 
1016 
1017 void G4OpenGLWtViewer::actionMovieParameters() {
1018  showMovieParametersDialog();
1019 }
1020 
1021 
1022 void G4OpenGLWtViewer::showMovieParametersDialog() {
1023  if (!fMovieParametersDialog) {
1024  fMovieParametersDialog= new G4OpenGLWtMovieDialog(this,fGLWindow);
1025  displayRecordingStatus();
1026  fMovieParametersDialog->checkEncoderSwParameters();
1027  fMovieParametersDialog->checkSaveFileNameParameters();
1028  fMovieParametersDialog->checkTempFolderParameters();
1029  if (getEncoderPath() == "") {
1030  setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
1031  }
1032  }
1033  fMovieParametersDialog->show();
1034 }
1035 #endif
1036 
1037 /*
1038 // http://www.google.com/codesearch?hl=en&q=+jpg+Wt+quality+WDialog+show:FZkUoth8oiw:TONpW2mR-_c:tyTfrKMO-xI&sa=N&cd=2&ct=rc&cs_p=http://soft.proindependent.com/src/qtiplot-0.8.9.zip&cs_f=qtiplot-0.8.9/qtiplot/src/application.cpp#a0
1039 
1040 void Graph::exportToSVG(const Wt::WString& fname)
1041 {
1042  // enable workaround for Wt3 misalignments
1043  WwtPainter::setSVGMode(true);
1044  WPicture picture;
1045  WPainter p(&picture);
1046  d_plot->print(&p, d_plot->rect());
1047  p.end();
1048 
1049  picture.save(fname, "svg");
1050 }
1051 */
1052 
1053 
1054 
1059 void G4OpenGLWtViewer::G4MousePressEvent(Wt::WMouseEvent *event)
1060 {
1061  if (event->button() & Wt::WMouseEvent::LeftButton) {
1062 #ifdef _A_FINIR_FIXME
1063  fWindow->setMouseTracking(true);
1064 #endif
1065  fAutoMove = false; // stop automove
1066  fLastPos1 = Wt::WPoint(event->widget().x,event->widget().y);
1067  fLastPos2 = fLastPos1;
1068  fLastPos3 = fLastPos2;
1069 // fLastEventTime->start();
1070  if (fMouseAction == STYLE3){ // pick
1071  Pick(event->widget().x,event->widget().y);
1072  }
1073  }
1074 }
1075 
1078 void G4OpenGLWtViewer::G4MouseReleaseEvent()
1079 {
1080  fSpinningDelay = 1;//fLastEventTime->elapsed();
1081  Wt::WPoint delta = Wt::WPoint(fLastPos3.x()-fLastPos1.x(),fLastPos3.y()-fLastPos1.y());
1082  if ((delta.x() == 0) && (delta.y() == 0)) {
1083  return;
1084  }
1085  if (fSpinningDelay < fLaunchSpinDelay ) {
1086  fAutoMove = true;
1087  Wt::WTime lastMoveTime;
1088 // lastMoveTime.start();
1089  // try to addapt speed move/rotate looking to drawing speed
1090  float correctionFactor = 5;
1091  while (fAutoMove) {
1092 // if ( lastMoveTime.elapsed () >= (int)(1000/fNbMaxFramesPerSec)) {
1093  if ( 1 >= (int)(1000/fNbMaxFramesPerSec)) {
1094  float lTime = 1000/((float)1);
1095  if (((((float)delta.x())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1096  ((((float)delta.x())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1097  correctionFactor = (float)delta.x()*(lTime/fNbMaxAnglePerSec);
1098  if (delta.x() <0 ) {
1099  correctionFactor = -correctionFactor;
1100  }
1101  }
1102  if (((((float)delta.y())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1103  ((((float)delta.y())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1104  correctionFactor = (float)delta.y()*(lTime/fNbMaxAnglePerSec);
1105  if (delta.y() <0 ) {
1106  correctionFactor = -correctionFactor;
1107  }
1108  }
1109 
1110  // Check Wt Versions for META Keys
1111 
1112  // Click and move mouse to rotate volume
1113  // ALT + Click and move mouse to rotate volume (View Direction)
1114  // SHIFT + Click and move camera point of view
1115  // CTRL + Click and zoom mouse to zoom in/out
1116 
1117  if (fMouseAction == STYLE1) { // rotate
1118  if (fNoKeyPress) {
1119  rotateWtScene(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1120  } else if (fAltKeyPress) {
1121  rotateWtSceneToggle(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1122  }
1123 
1124  } else if (fMouseAction == STYLE2) { // move
1125  moveScene(-((float)delta.x())/correctionFactor,-((float)delta.y())/correctionFactor,0,true);
1126  }
1127 // lastMoveTime.start();
1128  }
1129 #ifdef _A_FINIR_FIXME
1130  ((Wt::WApplication*)G4Wt::getInstance ())->processEvents();
1131 #endif
1132  }
1133  }
1134 #ifdef _A_FINIR_FIXME
1135  fWindow->setMouseTracking(false);
1136 #endif
1137 }
1138 
1139 
1140 void G4OpenGLWtViewer::G4MouseDoubleClickEvent()
1141 {
1142 #ifdef _A_FINIR_FIXME
1143  fWindow->setMouseTracking(true);
1144 #endif
1145 }
1146 
1147 
1155  void G4OpenGLWtViewer::G4MouseMoveEvent(Wt::WMouseEvent *event)
1156 {
1157 
1158  Wt::WMouseEvent::Button mButtons = event->button();
1159 
1160 #ifdef _A_FINIR_FIXME
1161  updateKeyModifierState(event->modifiers());
1162 #endif
1163 
1164  if (fAutoMove) {
1165  return;
1166  }
1167 
1168  fLastPos3 = fLastPos2;
1169  fLastPos2 = fLastPos1;
1170  fLastPos1 = Wt::WPoint(event->widget().x, event->widget().y);
1171 
1172  printf("G4OpenGLWtViewer move :%d %d\n",event->widget().x, event->widget().y);
1173  int deltaX = fLastPos2.x()-fLastPos1.x();
1174  int deltaY = fLastPos2.y()-fLastPos1.y();
1175 
1176  if (fMouseAction == STYLE1) { // rotate
1177  if (mButtons & Wt::WMouseEvent::LeftButton) {
1178  if (fNoKeyPress) {
1179  rotateWtScene(((float)deltaX),((float)deltaY));
1180  } else if (fAltKeyPress) {
1181  rotateWtSceneToggle(((float)deltaX),((float)deltaY));
1182  } else if (fShiftKeyPress) {
1183  unsigned int sizeWin;
1184  sizeWin = getWinWidth();
1185  if (getWinHeight() < getWinWidth()) {
1186  sizeWin = getWinHeight();
1187  }
1188 
1189  // L.Garnier : 08/2010 100 is the good value, but don't ask me why !
1190  float factor = ((float)100/(float)sizeWin) ;
1191  moveScene(-(float)deltaX*factor,-(float)deltaY*factor,0,false);
1192  } else if (fControlKeyPress) {
1193  fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+((float)deltaY)));
1194  }
1195  }
1196  } else if (fMouseAction == STYLE2) { // move
1197  if (mButtons & Wt::WMouseEvent::LeftButton) {
1198  moveScene(-deltaX,-deltaY,0,true);
1199  }
1200  }
1201 
1202 // fLastEventTime->start();
1203 }
1204 
1205 
1213 void G4OpenGLWtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1214 {
1215  if (fHoldMoveEvent)
1216  return;
1217  fHoldMoveEvent = true;
1218 
1219  G4double coefTrans = 0;
1220  GLdouble coefDepth = 0;
1221  if(mouseMove) {
1222  coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinWidth());
1223  if (getWinHeight() <getWinWidth()) {
1224  coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
1225  }
1226  } else {
1227  coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1228  coefDepth = getSceneDepth()*fDeltaDepth;
1229  }
1230  fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1231  updateWWidget();
1232  if (fAutoMove)
1233 #ifdef _A_FINIR_FIXME
1234  ((WApplication*)G4Wt::getInstance ())->processEvents();
1235 #endif
1236 
1237  fHoldMoveEvent = false;
1238 }
1239 
1240 
1246 void G4OpenGLWtViewer::rotateWtScene(float dx, float dy)
1247 {
1248  if (fHoldRotateEvent)
1249  return;
1250  fHoldRotateEvent = true;
1251 
1252  if( dx != 0) {
1253  rotateScene(dx,0);
1254  }
1255  if( dy != 0) {
1256  rotateScene(0,dy);
1257  }
1258  updateWWidget();
1259 
1260  fHoldRotateEvent = false;
1261 }
1262 
1268 void G4OpenGLWtViewer::rotateWtSceneToggle(float dx, float dy)
1269 {
1270  if (fHoldRotateEvent)
1271  return;
1272  fHoldRotateEvent = true;
1273 
1274  rotateSceneToggle(dx,dy);
1275 
1276  updateWWidget();
1277 
1278  fHoldRotateEvent = false;
1279 }
1280 
1293 void G4OpenGLWtViewer::rescaleImage(
1294  int /* aWidth */
1295 ,int /* aHeight */
1296 ){
1297  // GLfloat* feedback_buffer;
1298  // GLint returned;
1299  // FILE* file;
1300 
1301 // feedback_buffer = new GLfloat[size];
1302 // glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1303 // glRenderMode (GL_FEEDBACK);
1304 
1305 // DrawView();
1306 // returned = glRenderMode (GL_RENDER);
1307 
1308 }
1309 
1310 
1311 
1312 #ifdef _A_FINIR_FIXME
1313 
1319 bool G4OpenGLWtViewer::printPDF (
1320  const std::string aFilename
1321 ,int aInColor
1322 ,WImage aImage
1323 )
1324 {
1325 
1326  WPrinter printer;
1327  // printer.setPageSize(pageSize);
1328 
1329  // FIXME : L. Garnier 4/12/07
1330  // This is not working, it does nothing. Image is staying in color mode
1331  // So I have desactivate the B/W button in GUI
1332  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1333  aImage = aImage.convertToFormat ( aImage.format(), Wt::MonoOnly);
1334  }
1335 
1336 
1337  if (aFilename.substr(aFilename.size()-3) == ".ps") {
1338 #if WT_VERSION > 0x040200
1339  printer.setOutputFormat(WPrinter::PostScriptFormat);
1340 #endif
1341  } else {
1342 #if WT_VERSION > 0x040100
1343  printer.setOutputFormat(WPrinter::PdfFormat);
1344 #endif
1345  }
1346 #if WT_VERSION > 0x040100
1347  printer.setOutputFileName(Wt::WString(aFilename.c_str()));
1348 #endif
1349  // printer.setFullPage ( true);
1350  WPainter paint(&printer);
1351  paint.drawImage (0,0,aImage);
1352  paint.end();
1353  return true;
1354 }
1355 
1356 
1357 
1358 void G4OpenGLWtViewer::G4wheelEvent (Wt::WWheelEvent * event)
1359 {
1360  fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1361  updateWWidget();
1362 }
1363 #endif
1364 
1365  void G4OpenGLWtViewer::G4keyPressEvent (Wt::WKeyEvent * event)
1366 {
1367  if (fHoldKeyEvent)
1368  return;
1369 
1370  fHoldKeyEvent = true;
1371 
1372 
1373  // with no modifiers
1374 #ifdef _A_FINIR_FIXME
1375  updateKeyModifierState(event->modifiers());
1376 #endif
1377  if ((fNoKeyPress)) { // || (event->modifiers() == Wt::KeyboardModifier )) {
1378  if (event->key() == Wt::Key_Down) { // go down
1379  moveScene(0,1,0,false);
1380  }
1381  else if (event->key() == Wt::Key_Up) { // go up
1382  moveScene(0,-1,0,false);
1383  }
1384  if (event->key() == Wt::Key_Left) { // go left
1385  moveScene(-1,0,0,false);
1386  }
1387  else if (event->key() == Wt::Key_Right) { // go right
1388  moveScene(1,0,0,false);
1389  }
1390  if (event->text() == Wt::WString("-") ) { // go backward
1391  moveScene(0,0,1,false);
1392  }
1393  else if (event->text() == Wt::WString("+")) { // go forward
1394  moveScene(0,0,-1,false);
1395  }
1396 
1397  // escaped from full screen
1398  if (event->key() == Wt::Key_Escape) {
1399 #ifdef _A_FINIR_FIXME
1400  toggleFullScreen(false);
1401 #endif
1402  }
1403  }
1404  // several case here : If return is pressed, in every case -> display the movie parameters dialog
1405  // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1406  // If encoder not found-> does nothing.Only display a message in status box
1407  // If all ok-> generate parameter file
1408  // If ok -> put encoder button enabled
1409 
1410 #ifdef _A_FINIR_FIXME
1411  if ( (event->key() == Wt::Key_Enter)){ // end of video
1412  stopVideo();
1413  }
1414  if (event->key() == Wt::Key_Space){ // start/pause of video
1415  startPauseVideo();
1416  }
1417 #endif
1418 
1419  // H : Return Home view
1420  if (event->key() == Wt::Key_H){ // go Home
1421  fDeltaRotation = 1;
1422  fDeltaSceneTranslation = 0.01;
1423  fDeltaDepth = 0.01;
1424  fDeltaZoom = 0.05;
1425  fDeltaMove = 0.05;
1426 
1427  fVP.SetZoomFactor(1.);
1428  fVP.SetUpVector(G4Vector3D (0., 1., 0.));
1429  fVP.SetViewAndLights (G4Vector3D (0., 0., 1.));
1430 
1431  updateWWidget();
1432  }
1433 
1434  // Shift Modifier
1435  if (fShiftKeyPress) {
1436  if (event->key() == Wt::Key_Down) { // rotate phi
1437  rotateWtScene(0,-fDeltaRotation);
1438  }
1439  else if (event->key() == Wt::Key_Up) { // rotate phi
1440  rotateWtScene(0,fDeltaRotation);
1441  }
1442  if (event->key() == Wt::Key_Left) { // rotate theta
1443  rotateWtScene(fDeltaRotation,0);
1444  }
1445  else if (event->key() == Wt::Key_Right) { // rotate theta
1446  rotateWtScene(-fDeltaRotation,0);
1447  }
1448 
1449  // Alt Modifier
1450  }
1451  if ((fAltKeyPress)) {
1452  if (event->key() == Wt::Key_Down) { // rotate phi
1453  rotateWtSceneToggle(0,-fDeltaRotation);
1454  }
1455  else if (event->key() == Wt::Key_Up) { // rotate phi
1456  rotateWtSceneToggle(0,fDeltaRotation);
1457  }
1458  if (event->key() == Wt::Key_Left) { // rotate theta
1459  rotateWtSceneToggle(fDeltaRotation,0);
1460  }
1461  else if (event->key() == Wt::Key_Right) { // rotate theta
1462  rotateWtSceneToggle(-fDeltaRotation,0);
1463  }
1464 
1465  // Rotatio +/-
1466  if (event->text() == Wt::WString("+")) {
1467  fDeltaRotation = fDeltaRotation/0.7;
1468  G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
1469  }
1470  else if (event->text() == Wt::WString("-")) {
1471  fDeltaRotation = fDeltaRotation*0.7;
1472  G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
1473  }
1474 
1475  // Control Modifier OR Command on MAC
1476  }
1477  if ((fControlKeyPress)) {
1478  if (event->text() == Wt::WString("+")) {
1479  fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1480  updateWWidget();
1481  }
1482  else if (event->text() == Wt::WString("-")) {
1483  fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1484  updateWWidget();
1485  }
1486  }
1487 
1488  fHoldKeyEvent = false;
1489 }
1490 
1491 
1492 #ifdef _A_FINIR_FIXME
1493 void G4OpenGLWtViewer::updateKeyModifierState(Wt::KeyboardModifiers modifier) {
1494  // Check Wt Versions for META Keys
1495 
1496  fNoKeyPress = true;
1497  fAltKeyPress = false;
1498  fShiftKeyPress = false;
1499  fControlKeyPress = false;
1500 
1501  if (modifier & Wt::AltModifier ) {
1502  fAltKeyPress = true;
1503  fNoKeyPress = false;
1504  }
1505  if (modifier & Wt::ShiftModifier ) {
1506  fShiftKeyPress = true;
1507  fNoKeyPress = false;
1508  }
1509  if (modifier & Wt::ControlModifier ) {
1510  fControlKeyPress = true;
1511  fNoKeyPress = false;
1512  }
1513 }
1514 
1517 void G4OpenGLWtViewer::stopVideo() {
1518 
1519  // if encoder parameter is wrong, display parameters dialog and return
1520  if (!fMovieParametersDialog) {
1521  showMovieParametersDialog();
1522  }
1523  setRecordingStatus(STOP);
1524 
1525  if (fRecordFrameNumber >0) {
1526  // check parameters if they were modified (Re APPLY them...)
1527  if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1528  setRecordingStatus(BAD_ENCODER);
1529  } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1530  setRecordingStatus(BAD_OUTPUT);
1531  }
1532  } else {
1533  resetRecording();
1534  setRecordingInfos("No frame to encode.");
1535  }
1536 }
1537 
1540 void G4OpenGLWtViewer::saveVideo() {
1541 
1542  // if encoder parameter is wrong, display parameters dialog and return
1543  if (!fMovieParametersDialog) {
1544  showMovieParametersDialog();
1545  }
1546 
1547  fMovieParametersDialog->checkEncoderSwParameters();
1548  fMovieParametersDialog->checkSaveFileNameParameters();
1549 
1550  if (fRecordingStep == STOP) {
1551  setRecordingStatus(SAVE);
1552  generateMpegEncoderParameters();
1553  encodeVideo();
1554  }
1555 }
1556 
1557 
1560 void G4OpenGLWtViewer::startPauseVideo() {
1561 
1562  // first time, if temp parameter is wrong, display parameters dialog and return
1563 
1564  if (( fRecordingStep == WAIT)) {
1565  if ( fRecordFrameNumber == 0) {
1566  if (getTempFolderPath() == "") { // BAD_OUTPUT
1567  showMovieParametersDialog();
1568  setRecordingInfos("You should specified the temp folder in order to make movie");
1569  return;
1570  } else {
1571  // remove temp folder if it was create
1572  Wt::WString tmp = removeTempFolder();
1573  if (tmp !="") {
1574  setRecordingInfos(tmp);
1575  return;
1576  }
1577  tmp = createTempFolder();
1578  if (tmp != "") {
1579  setRecordingInfos("Can't create temp folder."+tmp);
1580  return;
1581  }
1582  }
1583  }
1584  }
1585  if ((fRecordingStep == WAIT)) {
1586  setRecordingStatus(START);
1587  } else if (fRecordingStep == START) {
1588  setRecordingStatus(PAUSE);
1589  } else if (fRecordingStep == PAUSE) {
1590  setRecordingStatus(CONTINUE);
1591  } else if (fRecordingStep == CONTINUE) {
1592  setRecordingStatus(PAUSE);
1593  }
1594 }
1595 
1596 void G4OpenGLWtViewer::setRecordingStatus(RECORDING_STEP step) {
1597 
1598  fRecordingStep = step;
1599  displayRecordingStatus();
1600 }
1601 
1602 
1603 void G4OpenGLWtViewer::displayRecordingStatus() {
1604 
1605  Wt::WString txtStatus = "";
1606  if (fRecordingStep == WAIT) {
1607  txtStatus = "Waiting to start...";
1608  fRecordFrameNumber = 0; // reset the frame number
1609  } else if (fRecordingStep == START) {
1610  txtStatus = "Start Recording...";
1611  } else if (fRecordingStep == PAUSE) {
1612  txtStatus = "Pause Recording...";
1613  } else if (fRecordingStep == CONTINUE) {
1614  txtStatus = "Continue Recording...";
1615  } else if (fRecordingStep == STOP) {
1616  txtStatus = "Stop Recording...";
1617  } else if (fRecordingStep == READY_TO_ENCODE) {
1618  txtStatus = "Ready to Encode...";
1619  } else if (fRecordingStep == ENCODING) {
1620  txtStatus = "Encoding...";
1621  } else if (fRecordingStep == FAILED) {
1622  txtStatus = "Failed to encode...";
1623  } else if ((fRecordingStep == BAD_ENCODER)
1624  || (fRecordingStep == BAD_OUTPUT)
1625  || (fRecordingStep == BAD_TMP)) {
1626  txtStatus = "Correct above errors first";
1627  } else if (fRecordingStep == SUCCESS) {
1628  txtStatus = "File encoded successfully";
1629  } else {
1630  }
1631 
1632  if (fMovieParametersDialog) {
1633  fMovieParametersDialog->setRecordingStatus(txtStatus);
1634  } else {
1635  G4cout << txtStatus.toUTF8().c_str() << G4endl;
1636  }
1637  setRecordingInfos("");
1638 }
1639 
1640 
1641 void G4OpenGLWtViewer::setRecordingInfos(Wt::WString txt) {
1642  if (fMovieParametersDialog) {
1643  fMovieParametersDialog->setRecordingInfos(txt);
1644  } else {
1645  G4cout << txt.toUTF8().c_str() << G4endl;
1646  }
1647 }
1648 
1651 void G4OpenGLWtViewer::initMovieParameters() {
1652  //init encoder
1653 
1654  //look for encoderPath
1655  fProcess = new WProcess();
1656 
1657  WObject ::connect(fProcess,SIGNAL(finished ( int)),
1658  this,SLOT(processLookForFinished()));
1659  fProcess->setReadChannelMode(WProcess::MergedChannels);
1660  fProcess->start ("which mpeg_encode");
1661 
1662 }
1663 
1666 Wt::WString G4OpenGLWtViewer::getEncoderPath() {
1667  return fEncoderPath;
1668 }
1669 
1670 
1675 Wt::WString G4OpenGLWtViewer::setEncoderPath(Wt::WString path) {
1676  if (path == "") {
1677  return "File does not exist";
1678  }
1679 
1680  path = WDir::cleanPath(path);
1681  WFileInfo *f = new WFileInfo(path);
1682  if (!f->exists()) {
1683  return "File does not exist";
1684  } else if (f->isDir()) {
1685  return "This is a directory";
1686  } else if (!f->isExecutable()) {
1687  return "File exist but is not executable";
1688  } else if (!f->isFile()) {
1689  return "This is not a file";
1690  }
1691  fEncoderPath = path;
1692 
1693  if ((fRecordingStep == BAD_ENCODER)) {
1694  setRecordingStatus(STOP);
1695  }
1696  return "";
1697 }
1698 
1699 
1700 bool G4OpenGLWtViewer::isRecording(){
1701  if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
1702  return true;
1703  }
1704  return false;
1705 }
1706 
1707 bool G4OpenGLWtViewer::isPaused(){
1708  if (fRecordingStep == PAUSE) {
1709  return true;
1710  }
1711  return false;
1712 }
1713 
1714 bool G4OpenGLWtViewer::isEncoding(){
1715  if (fRecordingStep == ENCODING) {
1716  return true;
1717  }
1718  return false;
1719 }
1720 
1721 bool G4OpenGLWtViewer::isWaiting(){
1722  if (fRecordingStep == WAIT) {
1723  return true;
1724  }
1725  return false;
1726 }
1727 
1728 bool G4OpenGLWtViewer::isStopped(){
1729  if (fRecordingStep == STOP) {
1730  return true;
1731  }
1732  return false;
1733 }
1734 
1735 bool G4OpenGLWtViewer::isFailed(){
1736  if (fRecordingStep == FAILED) {
1737  return true;
1738  }
1739  return false;
1740 }
1741 
1742 bool G4OpenGLWtViewer::isSuccess(){
1743  if (fRecordingStep == SUCCESS) {
1744  return true;
1745  }
1746  return false;
1747 }
1748 
1749 bool G4OpenGLWtViewer::isBadEncoder(){
1750  if (fRecordingStep == BAD_ENCODER) {
1751  return true;
1752  }
1753  return false;
1754 }
1755 bool G4OpenGLWtViewer::isBadTmp(){
1756  if (fRecordingStep == BAD_TMP) {
1757  return true;
1758  }
1759  return false;
1760 }
1761 bool G4OpenGLWtViewer::isBadOutput(){
1762  if (fRecordingStep == BAD_OUTPUT) {
1763  return true;
1764  }
1765  return false;
1766 }
1767 
1768 void G4OpenGLWtViewer::setBadEncoder(){
1769  fRecordingStep = BAD_ENCODER;
1770  displayRecordingStatus();
1771 }
1772 void G4OpenGLWtViewer::setBadTmp(){
1773  fRecordingStep = BAD_TMP;
1774  displayRecordingStatus();
1775 }
1776 void G4OpenGLWtViewer::setBadOutput(){
1777  fRecordingStep = BAD_OUTPUT;
1778  displayRecordingStatus();
1779 }
1780 
1781 void G4OpenGLWtViewer::setWaiting(){
1782  fRecordingStep = WAIT;
1783  displayRecordingStatus();
1784 }
1785 
1786 
1787 bool G4OpenGLWtViewer::isReadyToEncode(){
1788  if (fRecordingStep == READY_TO_ENCODE) {
1789  return true;
1790  }
1791  return false;
1792 }
1793 
1794 void G4OpenGLWtViewer::resetRecording() {
1795  setRecordingStatus(WAIT);
1796 }
1797 
1802 Wt::WString G4OpenGLWtViewer::setTempFolderPath(Wt::WString path) {
1803 
1804  if (path == "") {
1805  return "Path does not exist";
1806  }
1807  path = WDir::cleanPath(path);
1808  WFileInfo *d = new WFileInfo(path);
1809  if (!d->exists()) {
1810  return "Path does not exist";
1811  } else if (!d->isDir()) {
1812  return "This is not a directory";
1813  } else if (!d->isReadable()) {
1814  return path +" is read protected";
1815  } else if (!d->isWritable()) {
1816  return path +" is write protected";
1817  }
1818 
1819  if ((fRecordingStep == BAD_TMP)) {
1820  setRecordingStatus(WAIT);
1821  }
1822  fTempFolderPath = path;
1823  return "";
1824 }
1825 
1828 Wt::WString G4OpenGLWtViewer::getTempFolderPath() {
1829  return fTempFolderPath;
1830 }
1831 
1836 Wt::WString G4OpenGLWtViewer::setSaveFileName(Wt::WString path) {
1837 
1838  if (path == "") {
1839  return "Path does not exist";
1840  }
1841 
1842  WFileInfo *file = new WFileInfo(path);
1843  WDir dir = file->dir();
1844  path = WDir::cleanPath(path);
1845  if (file->exists()) {
1846  return "File already exist, please choose a new one";
1847  } else if (!dir.exists()) {
1848  return "Dir does not exist";
1849  } else if (!dir.isReadable()) {
1850  return path +" is read protected";
1851  }
1852 
1853  if ((fRecordingStep == BAD_OUTPUT)) {
1854  setRecordingStatus(STOP);
1855  }
1856  fSaveFileName = path;
1857  return "";
1858 }
1859 
1862 Wt::WString G4OpenGLWtViewer::getSaveFileName() {
1863  return fSaveFileName ;
1864 }
1865 
1870 Wt::WString G4OpenGLWtViewer::createTempFolder() {
1871  fMovieTempFolderPath = "";
1872  //check
1873  Wt::WString tmp = setTempFolderPath(fTempFolderPath);
1874  if (tmp != "") {
1875  return tmp;
1876  }
1877  Wt::WString sep = Wt::WString(WDir::separator());
1878  Wt::WString path = sep+"WtMovie_"+WDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
1879  WDir *d = new WDir(WDir::cleanPath(fTempFolderPath));
1880  // check if it is already present
1881  if (d->exists(path)) {
1882  return "Folder "+path+" already exists.Please remove it first";
1883  }
1884  if (d->mkdir(fTempFolderPath+path)) {
1885  fMovieTempFolderPath = fTempFolderPath+path;
1886  return "";
1887  } else {
1888  return "Can't create "+fTempFolderPath+path;
1889  }
1890  return "-";
1891 }
1892 
1895 Wt::WString G4OpenGLWtViewer::removeTempFolder() {
1896  // remove files in Wt_temp folder
1897  if (fMovieTempFolderPath == "") {
1898  return "";
1899  }
1900  WDir *d = new WDir(WDir::cleanPath(fMovieTempFolderPath));
1901  if (!d->exists()) {
1902  return ""; // already remove
1903  }
1904 
1905  d->setFilter( WDir::Files );
1906  Wt::WStringList subDirList = d->entryList();
1907  int res = true;
1908  Wt::WString error = "";
1909  for (Wt::WStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
1910  const Wt::WString currentFile = *it;
1911  if (!d->remove(currentFile)) {
1912  res = false;
1913  Wt::WString file = fMovieTempFolderPath+currentFile;
1914  error +="Removing file failed : "+file;
1915  } else {
1916  }
1917  }
1918  if (res) {
1919  if (d->rmdir(fMovieTempFolderPath)) {
1920  fMovieTempFolderPath = "";
1921  return "";
1922  } else {
1923  return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
1924  }
1925 
1926  }
1927  return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
1928 }
1929 
1930 
1931 
1932 bool G4OpenGLWtViewer::hasPendingEvents () {
1933 #ifdef _A_FINIR_FIXME
1934  return ((WApplication*)G4Wt::getInstance ())->hasPendingEvents ();
1935 #endif
1936  return false;
1937 }
1938 
1939 bool G4OpenGLWtViewer::generateMpegEncoderParameters () {
1940 
1941  // save the parameter file
1942  FILE* fp;
1943  fp = fopen (Wt::WString(fMovieTempFolderPath+fParameterFileName).toUTF8().c_str(), "w");
1944 
1945  if (fp == NULL) {
1946  setRecordingInfos("Generation of parameter file failed");
1947  return false;
1948  }
1949 
1950  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
1951  fprintf (fp,"#\n");
1952  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
1953  fprintf (fp,"# the copy\n");
1954  fprintf (fp,"#\n");
1955  fprintf (fp,"#\n");
1956  fprintf (fp,"# any line beginning with '#' is a comment\n");
1957  fprintf (fp,"#\n");
1958  fprintf (fp,"# no line should be longer than 255 characters\n");
1959  fprintf (fp,"#\n");
1960  fprintf (fp,"#\n");
1961  fprintf (fp,"# general format of each line is:\n");
1962  fprintf (fp,"# \n");
1963  fprintf (fp,"#\n");
1964  fprintf (fp,"# lines can generally be in any order\n");
1965  fprintf (fp,"#\n");
1966  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
1967  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
1968  fprintf (fp,"#\n");
1969  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
1970  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
1971  fprintf (fp,"# the INPUT parameter.\n");
1972  fprintf (fp,"#\n");
1973  fprintf (fp,"# MUST be in UPPER CASE\n");
1974  fprintf (fp,"#\n");
1975  fprintf (fp,"\n");
1976  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
1977  fprintf (fp,"# for more info.\n");
1978  fprintf (fp,"\n");
1979  fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
1980  fprintf (fp,"OUTPUT %s\n",getSaveFileName().toUTF8().c_str());
1981  fprintf (fp,"\n");
1982  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
1983  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
1984  fprintf (fp,"#\n");
1985  fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
1986  fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
1987  fprintf (fp,"# (must be upper case)\n");
1988  fprintf (fp,"#\n");
1989  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
1990  fprintf (fp,"\n");
1991  fprintf (fp,"#\n");
1992  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
1993  fprintf (fp,"# YUV_SIZE widthxheight\n");
1994  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
1995  fprintf (fp,"# on just one machine\n");
1996  fprintf (fp,"#\n");
1997  fprintf (fp,"YUV_SIZE 352x240\n");
1998  fprintf (fp,"\n");
1999  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2000  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2001  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2002  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2003  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2004  fprintf (fp,"# to specify the file order.\n");
2005  fprintf (fp,"\n");
2006  fprintf (fp,"INPUT_FORMAT UCB\n");
2007  fprintf (fp,"\n");
2008  fprintf (fp,"# the conversion statement\n");
2009  fprintf (fp,"#\n");
2010  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2011  fprintf (fp,"#\n");
2012  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2013  fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2014  fprintf (fp,"#\n");
2015  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2016  fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2017  fprintf (fp,"#\n");
2018  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2019  fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2020  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2021  fprintf (fp,"#\n");
2022  fprintf (fp,"INPUT_CONVERT * \n");
2023  fprintf (fp,"\n");
2024  fprintf (fp,"# number of frames in a GOP.\n");
2025  fprintf (fp,"#\n");
2026  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2027  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2028  fprintf (fp,"#\n");
2029  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2030  fprintf (fp,"#\n");
2031  fprintf (fp,"GOP_SIZE 16\n");
2032  fprintf (fp,"\n");
2033  fprintf (fp,"# number of slices in a frame\n");
2034  fprintf (fp,"#\n");
2035  fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2036  fprintf (fp,"# (which is the height divided by 16)\n");
2037  fprintf (fp,"#\n");
2038  fprintf (fp,"SLICES_PER_FRAME 1\n");
2039  fprintf (fp,"\n");
2040  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2041  fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toUTF8().c_str());
2042  fprintf (fp,"\n");
2043  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2044  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2045  fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2046  fprintf (fp,"INPUT\n");
2047  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2048  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2049  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2050  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2051  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2052  fprintf (fp,"# if you do, too bad!!!\n");
2053  fprintf (fp,"#\n");
2054  fprintf (fp,"#\n");
2055  fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2056  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2057  fprintf (fp,"# of files\n");
2058  fprintf (fp,"END_INPUT\n");
2059  fprintf (fp,"\n");
2060  fprintf (fp,"\n");
2061  fprintf (fp,"\n");
2062  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2063  fprintf (fp,"\n");
2064  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2065  fprintf (fp,"# Should be FULL for computer generated images\n");
2066  fprintf (fp,"PIXEL FULL\n");
2067  fprintf (fp,"\n");
2068  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2069  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2070  fprintf (fp,"RANGE 10\n");
2071  fprintf (fp,"\n");
2072  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2073  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2074  fprintf (fp,"\n");
2075  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2076  fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2077  fprintf (fp,"\n");
2078  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2079  fprintf (fp,"#\n");
2080  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2081  fprintf (fp,"#\n");
2082  fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2083  fprintf (fp,"\n");
2084  fprintf (fp,"#\n");
2085  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2086  fprintf (fp,"# (values must be between 1 and 31)\n");
2087  fprintf (fp,"# These are the Wscale values for the entire frame in variable bit-rate\n");
2088  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2089  fprintf (fp,"#\n");
2090  fprintf (fp,"\n");
2091  fprintf (fp,"# Wscale (Wuantization scale) affects quality and compression,\n");
2092  fprintf (fp,"# but has very little effect on speed.\n");
2093  fprintf (fp,"\n");
2094  fprintf (fp,"IWSCALE 4\n");
2095  fprintf (fp,"PWSCALE 5\n");
2096  fprintf (fp,"BWSCALE 12\n");
2097  fprintf (fp,"\n");
2098  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2099  fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2100  fprintf (fp,"\n");
2101  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2102  fprintf (fp,"\n");
2103  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2104  fprintf (fp,"#BIT_RATE 1000000\n");
2105  fprintf (fp,"\n");
2106  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2107  fprintf (fp,"BUFFER_SIZE 327680\n");
2108  fprintf (fp,"\n");
2109  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2110  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2111  fprintf (fp,"FRAME_RATE 30\n");
2112  fprintf (fp,"\n");
2113  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2114  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IWTABLE, etc.\n");
2115  fprintf (fp,"\n");
2116  fprintf (fp,"\n");
2117  fclose (fp);
2118 
2119  setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2120  setRecordingStatus(READY_TO_ENCODE);
2121  return true;
2122 }
2123 
2124 void G4OpenGLWtViewer::encodeVideo()
2125 {
2126  if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2127  setRecordingStatus(ENCODING);
2128 
2129  fProcess = new WProcess();
2130  WObject ::connect(fProcess,SIGNAL(finished ( int)),
2131  this,SLOT(processEncodeFinished()));
2132  WObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2133  this,SLOT(processEncodeStdout()));
2134  fProcess->setReadChannelMode(WProcess::MergedChannels);
2135  fProcess->start (fEncoderPath, Wt::WStringList(fMovieTempFolderPath+fParameterFileName));
2136  }
2137 }
2138 
2139 
2140 // FIXME : does not work on Wt3
2141 void G4OpenGLWtViewer::processEncodeStdout()
2142 {
2143  Wt::WString tmp = fProcess->readStdout ().data();
2144  int start = tmp.findRev("ESTIMATED TIME");
2145  tmp = tmp.mid(start,tmp.find("\n",start)-start);
2146  setRecordingInfos(tmp);
2147 }
2148 
2149 
2150 void G4OpenGLWtViewer::processEncodeFinished()
2151 {
2152 
2153  Wt::WString txt = "";
2154  txt = getProcessErrorMsg();
2155  if (txt == "") {
2156  setRecordingStatus(SUCCESS);
2157  } else {
2158  setRecordingStatus(FAILED);
2159  }
2160  // setRecordingInfos(txt+removeTempFolder());
2161 }
2162 
2163 
2164 void G4OpenGLWtViewer::processLookForFinished()
2165  {
2166 
2167  Wt::WString txt = getProcessErrorMsg();
2168  if (txt != "") {
2169  fEncoderPath = "";
2170  } else {
2171  fEncoderPath = Wt::WString(fProcess->readAllStandardOutput ().data()).trimmed();
2172  // if not found, return "not found"
2173  if (fEncoderPath.contains(" ")) {
2174  fEncoderPath = "";
2175  } else if (!fEncoderPath.contains("mpeg_encode")) {
2176  fEncoderPath = "";
2177  }
2178  setEncoderPath(fEncoderPath);
2179  }
2180  // init temp folder
2181  setTempFolderPath(WDir::temp ().absolutePath ());
2182 }
2183 
2184 
2185 Wt::WString G4OpenGLWtViewer::getProcessErrorMsg()
2186 {
2187  Wt::WString txt = "";
2188  if (fProcess->exitCode() != 0) {
2189  switch (fProcess->error()) {
2190  case WProcess::FailedToStart:
2191  txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2192  break;
2193  case WProcess::Crashed:
2194  txt = "The process crashed some time after starting successfully.\n";
2195  break;
2196  case WProcess::Timedout:
2197  txt = "The last waitFor...() function timed out. The state of WProcess is unchanged, and you can try calling waitFor...() again.\n";
2198  break;
2199  case WProcess::WriteError:
2200  txt = "An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.\n";
2201  break;
2202  case WProcess::ReadError:
2203  txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2204  break;
2205  case WProcess::UnknownError:
2206  txt = "An unknown error occurred. This is the default return value of error().\n";
2207  break;
2208  }
2209  }
2210  return txt;
2211 }
2212 #endif
2213 
2214 
2215 //
2216 // Matrix utility functions
2217 //
2218 
2219 /*
2220 function mvTranslate(v) {
2221  multMatrix(Matrix.Translation($V([v[0], v[1], v[2]])).ensure4x4());
2222 }
2223 
2224 
2225 var mvMatrixStack = [];
2226 
2227 function mvPushMatrix(m) {
2228  if (m) {
2229  mvMatrixStack.push(m.dup());
2230  mvMatrix = m.dup();
2231  } else {
2232  mvMatrixStack.push(mvMatrix.dup());
2233  }
2234 }
2235 
2236 function mvPopMatrix() {
2237  if (!mvMatrixStack.length) {
2238  throw("Can't pop from an empty matrix stack.");
2239  }
2240 
2241  mvMatrix = mvMatrixStack.pop();
2242  return mvMatrix;
2243 }
2244 
2245 function mvRotate(angle, v) {
2246  var inRadians = angle * Math.PI / 180.0;
2247 
2248  var m = Matrix.Rotation(inRadians, $V([v[0], v[1], v[2]])).ensure4x4();
2249  multMatrix(m);
2250 }
2251 */
2252 
2253 
2254 
2255 /*
2256 
2257 void MultiLayer::exportToSVG(const Wt::WString& fname)
2258 {
2259  WPicture picture;
2260  WPainter p(&picture);
2261  for (int i=0;i<(int)graphsList->count();i++)
2262  {
2263  Graph *gr=(Graph *)graphsList->at(i);
2264  Plot *myPlot= (Plot *)gr->plotWidget();
2265 
2266  Wt::WPoint pos=gr->pos();
2267 
2268  int width=int(myPlot->frameGeometry().width());
2269  int height=int(myPlot->frameGeometry().height());
2270 
2271  myPlot->print(&p, WRect(pos,WSize(width,height)));
2272  }
2273 
2274  p.end();
2275  picture.save(fname, "svg");
2276 }
2277 */
2278 #endif
2279 
2280 
2281 
2282 
2283  /*
2284 G4UIWt::CommandEnteredCallback
2285 G4UIWt::CommandEnteredCallback 1
2286 G4UIWt::CommandEnteredCallback 2
2287 G4UIWt::CommandEnteredCallback 3
2288 G4UIWt::CommandEnteredCallback 4
2289 G4VisCommandViewerCreate::SetNewValue Before CreateViewer
2290 G4VisManager::CreateViewer Before CreateViewer
2291 G4OpenGLImmediateWt::CreateViewer
2292 G4OpenGLImmediateWt::CreateViewer after Get Pointer
2293 G4OpenGLImmediateWt::CreateViewer uiWt
2294 G4UIWt::AddTabWidget 50 50
2295 G4UIWt::AddTabWidget 4
2296 G4UIWt::AddTabWidget 5
2297 G4UIWt::AddTabWidget 5a
2298 G4UIWt::AddTabWidget 5a2 69882928 69985360
2299 G4UIWt::AddTabWidget 5b
2300 G4UIWt::AddTabWidget 5c
2301 G4UIWt::AddTabWidget 6
2302 G4UIWt::AddTabWidget ADD 50 50 + 23 1880279432---------------------------------------------------
2303 G4UIWt::AddTabWidget 7
2304 G4UIWt::AddTabWidget 8
2305 G4UIWt::AddTabWidget 9
2306 G4UIWt::AddTabWidget END
2307 G4OpenGLViewer:: Creation
2308 G4OpenGLWtViewer::Create
2309 G4OpenGLWtViewer::G4OpenGLWtViewer END
2310 G4OpenGLImmediateWtViewer INIT
2311 G4OpenGLImmediateWt::CreateViewer lastInsert :68536784
2312 G4OpenGLImmediateWt::CreateViewer END
2313 G4VisManager::CreateViewer After 1 CreateViewer
2314 G4VisManager::CreateViewer After 1 CreateViewer
2315 G4VisManager::CreateViewer After 2 CreateViewer
2316 G4VisManager::CreateViewer After 3 CreateViewer
2317 G4VisManager::CreateViewer After 4 CreateViewer
2318 G4OpenGLImmediateWtViewer::Initialise
2319 G4OpenGLWtViewer::CreateMainWindow
2320 G4OpenGLViewer::ResizeWindow 600 600
2321 G4OpenGLViewer::SetWinSize 600 600
2322 G4VisManager::CreateViewer After 5 CreateViewer
2323 G4VisManager::CreateViewer After 5 CreateViewer
2324 G4VisManager::CreateViewer After 6 CreateViewer
2325 G4VisManager::CreateViewer After 7 CreateViewer
2326 G4VisManager::CreateViewer After 8 CreateViewer
2327 G4VisManager::CreateViewer After 9 CreateViewer
2328 G4VisManager::CreateViewer After END CreateViewer
2329 G4VisCommandViewerCreate::SetNewValue After CreateViewer 1
2330 G4VisCommandViewerCreate::SetNewValue After CreateViewer 2
2331 G4VisCommandViewerCreate::SetNewValue After CreateViewer 3
2332 G4OpenGLViewer::SetView
2333 G4OpenGLViewer::ResizeGLView 600 600 0x104857b40
2334 G4OpenGLViewer::ClearView
2335 G4OpenGLViewer::ClearView set Background :0.040000 .4 .9: 1.000000
2336 G4OpenGLViewer::ClearView flush
2337 G4OpenGLImmediateWtViewer DrawView
2338 G4OpenGLImmediateWtViewer updateWWidget
2339 G4OpenGLImmediateWtViewer paintGL vvvvvvvvvvvvvvvvvvvv
2340  G4OpenGLWtViewer paintGL VVVVVVVVVVVVVVVVVVVVVVVVVV
2341  G4OpenGLViewer::SetView
2342  G4OpenGLViewer::ResizeGLView 600 600 0x104857b40
2343  G4OpenGLViewer::ClearView
2344  G4OpenGLViewer::ClearView set Background :0.080000 .4 .9: 0.000000
2345  G4OpenGLViewer::ClearView flush
2346 #0 G4OpenGLViewer::ClearView (this=0x1049f1540) at src/G4OpenGLViewer.cc:195
2347 #1 0x0000000100353e1d in G4OpenGLWtViewer::paintGL (this=0x1049f0e00) at src/G4OpenGLWtViewer.cc:508
2348 #2 0x000000010030e2bd in G4OpenGLImmediateWtViewer::paintGL (this=0x1049f0e00) at src/G4OpenGLImmediateWtViewer.cc:117
2349 #3 0x000000010030e1b9 in G4OpenGLImmediateWtViewer::updateWWidget (this=0x1049f0e00) at src/G4OpenGLImmediateWtViewer.cc:314
2350 #4 0x000000010030e28e in G4OpenGLImmediateWtViewer::DrawView (this=0x1049f0e00) at src/G4OpenGLImmediateWtViewer.cc:206
2351 #5 0x00000001005fed54 in G4VisCommandViewerRefresh::SetNewValue (this=0x104240e30, newValue=@0x1045436f0) at src/G4VisCommandsViewer.cc:1189
2352 #6 0x0000000101612e04 in ~G4String [inlined] () at src/G4UIcommand.cc:211
2353 #7 0x0000000101612e04 in ~G4String [inlined] () at /Users/garnier/Work/geant4/source/global/management/include/G4String.hh:122
2354 #8 0x0000000101612e04 in G4UIcommand::DoIt (this=<value temporarily unavailable, due to optimizations>, parameterList=<value temporarily unavailable, due to optimizations>) at src/G4UIcommand.cc:211
2355 
2356  G4OpenGLWtViewer drawScene vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2357  G4OpenGLWtViewer drawArrays
2358  G4OpenGLWtViewer drawArrays
2359  G4OpenGLWtViewer drawArrays
2360  G4OpenGLWtViewer drawArrays
2361  G4OpenGLWtViewer drawScene Call ComputeView
2362  G4OpenGLWtViewer::ComputeView 600 600 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
2363  G4OpenGLWtViewer drawArrays
2364  G4OpenGLWtViewer::ComputeView NeedKernelVisit
2365  G4OpenGLWtViewer::ComputeView ProcessView
2366  G4VViewer::ProcessView need ? 1
2367  G4VSceneHandler::ProcessScene
2368  G4OpenGLWtViewer::FinishView()
2369  G4VSceneHandler::ProcessScene END
2370  G4VViewer::ProcessView END
2371  G4OpenGLWtViewer::FinishView()
2372  G4OpenGLWtViewer::ComputeView 600 600 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2373  G4OpenGLWtViewer drawScene END Call ComputeView
2374  G4OpenGLWtViewer drawScene END ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2375  G4OpenGLImmediateWtViewer resizeGL
2376  G4OpenGLWtViewer resizeGL 600 600
2377  G4OpenGLWtViewer paintGL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2378 G4OpenGLImmediateWtViewer paintGL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2379 G4OpenGLImmediateWtViewer updateWWidget END
2380 G4OpenGLImmediateWtViewer DrawView END
2381 G4VisCommandViewerCreate::SetNewValue After CreateViewer 4
2382 G4UIWt::CommandEnteredCallback 5
2383 G4UIWt::CommandEnteredCallback 6
2384 G4UIWt::CommandEnteredCallback END
2385 G4UIWt::CommandLineSlot
2386 G4OpenGLWtViewer initializeGL
2387 G4OpenGLWtViewer centerpoint END
2388 G4OpenGLWtViewer initializeGL END
2389 G4OpenGLImmediateWtViewer updateWWidget
2390 G4OpenGLImmediateWtViewer paintGL vvvvvvvvvvvvvvvvvvvv
2391  G4OpenGLWtViewer paintGL VVVVVVVVVVVVVVVVVVVVVVVVVV
2392  G4OpenGLViewer::SetView
2393  G4OpenGLViewer::ResizeGLView 600 600 0x104857b40
2394  G4OpenGLViewer::ClearView
2395  G4OpenGLViewer::ClearView set Background :0.120000 .4 .9: 0.000000
2396  G4OpenGLViewer::ClearView flush
2397 #0 G4OpenGLViewer::ClearView (this=0x1049f1540) at src/G4OpenGLViewer.cc:195
2398 #1 0x0000000100353e1d in G4OpenGLWtViewer::paintGL (this=0x1049f0e00) at src/G4OpenGLWtViewer.cc:508
2399 #2 0x000000010030e2bd in G4OpenGLImmediateWtViewer::paintGL (this=0x1049f0e00) at src/G4OpenGLImmediateWtViewer.cc:117
2400 #3 0x000000010030e1b9 in G4OpenGLImmediateWtViewer::updateWWidget (this=0x1049f0e00) at src/G4OpenGLImmediateWtViewer.cc:314
2401 #4 0x0000000100354e82 in G4OpenGLWtViewer::initializeGL (this=0x1049f0e00) at src/G4OpenGLWtViewer.cc:446
2402 #5 0x000000010283b785 in basic_string [inlined] () at /usr/include/c++/4.2.1/bits/basic_string.h:451
2403 #6 0x000000010283b785 in _Alloc_hider [inlined] () at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WGLWidget.C:2067
2404 #7 0x000000010283b785 in basic_string [inlined] () at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WGLWidget.C:262
2405 #8 0x000000010283b785 in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str () at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WGLWidget.C:130
2406 #9 std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::str () at /usr/include/c++/4.2.1/sstream:572
2407 
2408 
2409  G4OpenGLWtViewer drawScene vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2410  G4OpenGLWtViewer drawArrays
2411  G4OpenGLWtViewer drawArrays
2412  G4OpenGLWtViewer drawArrays
2413  G4OpenGLWtViewer drawArrays
2414  G4OpenGLWtViewer drawScene Call ComputeView
2415  G4OpenGLWtViewer::ComputeView 600 600 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
2416  G4OpenGLWtViewer drawArrays
2417  G4OpenGLWtViewer::ComputeView NeedKernelVisit
2418  G4OpenGLWtViewer::ComputeView ProcessView
2419  G4VViewer::ProcessView need ? 1
2420  G4VSceneHandler::ProcessScene
2421  G4OpenGLWtViewer::FinishView()
2422  G4VSceneHandler::ProcessScene END
2423  G4VViewer::ProcessView END
2424  G4OpenGLWtViewer::FinishView()
2425  G4OpenGLWtViewer::ComputeView 600 600 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2426  G4OpenGLWtViewer drawScene END Call ComputeView
2427  G4OpenGLWtViewer drawScene END ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2428  G4OpenGLImmediateWtViewer resizeGL
2429  G4OpenGLWtViewer resizeGL 600 600
2430  G4OpenGLWtViewer paintGL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2431 G4OpenGLImmediateWtViewer paintGL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2432 G4OpenGLImmediateWtViewer updateWWidget END
2433 G4OpenGLImmediateWtViewer resizeGL
2434 G4OpenGLWtViewer resizeGL 600 600
2435 G4OpenGLImmediateWtViewer paintGL vvvvvvvvvvvvvvvvvvvv
2436  G4OpenGLWtViewer paintGL VVVVVVVVVVVVVVVVVVVVVVVVVV
2437  G4OpenGLViewer::SetView
2438  G4OpenGLViewer::ResizeGLView 600 600 0x104857b40
2439  G4OpenGLViewer::ClearView
2440  G4OpenGLViewer::ClearView set Background :0.160000 .4 .9: 0.000000
2441  G4OpenGLViewer::ClearView flush
2442 #0 G4OpenGLViewer::ClearView (this=0x1049f1540) at src/G4OpenGLViewer.cc:195
2443 #1 0x0000000100353e1d in G4OpenGLWtViewer::paintGL (this=0x1049f0e00) at src/G4OpenGLWtViewer.cc:508
2444 #2 0x000000010030e2bd in G4OpenGLImmediateWtViewer::paintGL (this=0x1049f0e00) at src/G4OpenGLImmediateWtViewer.cc:117
2445 #3 0x000000010283955b in std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::str () at /usr/include/c++/4.2.1/sstream:527
2446 #4 0x000000010283955b in Wt::WGLWidget::updateDom (this=<value temporarily unavailable, due to optimizations>, element=@0x1049e1800, all=true) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WGLWidget.C:531
2447 #5 0x000000010283ba3c in Wt::WGLWidget::createDomElement (this=0x1049f0e00, app=<value temporarily unavailable, due to optimizations>) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WGLWidget.C:473
2448 #6 0x0000000102993cfa in Wt::WWidget::createSDomElement (this=0x1049f0e00, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WWidget.C:326
2449 #7 0x00000001027ebf16 in Wt::WContainerWidget::createDomChildren (this=0x1041c1b50, parent=@0x1049e0c00, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WContainerWidget.C:720
2450 #8 0x00000001027ec5a6 in Wt::WContainerWidget::createDomElement (this=0x1041c1b50, app=0x105021e00, addChildren=true) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WContainerWidget.C:653
2451 #9 0x0000000102993cfa in Wt::WWidget::createSDomElement (this=0x1041c1b50, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WWidget.C:326
2452 #10 0x00000001027ebf16 in Wt::WContainerWidget::createDomChildren (this=0x1041c1cf0, parent=@0x1049f5200, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WContainerWidget.C:720
2453 #11 0x00000001027ec5a6 in Wt::WContainerWidget::createDomElement (this=0x1041c1cf0, app=0x105021e00, addChildren=true) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WContainerWidget.C:653
2454 #12 0x0000000102993cfa in Wt::WWidget::createSDomElement (this=0x1041c1cf0, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WWidget.C:326
2455 #13 0x00000001027eb5a2 in Wt::WContainerWidget::updateDomChildren (this=0x104278560, parent=@0x1049f4600, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WContainerWidget.C:748
2456 #14 0x00000001027ec62d in Wt::WContainerWidget::getDomChanges (this=0x104278560, result=@0x1045449b0, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WContainerWidget.C:632
2457 #15 0x0000000102976c93 in Wt::WWebWidget::getSDomChanges (this=0x104278560, result=@0x1045449b0, app=0x105021e00) at /Users/garnier/Work/Devel/wt-3.2.0/src/Wt/WWebWidget.C:1788
2458 
2459 
2460  G4OpenGLWtViewer drawScene vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2461  G4OpenGLWtViewer drawArrays
2462  G4OpenGLWtViewer drawArrays
2463  G4OpenGLWtViewer drawArrays
2464  G4OpenGLWtViewer drawArrays
2465  G4OpenGLWtViewer drawScene Call ComputeView
2466  G4OpenGLWtViewer::ComputeView 600 600 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
2467  G4OpenGLWtViewer drawArrays
2468  G4OpenGLWtViewer::ComputeView NeedKernelVisit
2469  G4OpenGLWtViewer::ComputeView ProcessView
2470  G4VViewer::ProcessView need ? 1
2471  G4VSceneHandler::ProcessScene
2472  G4OpenGLWtViewer::FinishView()
2473  G4VSceneHandler::ProcessScene END
2474  G4VViewer::ProcessView END
2475  G4OpenGLWtViewer::FinishView()
2476  G4OpenGLWtViewer::ComputeView 600 600 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2477  G4OpenGLWtViewer drawScene END Call ComputeView
2478  G4OpenGLWtViewer drawScene END ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2479  G4OpenGLImmediateWtViewer resizeGL
2480  G4OpenGLWtViewer resizeGL 600 600
2481  G4OpenGLWtViewer paintGL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2482 G4OpenGLImmediateWtViewer paintGL ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2483  */