Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4OpenGLWtViewer.cc
Go to the documentation of this file.
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 // $Id$
28 //
29 //
30 // G4OpenGLWtViewer : Class to provide Wt specific
31 // functionality for OpenGL in GEANT4
32 //
33 // 27/06/2003 : G.Barrand : implementation (at last !).
34 
35 #ifdef G4VIS_BUILD_OPENGLWT_DRIVER
36 
37 #include "G4OpenGLWtViewer.hh"
38 #include "G4VViewer.hh"
39 #include "G4VSceneHandler.hh"
40 #include "G4OpenGLSceneHandler.hh"
41 
42 #include "G4ios.hh"
43 #include "G4VisExtent.hh"
44 #include "G4LogicalVolume.hh"
45 #include "G4VSolid.hh"
46 #include "G4Point3D.hh"
47 #include "G4Normal3D.hh"
48 #include "G4Scene.hh"
49 //#include "G4OpenGLWtExportDialog.hh"
50 //#include "G4OpenGLWtMovieDialog.hh"
51 #include "G4UnitsTable.hh"
52 #include "G4Wt.hh"
53 #include "G4UIWt.hh"
54 #include "G4UImanager.hh"
55 #include "G4UIcommandTree.hh"
56 
57 #include <WT/WHBoxLayout>
58 #include <WT/WApplication>
59 
60 
61 
62 
64 
67 void G4OpenGLWtViewer::SetView (
68 )
69 {
72  G4OpenGLViewer::SetView ();
73 }
74 
75 
76 
77 
79 void G4OpenGLWtViewer::CreateMainWindow (
80  Wt::WGLWidget* glWidget
81  ,Wt::WString name
82 )
83 {
86 #ifdef G4DEBUG_VIS_OGL
87  printf("G4OpenGLWtViewer::CreateMainWindow \n");
88 #endif
89 
90  if(fWindow) return; //Done.
91 
92  fWindow = glWidget ;
93  // fWindow->makeCurrent();
94 
95  //G4Wt* interactorManager = G4Wt::getInstance ();
96 
97  ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY());
98 
99  // FIXME L.Garnier 9/11/09 Has to be check !!!
100  // Wt UI with Wt Vis
101  // Wt UI with X Vis
102  // X UI with Wt Vis
103  // X UI with X Vis
104  // Ne marche pas avec un UIBatch !! (ecran blanc)
105 
106  // return false if G4UIWt was not launch
107 
108  fGLWindow = fWindow;
109  // FIXME:: fGLWindow->resize(getWinWidth(), getWinHeight());
110 
111  if(!fWindow) return;
112 
113 #ifdef _A_FINIR_FIXME
114  if (!fContextMenu)
115  createPopupMenu();
116 #endif
117 
118  // FIXME:: updateWWidget();
119 
120 }
121 
124 // void G4OpenGLWtViewer::dialogClosed() {
125 // // fGLWindow = NULL;
126 // }
127 
129 G4OpenGLWtViewer::G4OpenGLWtViewer (
130  G4OpenGLSceneHandler& scene
131  )
132  :G4VViewer (scene, -1)
133  ,G4OpenGLViewer (scene)
134  ,fWindow(0)
135  ,fRecordFrameNumber(0)
136  //#ifdef _A_FINIR_FIXME ,fContextMenu(0)
137  ,fMouseAction(STYLE1)
138  ,fDeltaRotation(1)
139  ,fDeltaSceneTranslation(0.01)
140  ,fDeltaDepth(0.01)
141  ,fDeltaZoom(0.05)
142  ,fDeltaMove(0.05)
143  ,fHoldKeyEvent(false)
144  ,fHoldMoveEvent(false)
145  ,fHoldRotateEvent(false)
146  ,fAutoMove(false)
147  ,fEncoderPath("")
148  ,fTempFolderPath("")
149  ,fMovieTempFolderPath("")
150  ,fSaveFileName("")
151  ,fParameterFileName("mpeg_encode_parameter_file.par")
152  ,fMovieParametersDialog(NULL)
153  ,fRecordingStep(WAIT)
154  ,fProcess(NULL)
155  ,fNbMaxFramesPerSec(100)
156  ,fNbMaxAnglePerSec(360)
157  ,fLaunchSpinDelay(100)
158  ,fXRot(0)
159  ,fYRot(0)
160  ,fNoKeyPress(true)
161  ,fAltKeyPress(false)
162  ,fControlKeyPress(false)
163  ,fShiftKeyPress(false)
164 {
165 
166  // launch Wt if not
167  G4Wt::getInstance ();
168 
169 #ifdef G4DEBUG_VIS_OGL
170  printf("G4OpenGLWtViewer::Create \n");
171 #endif
172  fLastPos3 = Wt::WPoint(-1,-1);
173  fLastPos2 = Wt::WPoint(-1,-1);
174  fLastPos1 = Wt::WPoint(-1,-1);
175 
176 #ifdef _A_FINIR_FIXME
177  initMovieParameters();
178 #endif
179 
180  fLastEventTime = new Wt::WTime();
181 
182 #ifdef G4DEBUG_VIS_OGL
183  printf("G4OpenGLWtViewer::G4OpenGLWtViewer END\n");
184 #endif
185 }
186 
188 G4OpenGLWtViewer::~G4OpenGLWtViewer (
189 )
190 {
193 #ifdef _A_FINIR_FIXME
194  G4cout <<removeTempFolder().toUTF8().c_str() <<G4endl;
195 #endif
196 }
197 
198 
199 #ifdef _A_FINIR_FIXME
200 
203 void G4OpenGLWtViewer::createPopupMenu() {
204 
205  fContextMenu = new WMenu("All");
206 
207  WMenu *mMouseAction = fContextMenu->addMenu("&Mouse actions");
208 
209  fRotateAction = mMouseAction->addAction("Rotate");
210  fMoveAction = mMouseAction->addAction("Move");
211  fPickAction = mMouseAction->addAction("Pick");
212  WAction *shortcutsAction = mMouseAction->addAction("Show shortcuts");
213 
214  fRotateAction->setCheckable(true);
215  fMoveAction->setCheckable(false);
216  fPickAction->setCheckable(false);
217  shortcutsAction->setCheckable(false);
218 
219  fRotateAction->setChecked(true);
220  fMoveAction->setChecked(false);
221  fPickAction->setChecked(false);
222  shortcutsAction->setChecked(false);
223 
224  WObject ::connect(fRotateAction,
225  SIGNAL(triggered(bool)),
226  this,
227  SLOT(actionMouseRotate()));
228 
229  WObject ::connect(fMoveAction,
230  SIGNAL(triggered(bool)),
231  this,
232  SLOT(actionMouseMove()));
233 
234  WObject ::connect(fPickAction,
235  SIGNAL(triggered(bool)),
236  this,
237  SLOT(actionMousePick()));
238 
239  WObject ::connect(shortcutsAction,
240  SIGNAL(triggered(bool)),
241  this,
242  SLOT(showShortcuts()));
243 
244  // === Style Menu ===
245  WMenu *mStyle = fContextMenu->addMenu("&Style");
246 
247  WMenu *mRepresentation = mStyle->addMenu("&Representation");
248  WMenu *mProjection = mStyle->addMenu("&Projection");
249  WAction *polyhedron = mRepresentation->addAction("Polyhedron");
250  WAction *nurbs = mRepresentation->addAction("NURBS");
251 
252  WAction *ortho = mProjection->addAction("Orthographic");
253  WAction *perspective = mProjection->addAction("Persepective");
254 
255  // INIT mRepresentation
257  style = fVP.GetRepStyle();
258  if (style == G4ViewParameters::polyhedron) {
259  createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),1);
260  } else if (style == G4ViewParameters::nurbs) {
261  createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),2);
262  } else {
263  mRepresentation->clear();
264  }
265 
266  // INIT mProjection
267  if (fVP.GetFieldHalfAngle() == 0) {
268  createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),1);
269  } else {
270  createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),2);
271  }
272 
273  // === Drawing Menu ===
274  WMenu *mDrawing = mStyle->addMenu("&Drawing");
275 
276  fDrawingWireframe = mDrawing->addAction("Wireframe");
277  fDrawingWireframe->setCheckable(true);
278 
279  fDrawingLineRemoval = mDrawing->addAction("Hidden line removal");
280  fDrawingLineRemoval->setCheckable(true);
281 
282  fDrawingSurfaceRemoval = mDrawing->addAction("Hidden Surface removal");
283  fDrawingSurfaceRemoval->setCheckable(true);
284 
285  fDrawingLineSurfaceRemoval = mDrawing->addAction("Hidden line and surface removal");
286  fDrawingLineSurfaceRemoval->setCheckable(true);
287 
288  // INIT Drawing
290  d_style = fVP.GetDrawingStyle();
291 
292  if (d_style == G4ViewParameters::wireframe) {
293  fDrawingWireframe->setChecked(true);
294  } else if (d_style == G4ViewParameters::hlr) {
295  fDrawingLineRemoval->setChecked(true);
296  } else if (d_style == G4ViewParameters::hsr) {
297  fDrawingSurfaceRemoval->setChecked(true);
298  } else if (d_style == G4ViewParameters::hlhsr) {
299  fDrawingLineSurfaceRemoval->setChecked(true);
300  } else {
301  mDrawing->clear();
302  }
303  WObject ::connect(fDrawingWireframe,
304  SIGNAL(triggered(bool)),
305  this,
306  SLOT(actionDrawingWireframe()));
307  WObject ::connect(fDrawingLineRemoval,
308  SIGNAL(triggered(bool)),
309  this,
310  SLOT(actionDrawingLineRemoval()));
311  WObject ::connect(fDrawingSurfaceRemoval,
312  SIGNAL(triggered(bool)),
313  this,
314  SLOT(actionDrawingSurfaceRemoval()));
315  WObject ::connect(fDrawingLineSurfaceRemoval,
316  SIGNAL(triggered(bool)),
317  this,
318  SLOT(actionDrawingLineSurfaceRemoval()));
319 
320  // Background Color
321 
322  WAction *backgroundColorChooser ;
323 
324  // === Action Menu ===
325  backgroundColorChooser = mStyle->addAction("Background color");
326  WObject ::connect(backgroundColorChooser,
327  SIGNAL(triggered()),
328  this,
329  SLOT(actionChangeBackgroundColor()));
330 
331  // Text Color
332 
333  WAction *textColorChooser ;
334  // === Action Menu ===
335  textColorChooser = mStyle->addAction("Text color");
336  WObject ::connect(textColorChooser,
337  SIGNAL(triggered()),
338  this,
339  SLOT(actionChangeTextColor()));
340 
341  // Default Color
342 
343  WAction *defaultColorChooser ;
344  // === Action Menu ===
345  defaultColorChooser = mStyle->addAction("Default color");
346  WObject ::connect(defaultColorChooser,
347  SIGNAL(triggered()),
348  this,
349  SLOT(actionChangeDefaultColor()));
350 
351 
352  // === Action Menu ===
353  WMenu *mActions = fContextMenu->addMenu("&Actions");
354  WAction *createEPS = mActions->addAction("Save as ...");
355  WObject ::connect(createEPS,
356  SIGNAL(triggered()),
357  this,
358  SLOT(actionSaveImage()));
359 
360  // === Action Menu ===
361  WAction *movieParameters = mActions->addAction("Movie parameters...");
362  WObject ::connect(movieParameters,
363  SIGNAL(triggered()),
364  this,
365  SLOT(actionMovieParameters()));
366 
367 
368 
369 
370  // === Special Menu ===
371  WMenu *mSpecial = fContextMenu->addMenu("S&pecial");
372  WMenu *mTransparency = mSpecial->addMenu("Transparency");
373  WAction *transparencyOn = mTransparency->addAction("On");
374  WAction *transparencyOff = mTransparency->addAction("Off");
375 
376  if (transparency_enabled == false) {
377  createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),2);
378  } else if (transparency_enabled == true) {
379  createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),1);
380  } else {
381  mSpecial->clear();
382  }
383 
384 
385  WMenu *mAntialiasing = mSpecial->addMenu("Antialiasing");
386  WAction *antialiasingOn = mAntialiasing->addAction("On");
387  WAction *antialiasingOff = mAntialiasing->addAction("Off");
388 
389  if (antialiasing_enabled == false) {
390  createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),2);
391  } else if (antialiasing_enabled == true) {
392  createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),1);
393  } else {
394  mAntialiasing->clear();
395  }
396 
397  WMenu *mHaloing = mSpecial->addMenu("Haloing");
398  WAction *haloingOn = mHaloing->addAction("On");
399  WAction *haloingOff = mHaloing->addAction("Off");
400 
401  if (haloing_enabled == false) {
402  createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),2);
403  } else if (haloing_enabled == true) {
404  createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),1);
405  } else {
406  mHaloing->clear();
407  }
408 
409  WMenu *mAux = mSpecial->addMenu("Auxiliary edges");
410  WAction *auxOn = mAux->addAction("On");
411  WAction *auxOff = mAux->addAction("Off");
412  if (!fVP.IsAuxEdgeVisible()) {
413  createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),1);
414  } else {
415  createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),2);
416  }
417 
418 
419 
420  WMenu *mFullScreen = mSpecial->addMenu("&Full screen");
421  fFullScreenOn = mFullScreen->addAction("On");
422  fFullScreenOff = mFullScreen->addAction("Off");
423  createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(bool)),2);
424 
425 }
426 
427 
428 void G4OpenGLWtViewer::G4manageContextMenuEvent(WContextMenuEvent *e)
429 {
430  if (!fGLWindow) {
431  G4cerr << "Visualization window not defined, please choose one before" << G4endl;
432  } else {
433 
434  if (!fContextMenu)
435  createPopupMenu();
436 
437  // launch menu
438  if ( fContextMenu ) {
439  fContextMenu->exec( e->globalPos() );
440  // delete fContextMenu;
441  }
442  }
443  e->accept();
444 }
445 
446 
455 void G4OpenGLWtViewer::createRadioAction(WAction *action1,WAction *action2, const std::string& method,unsigned int nCheck) {
456 
457  action1->setCheckable(true);
458  action2->setCheckable(true);
459 
460  if (nCheck ==1)
461  action1->setChecked (true);
462  else
463  action2->setChecked (true);
464 
465  WObject ::connect(action1, SIGNAL(triggered(bool)),action2, SLOT(toggle()));
466  WObject ::connect(action2, SIGNAL(triggered(bool)),action1, SLOT(toggle()));
467 
468  WObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
469 
470 }
471 
475 void G4OpenGLWtViewer::actionMouseRotate() {
476  emit toggleMouseAction(STYLE1);
477 }
478 
479 
483 void G4OpenGLWtViewer::actionMouseMove() {
484  emit toggleMouseAction(STYLE2);
485 }
486 
487 
491 void G4OpenGLWtViewer::actionMousePick() {
492  emit toggleMouseAction(STYLE3);
493 }
494 
495 
499 void G4OpenGLWtViewer::actionDrawingWireframe() {
500  emit toggleDrawingAction(1);
501 }
502 
506 void G4OpenGLWtViewer::actionDrawingLineRemoval() {
507  emit toggleDrawingAction(2);
508 }
509 
513 void G4OpenGLWtViewer::actionDrawingSurfaceRemoval() {
514  emit toggleDrawingAction(3);
515 }
516 
520 void G4OpenGLWtViewer::actionDrawingLineSurfaceRemoval() {
521  emit toggleDrawingAction(4);
522 }
523 
524 
529 void G4OpenGLWtViewer::toggleMouseAction(mouseActions aAction) {
530 
531  if ((aAction == STYLE1) || //initialize all
532  (aAction == STYLE2) ||
533  (aAction == STYLE3)) {
534  fRotateAction->setChecked (false);
535  fMoveAction->setChecked (false);
536  fPickAction->setChecked (false);
537  fVP.SetPicking(false);
538  fMouseAction = aAction;
539  }
540  // rotate
541  if (aAction == STYLE1) { // rotate
542  showShortcuts();
543  fRotateAction->setChecked (true);
544  } else if (aAction == STYLE2) { //move
545  fMoveAction->setChecked (true);
546  } else if (aAction == STYLE3) { //pick
547  fPickAction->setChecked (true);
548  fVP.SetPicking(true);
549  }
550 }
551 
552 #endif
553 
556 void G4OpenGLWtViewer::showShortcuts() {
557  G4cout << "========= Mouse Shortcuts =========" << G4endl;
558  if (fMouseAction == STYLE1) { // rotate
559  G4cout << "Click and move mouse to rotate volume " << G4endl;
560  G4cout << "ALT + Click and move mouse to rotate volume (View Direction)" << G4endl;
561  G4cout << "CTRL + Click and zoom mouse to zoom in/out" << G4endl;
562  G4cout << "SHIFT + Click and zoommove camera point of view" << G4endl;
563  } else if (fMouseAction == STYLE2) { //move
564  G4cout << "Move camera point of view with mouse" << G4endl;
565  } else if (fMouseAction == STYLE3) { //pick
566  G4cout << "Click and pick " << G4endl;
567  }
568  G4cout << "========= Move Shortcuts =========" << G4endl;
569  G4cout << "Press left/right arrows to move volume left/right" << G4endl;
570  G4cout << "Press up/down arrows to move volume up/down" << G4endl;
571  G4cout << "Press '+'/'-' to move volume toward/forward" << G4endl;
572  G4cout << G4endl;
573  G4cout << "========= Rotation (Theta/Phi) Shortcuts =========" << G4endl;
574  G4cout << "Press SHIFT + left/right arrows to rotate volume left/right" << G4endl;
575  G4cout << "Press SHIFT + up/down arrows to rotate volume up/down" << G4endl;
576  G4cout << G4endl;
577  G4cout << "========= Rotation (View Direction) Shortcuts =========" << G4endl;
578  G4cout << "Press ALT + left/right to rotate volume around vertical direction" << G4endl;
579  G4cout << "Press ALT + up/down to rotate volume around horizontal direction" << G4endl;
580  G4cout << G4endl;
581  G4cout << "========= Zoom View =========" << G4endl;
582  G4cout << "Press CTRL + '+'/'-' to zoom into volume" << G4endl;
583  G4cout << G4endl;
584  G4cout << "========= Misc =========" << G4endl;
585  G4cout << "Press ALT +/- to slow/speed rotation/move" << G4endl;
586  G4cout << "Press H to reset view" << G4endl;
587  G4cout << "Press Esc to exit FullScreen" << G4endl;
588  G4cout << G4endl;
589  G4cout << "========= Video =========" << G4endl;
590  G4cout << "In video mode : " << G4endl;
591  G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
592  G4cout << " Press RETURN to Stop video recording " << G4endl;
593  G4cout << G4endl;
594 }
595 
596 
597 
598 #ifdef _A_FINIR_FIXME
599 
610 void G4OpenGLWtViewer::toggleDrawingAction(int aAction) {
611 
613 
614 
615  // initialize
616  if ((aAction >0) && (aAction <5)) {
617  fDrawingWireframe->setChecked (false);
618  fDrawingLineRemoval->setChecked (false);
619  fDrawingSurfaceRemoval->setChecked (false);
620  fDrawingLineSurfaceRemoval->setChecked (false);
621  }
622  if (aAction ==1) {
623  fDrawingWireframe->setChecked (true);
624 
625  d_style = G4ViewParameters::wireframe;
626 
627  } else if (aAction ==2) {
628  fDrawingLineRemoval->setChecked (true);
629 
630  d_style = G4ViewParameters::hlr;
631 
632  } else if (aAction ==3) {
633  fDrawingSurfaceRemoval->setChecked (true);
634 
635  d_style = G4ViewParameters::hsr;
636 
637  } else if (aAction ==4) {
638  fDrawingLineSurfaceRemoval->setChecked (true);
639  d_style = G4ViewParameters::hlhsr;
640  }
641  fVP.SetDrawingStyle(d_style);
642 
643  updateWWidget();
644 }
645 
646 
657 void G4OpenGLWtViewer::toggleRepresentation(bool check) {
658 
660  if (check == 1) {
662  } else {
663  style = G4ViewParameters::nurbs;
664  }
665  fVP.SetRepStyle (style);
666 
667  updateWWidget();
668 }
669 
680 void G4OpenGLWtViewer::toggleProjection(bool check) {
681 
682  if (check == 1) {
683  G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection o");
684  } else {
685  G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection p");
686  }
687  updateWWidget();
688 }
689 
690 
695 void G4OpenGLWtViewer::toggleTransparency(bool check) {
696 
697  if (check) {
698  transparency_enabled = false;
699  } else {
700  transparency_enabled = true;
701  }
702  SetNeedKernelVisit (true);
703  updateWWidget();
704 }
705 
710 void G4OpenGLWtViewer::toggleAntialiasing(bool check) {
711 
712  if (!check) {
713  antialiasing_enabled = false;
714  glDisable (GL_LINE_SMOOTH);
715  glDisable (GL_POLYGON_SMOOTH);
716  } else {
717  antialiasing_enabled = true;
718  glEnable (GL_LINE_SMOOTH);
719  glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
720  glEnable (GL_POLYGON_SMOOTH);
721  glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
722  }
723 
724  updateWWidget();
725 }
726 
731 //FIXME : I SEE NOTHING...
732 void G4OpenGLWtViewer::toggleHaloing(bool check) {
733  if (check) {
734  haloing_enabled = false;
735  } else {
736  haloing_enabled = true;
737  }
738 
739  updateWWidget();
740 
741 }
742 
747 void G4OpenGLWtViewer::toggleAux(bool check) {
748  if (check) {
749  fVP.SetAuxEdgeVisible(true);
750  } else {
751  fVP.SetAuxEdgeVisible(false);
752  }
753  SetNeedKernelVisit (true);
754  updateWWidget();
755 }
756 
760 void G4OpenGLWtViewer::toggleFullScreen(bool check) {
761  if (check != fGLWindow->isFullScreen()) { //toggle
762  fGLWindow->setWindowState(fGLWindow->windowState() ^ Wt::WindowFullScreen);
763  G4cerr << "This version of Wt could not do fullScreen. Resizing the widget is the only solution available." << G4endl;
764  }
765 }
766 #endif
767 
768 #ifdef _A_FINIR_FIXME
769 void G4OpenGLWtViewer::savePPMToTemp() {
770  if (fMovieTempFolderPath == "") {
771  return;
772  }
773  Wt::WString fileName ="Test"+Wt::WString::number(fRecordFrameNumber)+".ppm";
774  Wt::WString filePath =fMovieTempFolderPath+fileName;
775 
776  WImage image;
777  image = fWindow->grabFrameBuffer();
778  bool res = false;
779 
780  res = image.save(filePath,0);
781  if (res == false) {
782  resetRecording();
783  setRecordingInfos("Can't save tmp file "+filePath);
784  return;
785  }
786 
787  setRecordingInfos("File "+fileName+" saved");
788  fRecordFrameNumber++;
789 }
790 
791 
792 
793 void G4OpenGLWtViewer::actionSaveImage() {
794  Wt::WString filters;
795  WList<WByteArray> formats = WImageWriter::supportedImageFormats ();
796  for (int i = 0; i < formats.size(); ++i) {
797  filters +=formats.at(i) + ";;";
798  }
799  filters += "eps;;";
800  filters += "ps;;";
801  filters += "pdf";
802  Wt::WString* selectedFormat = new Wt::WString();
803  std::string name;
804  name = WFileDialog::getSaveFileName ( fGLWindow,
805  tr("Save as ..."),
806  ".",
807  filters,
808  selectedFormat ).toUTF8().c_str();
809  // bmp jpg jpeg png ppm xbm xpm
810  if (name.empty()) {
811  return;
812  }
813  name += "." + selectedFormat->toUTF8();
814  Wt::WString format = selectedFormat->toLower();
815  setPrintFilename(name.c_str(),0);
816  G4OpenGLWtExportDialog* exportDialog= new G4OpenGLWtExportDialog(fGLWindow,format,fWindow->height(),fWindow->width());
817  if( exportDialog->exec()) {
818 
819  WImage image;
820  bool res = false;
821  if ((exportDialog->getWidth() !=fWindow->width()) ||
822  (exportDialog->getHeight() !=fWindow->height())) {
823  setPrintSize(exportDialog->getWidth(),exportDialog->getHeight());
824  if ((format != Wt::WString("eps")) && (format != Wt::WString("ps"))) {
825  G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
826 
827  // rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
828  // WGLWidget* glResized = fWindow;
829 
830  // FIXME :
831  // L.Garnier : I've try to implement change size function, but the problem is
832  // the renderPixmap function call the WGLWidget to resize and it doesn't draw
833  // the content of this widget... It only draw the background.
834 
835  // fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
836 
837  // WPixmap pixmap = fWindow->renderPixmap ();
838 
839  // image = pixmap->toImage();
840  // glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
841  // image = glResized->grabFrameBuffer();
842  }
843  } else {
844  image = fWindow->grabFrameBuffer();
845  }
846  if (format == Wt::WString("eps")) {
847  fVectoredPs = exportDialog->getVectorEPS();
848  printEPS();
849  } else if (format == "ps") {
850  fVectoredPs = true;
851  printEPS();
852  } else if (format == "pdf") {
853 
854  res = printPDF(name,exportDialog->getNbColor(),image);
855 
856  } else if ((format == "tif") ||
857  (format == "tiff") ||
858  (format == "jpg") ||
859  (format == "jpeg") ||
860  (format == "png") ||
861  (format == "pbm") ||
862  (format == "pgm") ||
863  (format == "ppm") ||
864  (format == "bmp") ||
865  (format == "xbm") ||
866  (format == "xpm")) {
867  res = image.save(Wt::WString(name.c_str()),0,exportDialog->getSliderValue());
868  } else {
869  G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
870  }
871  if ((format == Wt::WString("eps")) && (format == Wt::WString("ps"))) {
872  if (res == false) {
873  G4cerr << "Error while saving file... "<<name.c_str()<< G4endl;
874  } else {
875  G4cout << "File "<<name.c_str()<<" has been saved " << G4endl;
876  }
877  }
878 
879  } else { // cancel selected
880  return;
881  }
882 
883 }
884 #endif
885 
886 
887 #ifdef _A_FINIR_FIXME
888 void G4OpenGLWtViewer::actionChangeBackgroundColor() {
889 
890  // //I need to revisit the kernel if the background colour changes and
891  // //hidden line removal is enabled, because hlr drawing utilises the
892  // //background colour in its drawing...
893  // // (Note added by JA 13/9/2005) Background now handled in view
894  // // parameters. A kernel visit is triggered on change of background.
895 
896  WColor color;
897  color = WColorDialog::getColor(Wt::black, fGLWindow);
898  if (color.isValid()) {
899  Wt::WString com = "/vis/viewer/set/background ";
900  Wt::WString num;
901  com += num.setNum(((float)color.red())/256)+" ";
902  com += num.setNum(((float)color.green())/256)+" ";
903  com += num.setNum(((float)color.blue())/256)+" ";
904  G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
905  updateWWidget();
906  }
907 }
908 
909 void G4OpenGLWtViewer::actionChangeTextColor() {
910 
911  WColor color;
912  color = WColorDialog::getColor(Wt::yellow, fGLWindow);
913  if (color.isValid()) {
914  Wt::WString com = "/vis/viewer/set/defaultTextColour ";
915  Wt::WString num;
916  com += num.setNum(((float)color.red())/256)+" ";
917  com += num.setNum(((float)color.green())/256)+" ";
918  com += num.setNum(((float)color.blue())/256)+" ";
919  G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
920  updateWWidget();
921  }
922 }
923 
924 void G4OpenGLWtViewer::actionChangeDefaultColor() {
925 
926  WColor color;
927  color = WColorDialog::getColor(Wt::white, fGLWindow);
928  printf("actionChangeDefaultColor\n");
929  if (color.isValid()) {
930  Wt::WString com = "/vis/viewer/set/defaultColour ";
931  Wt::WString num;
932  com += num.setNum(((float)color.red())/256)+" ";
933  com += num.setNum(((float)color.green())/256)+" ";
934  com += num.setNum(((float)color.blue())/256)+" ";
935  G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
936  updateWWidget();
937  }
938 }
939 
940 
941 void G4OpenGLWtViewer::actionMovieParameters() {
942  showMovieParametersDialog();
943 }
944 
945 
946 void G4OpenGLWtViewer::showMovieParametersDialog() {
947  if (!fMovieParametersDialog) {
948  fMovieParametersDialog= new G4OpenGLWtMovieDialog(this,fGLWindow);
949  displayRecordingStatus();
950  fMovieParametersDialog->checkEncoderSwParameters();
951  fMovieParametersDialog->checkSaveFileNameParameters();
952  fMovieParametersDialog->checkTempFolderParameters();
953  if (getEncoderPath() == "") {
954  setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
955  }
956  }
957  fMovieParametersDialog->show();
958 }
959 #endif
960 
961 /*
962 // 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
963 
964 void Graph::exportToSVG(const Wt::WString& fname)
965 {
966  // enable workaround for Wt3 misalignments
967  WwtPainter::setSVGMode(true);
968  WPicture picture;
969  WPainter p(&picture);
970  d_plot->print(&p, d_plot->rect());
971  p.end();
972 
973  picture.save(fname, "svg");
974 }
975 */
976 
977 
978 
979 void G4OpenGLWtViewer::FinishView()
980 {
981  glFlush ();
982 
983  // L. Garnier 10/2009 : Not necessary and cause problems on mac OS X 10.6
984  // fWindow->swapBuffers ();
985 }
986 
991 void G4OpenGLWtViewer::G4MousePressEvent(Wt::WMouseEvent *event)
992 {
993  if (event->button() & Wt::WMouseEvent::LeftButton) {
994 #ifdef _A_FINIR_FIXME
995  fWindow->setMouseTracking(true);
996 #endif
997  fAutoMove = false; // stop automove
998  fLastPos1 = Wt::WPoint(event->widget().x,event->widget().y);
999  fLastPos2 = fLastPos1;
1000  fLastPos3 = fLastPos2;
1001  fLastEventTime->start();
1002  if (fMouseAction == STYLE3){ // pick
1003  Pick(event->widget().x,event->widget().y);
1004  }
1005  }
1006 }
1007 
1010 void G4OpenGLWtViewer::G4MouseReleaseEvent()
1011 {
1012  fSpinningDelay = fLastEventTime->elapsed();
1013  Wt::WPoint delta = Wt::WPoint(fLastPos3.x()-fLastPos1.x(),fLastPos3.y()-fLastPos1.y());
1014  if ((delta.x() == 0) && (delta.y() == 0)) {
1015  return;
1016  }
1017  if (fSpinningDelay < fLaunchSpinDelay ) {
1018  fAutoMove = true;
1019  Wt::WTime lastMoveTime;
1020  lastMoveTime.start();
1021  // try to addapt speed move/rotate looking to drawing speed
1022  float correctionFactor = 5;
1023  while (fAutoMove) {
1024  if ( lastMoveTime.elapsed () >= (int)(1000/fNbMaxFramesPerSec)) {
1025  float lTime = 1000/((float)lastMoveTime.elapsed ());
1026  if (((((float)delta.x())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1027  ((((float)delta.x())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1028  correctionFactor = (float)delta.x()*(lTime/fNbMaxAnglePerSec);
1029  if (delta.x() <0 ) {
1030  correctionFactor = -correctionFactor;
1031  }
1032  }
1033  if (((((float)delta.y())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1034  ((((float)delta.y())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1035  correctionFactor = (float)delta.y()*(lTime/fNbMaxAnglePerSec);
1036  if (delta.y() <0 ) {
1037  correctionFactor = -correctionFactor;
1038  }
1039  }
1040 
1041  // Check Wt Versions for META Keys
1042 
1043  // Click and move mouse to rotate volume
1044  // ALT + Click and move mouse to rotate volume (View Direction)
1045  // SHIFT + Click and move camera point of view
1046  // CTRL + Click and zoom mouse to zoom in/out
1047 
1048  if (fMouseAction == STYLE1) { // rotate
1049  if (fNoKeyPress) {
1050  rotateWtScene(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1051  } else if (fAltKeyPress) {
1052  rotateWtSceneInViewDirection(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1053  }
1054 
1055  } else if (fMouseAction == STYLE2) { // move
1056  moveScene(-((float)delta.x())/correctionFactor,-((float)delta.y())/correctionFactor,0,true);
1057  }
1058  lastMoveTime.start();
1059  }
1060 #ifdef _A_FINIR_FIXME
1061  ((Wt::WApplication*)G4Wt::getInstance ())->processEvents();
1062 #endif
1063  }
1064  }
1065 #ifdef _A_FINIR_FIXME
1066  fWindow->setMouseTracking(false);
1067 #endif
1068 }
1069 
1070 
1071 void G4OpenGLWtViewer::G4MouseDoubleClickEvent()
1072 {
1073 #ifdef _A_FINIR_FIXME
1074  fWindow->setMouseTracking(true);
1075 #endif
1076 }
1077 
1078 
1086  void G4OpenGLWtViewer::G4MouseMoveEvent(Wt::WMouseEvent *event)
1087 {
1088 
1089  Wt::WMouseEvent::Button mButtons = event->button();
1090 
1091 #ifdef _A_FINIR_FIXME
1092  updateKeyModifierState(event->modifiers());
1093 #endif
1094 
1095  if (fAutoMove) {
1096  return;
1097  }
1098 
1099  fLastPos3 = fLastPos2;
1100  fLastPos2 = fLastPos1;
1101  fLastPos1 = Wt::WPoint(event->widget().x, event->widget().y);
1102 
1103  int deltaX = fLastPos2.x()-fLastPos1.x();
1104  int deltaY = fLastPos2.y()-fLastPos1.y();
1105 
1106  if (fMouseAction == STYLE1) { // rotate
1107  if (mButtons & Wt::WMouseEvent::LeftButton) {
1108  if (fNoKeyPress) {
1109  rotateWtScene(((float)deltaX),((float)deltaY));
1110  } else if (fAltKeyPress) {
1111  rotateWtSceneInViewDirection(((float)deltaX),((float)deltaY));
1112  } else if (fShiftKeyPress) {
1113  unsigned int sizeWin;
1114  sizeWin = getWinWidth();
1115  if (getWinHeight() < getWinWidth()) {
1116  sizeWin = getWinHeight();
1117  }
1118 
1119  // L.Garnier : 08/2010 100 is the good value, but don't ask me why !
1120  float factor = ((float)100/(float)sizeWin) ;
1121  moveScene(-(float)deltaX*factor,-(float)deltaY*factor,0,false);
1122  } else if (fControlKeyPress) {
1123  fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+((float)deltaY)));
1124  }
1125  }
1126  } else if (fMouseAction == STYLE2) { // move
1127  if (mButtons & Wt::WMouseEvent::LeftButton) {
1128  moveScene(-deltaX,-deltaY,0,true);
1129  }
1130  }
1131 
1132  fLastEventTime->start();
1133 }
1134 
1135 
1143 void G4OpenGLWtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1144 {
1145  if (fHoldMoveEvent)
1146  return;
1147  fHoldMoveEvent = true;
1148 
1149  G4double coefTrans = 0;
1150  GLdouble coefDepth = 0;
1151  if(mouseMove) {
1152  coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinWidth());
1153  if (getWinHeight() <getWinWidth()) {
1154  coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
1155  }
1156  } else {
1157  coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1158  coefDepth = getSceneDepth()*fDeltaDepth;
1159  }
1160  fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1161  updateWWidget();
1162  if (fAutoMove)
1163 #ifdef _A_FINIR_FIXME
1164  ((WApplication*)G4Wt::getInstance ())->processEvents();
1165 #endif
1166 
1167  fHoldMoveEvent = false;
1168 }
1169 
1170 
1176 void G4OpenGLWtViewer::rotateWtScene(float dx, float dy)
1177 {
1178  if (fHoldRotateEvent)
1179  return;
1180  fHoldRotateEvent = true;
1181 
1182  if( dx != 0) {
1183  rotateScene(dx,0);
1184  }
1185  if( dy != 0) {
1186  rotateScene(0,dy);
1187  }
1188  updateWWidget();
1189 
1190  fHoldRotateEvent = false;
1191 }
1192 
1198 void G4OpenGLWtViewer::rotateWtSceneInViewDirection(float dx, float dy)
1199 {
1200  if (fHoldRotateEvent)
1201  return;
1202  fHoldRotateEvent = true;
1203 
1204  fXRot +=dx;
1205  fYRot +=dy;
1206 
1207  rotateSceneInViewDirection(dx/100,dy/100);
1208 
1209  updateWWidget();
1210 
1211  fHoldRotateEvent = false;
1212 }
1213 
1219 void G4OpenGLWtViewer::rotateWtCamera(float dx, float dy)
1220 {
1221  if (fHoldRotateEvent)
1222  return;
1223  fHoldRotateEvent = true;
1224 
1225  rotateScene(dx,dy);
1226  updateWWidget();
1227 
1228  fHoldRotateEvent = false;
1229 }
1230 
1236 void G4OpenGLWtViewer::rotateWtCameraInViewDirection(float dx, float dy)
1237 {
1238  if (fHoldRotateEvent)
1239  return;
1240  fHoldRotateEvent = true;
1241 
1242  fVP.SetUpVector(G4Vector3D(0.0, 1.0, 0.0));
1243  fVP.SetViewAndLights (G4Vector3D(0.0, 0.0, 1.0));
1244 
1245 
1246  fXRot +=dx;
1247  fYRot +=dy;
1248 
1249  rotateSceneInViewDirection(fXRot/100,fYRot/100);
1250 
1251  updateWWidget();
1252 
1253  fHoldRotateEvent = false;
1254 }
1255 
1256 
1257 
1258 
1259 
1264 void G4OpenGLWtViewer::rescaleImage(
1265  int /* aWidth */
1266 ,int /* aHeight */
1267 ){
1268  // GLfloat* feedback_buffer;
1269  // GLint returned;
1270  // FILE* file;
1271 
1272 // feedback_buffer = new GLfloat[size];
1273 // glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1274 // glRenderMode (GL_FEEDBACK);
1275 
1276 // DrawView();
1277 // returned = glRenderMode (GL_RENDER);
1278 
1279 }
1280 
1281 
1282 
1283 #ifdef _A_FINIR_FIXME
1284 
1290 bool G4OpenGLWtViewer::printPDF (
1291  const std::string aFilename
1292 ,int aInColor
1293 ,WImage aImage
1294 )
1295 {
1296 
1297  WPrinter printer;
1298  // printer.setPageSize(pageSize);
1299 
1300  // FIXME : L. Garnier 4/12/07
1301  // This is not working, it does nothing. Image is staying in color mode
1302  // So I have desactivate the B/W button in GUI
1303  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1304  aImage = aImage.convertToFormat ( aImage.format(), Wt::MonoOnly);
1305  }
1306 
1307 
1308  if (aFilename.substr(aFilename.size()-3) == ".ps") {
1309 #if WT_VERSION > 0x040200
1310  printer.setOutputFormat(WPrinter::PostScriptFormat);
1311 #endif
1312  } else {
1313 #if WT_VERSION > 0x040100
1314  printer.setOutputFormat(WPrinter::PdfFormat);
1315 #endif
1316  }
1317 #if WT_VERSION > 0x040100
1318  printer.setOutputFileName(Wt::WString(aFilename.c_str()));
1319 #endif
1320  // printer.setFullPage ( true);
1321  WPainter paint(&printer);
1322  paint.drawImage (0,0,aImage);
1323  paint.end();
1324  return true;
1325 }
1326 
1327 
1328 
1329 void G4OpenGLWtViewer::G4wheelEvent (Wt::WWheelEvent * event)
1330 {
1331  fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1332  updateWWidget();
1333 }
1334 #endif
1335 
1336  void G4OpenGLWtViewer::G4keyPressEvent (Wt::WKeyEvent * event)
1337 {
1338  if (fHoldKeyEvent)
1339  return;
1340 
1341  fHoldKeyEvent = true;
1342 
1343 
1344  // with no modifiers
1345 #ifdef _A_FINIR_FIXME
1346  updateKeyModifierState(event->modifiers());
1347 #endif
1348  if ((fNoKeyPress)) { // || (event->modifiers() == Wt::KeyboardModifier )) {
1349  if (event->key() == Wt::Key_Down) { // go down
1350  moveScene(0,1,0,false);
1351  }
1352  else if (event->key() == Wt::Key_Up) { // go up
1353  moveScene(0,-1,0,false);
1354  }
1355  if (event->key() == Wt::Key_Left) { // go left
1356  moveScene(-1,0,0,false);
1357  }
1358  else if (event->key() == Wt::Key_Right) { // go right
1359  moveScene(1,0,0,false);
1360  }
1361  if (event->text() == Wt::WString("-") ) { // go backward
1362  moveScene(0,0,1,false);
1363  }
1364  else if (event->text() == Wt::WString("+")) { // go forward
1365  moveScene(0,0,-1,false);
1366  }
1367 
1368  // escaped from full screen
1369  if (event->key() == Wt::Key_Escape) {
1370 #ifdef _A_FINIR_FIXME
1371  toggleFullScreen(false);
1372 #endif
1373  }
1374  }
1375  // several case here : If return is pressed, in every case -> display the movie parameters dialog
1376  // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1377  // If encoder not found-> does nothing.Only display a message in status box
1378  // If all ok-> generate parameter file
1379  // If ok -> put encoder button enabled
1380 
1381 #ifdef _A_FINIR_FIXME
1382  if ( (event->key() == Wt::Key_Enter)){ // end of video
1383  stopVideo();
1384  }
1385  if (event->key() == Wt::Key_Space){ // start/pause of video
1386  startPauseVideo();
1387  }
1388 #endif
1389 
1390  // H : Return Home view
1391  if (event->key() == Wt::Key_H){ // go Home
1392  fDeltaRotation = 1;
1393  fDeltaSceneTranslation = 0.01;
1394  fDeltaDepth = 0.01;
1395  fDeltaZoom = 0.05;
1396  fDeltaMove = 0.05;
1397 
1398  fVP.SetZoomFactor(1.);
1399  fVP.SetUpVector(G4Vector3D (0., 1., 0.));
1400  fVP.SetViewAndLights (G4Vector3D (0., 0., 1.));
1401 
1402  updateWWidget();
1403  }
1404 
1405  // Shift Modifier
1406  if (fShiftKeyPress) {
1407  if (event->key() == Wt::Key_Down) { // rotate phi
1408  rotateWtScene(0,-fDeltaRotation);
1409  }
1410  else if (event->key() == Wt::Key_Up) { // rotate phi
1411  rotateWtScene(0,fDeltaRotation);
1412  }
1413  if (event->key() == Wt::Key_Left) { // rotate theta
1414  rotateWtScene(fDeltaRotation,0);
1415  }
1416  else if (event->key() == Wt::Key_Right) { // rotate theta
1417  rotateWtScene(-fDeltaRotation,0);
1418  }
1419 
1420  // Alt Modifier
1421  }
1422  if ((fAltKeyPress)) {
1423  if (event->key() == Wt::Key_Down) { // rotate phi
1424  rotateWtSceneInViewDirection(0,-fDeltaRotation);
1425  }
1426  else if (event->key() == Wt::Key_Up) { // rotate phi
1427  rotateWtSceneInViewDirection(0,fDeltaRotation);
1428  }
1429  if (event->key() == Wt::Key_Left) { // rotate theta
1430  rotateWtSceneInViewDirection(fDeltaRotation,0);
1431  }
1432  else if (event->key() == Wt::Key_Right) { // rotate theta
1433  rotateWtSceneInViewDirection(-fDeltaRotation,0);
1434  }
1435 
1436  // Rotatio +/-
1437  if (event->text() == Wt::WString("+")) {
1438  fDeltaRotation = fDeltaRotation/0.7;
1439  G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
1440  }
1441  else if (event->text() == Wt::WString("-")) {
1442  fDeltaRotation = fDeltaRotation*0.7;
1443  G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
1444  }
1445 
1446  // Control Modifier OR Command on MAC
1447  }
1448  if ((fControlKeyPress)) {
1449  if (event->text() == Wt::WString("+")) {
1450  fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1451  updateWWidget();
1452  }
1453  else if (event->text() == Wt::WString("-")) {
1454  fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1455  updateWWidget();
1456  }
1457  }
1458 
1459  fHoldKeyEvent = false;
1460 }
1461 
1462 
1463 #ifdef _A_FINIR_FIXME
1464 void G4OpenGLWtViewer::updateKeyModifierState(Wt::KeyboardModifiers modifier) {
1465  // Check Wt Versions for META Keys
1466 
1467  fNoKeyPress = true;
1468  fAltKeyPress = false;
1469  fShiftKeyPress = false;
1470  fControlKeyPress = false;
1471 
1472  if (modifier & Wt::AltModifier ) {
1473  fAltKeyPress = true;
1474  fNoKeyPress = false;
1475  }
1476  if (modifier & Wt::ShiftModifier ) {
1477  fShiftKeyPress = true;
1478  fNoKeyPress = false;
1479  }
1480  if (modifier & Wt::ControlModifier ) {
1481  fControlKeyPress = true;
1482  fNoKeyPress = false;
1483  }
1484 }
1485 
1488 void G4OpenGLWtViewer::stopVideo() {
1489 
1490  // if encoder parameter is wrong, display parameters dialog and return
1491  if (!fMovieParametersDialog) {
1492  showMovieParametersDialog();
1493  }
1494  setRecordingStatus(STOP);
1495 
1496  if (fRecordFrameNumber >0) {
1497  // check parameters if they were modified (Re APPLY them...)
1498  if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1499  setRecordingStatus(BAD_ENCODER);
1500  } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1501  setRecordingStatus(BAD_OUTPUT);
1502  }
1503  } else {
1504  resetRecording();
1505  setRecordingInfos("No frame to encode.");
1506  }
1507 }
1508 
1511 void G4OpenGLWtViewer::saveVideo() {
1512 
1513  // if encoder parameter is wrong, display parameters dialog and return
1514  if (!fMovieParametersDialog) {
1515  showMovieParametersDialog();
1516  }
1517 
1518  fMovieParametersDialog->checkEncoderSwParameters();
1519  fMovieParametersDialog->checkSaveFileNameParameters();
1520 
1521  if (fRecordingStep == STOP) {
1522  setRecordingStatus(SAVE);
1523  generateMpegEncoderParameters();
1524  encodeVideo();
1525  }
1526 }
1527 
1528 
1531 void G4OpenGLWtViewer::startPauseVideo() {
1532 
1533  // first time, if temp parameter is wrong, display parameters dialog and return
1534 
1535  if (( fRecordingStep == WAIT)) {
1536  if ( fRecordFrameNumber == 0) {
1537  if (getTempFolderPath() == "") { // BAD_OUTPUT
1538  showMovieParametersDialog();
1539  setRecordingInfos("You should specified the temp folder in order to make movie");
1540  return;
1541  } else {
1542  // remove temp folder if it was create
1543  Wt::WString tmp = removeTempFolder();
1544  if (tmp !="") {
1545  setRecordingInfos(tmp);
1546  return;
1547  }
1548  tmp = createTempFolder();
1549  if (tmp != "") {
1550  setRecordingInfos("Can't create temp folder."+tmp);
1551  return;
1552  }
1553  }
1554  }
1555  }
1556  if ((fRecordingStep == WAIT)) {
1557  setRecordingStatus(START);
1558  } else if (fRecordingStep == START) {
1559  setRecordingStatus(PAUSE);
1560  } else if (fRecordingStep == PAUSE) {
1561  setRecordingStatus(CONTINUE);
1562  } else if (fRecordingStep == CONTINUE) {
1563  setRecordingStatus(PAUSE);
1564  }
1565 }
1566 
1567 void G4OpenGLWtViewer::setRecordingStatus(RECORDING_STEP step) {
1568 
1569  fRecordingStep = step;
1570  displayRecordingStatus();
1571 }
1572 
1573 
1574 void G4OpenGLWtViewer::displayRecordingStatus() {
1575 
1576  Wt::WString txtStatus = "";
1577  if (fRecordingStep == WAIT) {
1578  txtStatus = "Waiting to start...";
1579  fRecordFrameNumber = 0; // reset the frame number
1580  } else if (fRecordingStep == START) {
1581  txtStatus = "Start Recording...";
1582  } else if (fRecordingStep == PAUSE) {
1583  txtStatus = "Pause Recording...";
1584  } else if (fRecordingStep == CONTINUE) {
1585  txtStatus = "Continue Recording...";
1586  } else if (fRecordingStep == STOP) {
1587  txtStatus = "Stop Recording...";
1588  } else if (fRecordingStep == READY_TO_ENCODE) {
1589  txtStatus = "Ready to Encode...";
1590  } else if (fRecordingStep == ENCODING) {
1591  txtStatus = "Encoding...";
1592  } else if (fRecordingStep == FAILED) {
1593  txtStatus = "Failed to encode...";
1594  } else if ((fRecordingStep == BAD_ENCODER)
1595  || (fRecordingStep == BAD_OUTPUT)
1596  || (fRecordingStep == BAD_TMP)) {
1597  txtStatus = "Correct above errors first";
1598  } else if (fRecordingStep == SUCCESS) {
1599  txtStatus = "File encoded successfully";
1600  } else {
1601  }
1602 
1603  if (fMovieParametersDialog) {
1604  fMovieParametersDialog->setRecordingStatus(txtStatus);
1605  } else {
1606  G4cout << txtStatus.toUTF8().c_str() << G4endl;
1607  }
1608  setRecordingInfos("");
1609 }
1610 
1611 
1612 void G4OpenGLWtViewer::setRecordingInfos(Wt::WString txt) {
1613  if (fMovieParametersDialog) {
1614  fMovieParametersDialog->setRecordingInfos(txt);
1615  } else {
1616  G4cout << txt.toUTF8().c_str() << G4endl;
1617  }
1618 }
1619 
1622 void G4OpenGLWtViewer::initMovieParameters() {
1623  //init encoder
1624 
1625  //look for encoderPath
1626  fProcess = new WProcess();
1627 
1628  WObject ::connect(fProcess,SIGNAL(finished ( int)),
1629  this,SLOT(processLookForFinished()));
1630  fProcess->setReadChannelMode(WProcess::MergedChannels);
1631  fProcess->start ("which mpeg_encode");
1632 
1633 }
1634 
1637 Wt::WString G4OpenGLWtViewer::getEncoderPath() {
1638  return fEncoderPath;
1639 }
1640 
1641 
1646 Wt::WString G4OpenGLWtViewer::setEncoderPath(Wt::WString path) {
1647  if (path == "") {
1648  return "File does not exist";
1649  }
1650 
1651  path = WDir::cleanPath(path);
1652  WFileInfo *f = new WFileInfo(path);
1653  if (!f->exists()) {
1654  return "File does not exist";
1655  } else if (f->isDir()) {
1656  return "This is a directory";
1657  } else if (!f->isExecutable()) {
1658  return "File exist but is not executable";
1659  } else if (!f->isFile()) {
1660  return "This is not a file";
1661  }
1662  fEncoderPath = path;
1663 
1664  if ((fRecordingStep == BAD_ENCODER)) {
1665  setRecordingStatus(STOP);
1666  }
1667  return "";
1668 }
1669 
1670 
1671 bool G4OpenGLWtViewer::isRecording(){
1672  if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
1673  return true;
1674  }
1675  return false;
1676 }
1677 
1678 bool G4OpenGLWtViewer::isPaused(){
1679  if (fRecordingStep == PAUSE) {
1680  return true;
1681  }
1682  return false;
1683 }
1684 
1685 bool G4OpenGLWtViewer::isEncoding(){
1686  if (fRecordingStep == ENCODING) {
1687  return true;
1688  }
1689  return false;
1690 }
1691 
1692 bool G4OpenGLWtViewer::isWaiting(){
1693  if (fRecordingStep == WAIT) {
1694  return true;
1695  }
1696  return false;
1697 }
1698 
1699 bool G4OpenGLWtViewer::isStopped(){
1700  if (fRecordingStep == STOP) {
1701  return true;
1702  }
1703  return false;
1704 }
1705 
1706 bool G4OpenGLWtViewer::isFailed(){
1707  if (fRecordingStep == FAILED) {
1708  return true;
1709  }
1710  return false;
1711 }
1712 
1713 bool G4OpenGLWtViewer::isSuccess(){
1714  if (fRecordingStep == SUCCESS) {
1715  return true;
1716  }
1717  return false;
1718 }
1719 
1720 bool G4OpenGLWtViewer::isBadEncoder(){
1721  if (fRecordingStep == BAD_ENCODER) {
1722  return true;
1723  }
1724  return false;
1725 }
1726 bool G4OpenGLWtViewer::isBadTmp(){
1727  if (fRecordingStep == BAD_TMP) {
1728  return true;
1729  }
1730  return false;
1731 }
1732 bool G4OpenGLWtViewer::isBadOutput(){
1733  if (fRecordingStep == BAD_OUTPUT) {
1734  return true;
1735  }
1736  return false;
1737 }
1738 
1739 void G4OpenGLWtViewer::setBadEncoder(){
1740  fRecordingStep = BAD_ENCODER;
1741  displayRecordingStatus();
1742 }
1743 void G4OpenGLWtViewer::setBadTmp(){
1744  fRecordingStep = BAD_TMP;
1745  displayRecordingStatus();
1746 }
1747 void G4OpenGLWtViewer::setBadOutput(){
1748  fRecordingStep = BAD_OUTPUT;
1749  displayRecordingStatus();
1750 }
1751 
1752 void G4OpenGLWtViewer::setWaiting(){
1753  fRecordingStep = WAIT;
1754  displayRecordingStatus();
1755 }
1756 
1757 
1758 bool G4OpenGLWtViewer::isReadyToEncode(){
1759  if (fRecordingStep == READY_TO_ENCODE) {
1760  return true;
1761  }
1762  return false;
1763 }
1764 
1765 void G4OpenGLWtViewer::resetRecording() {
1766  setRecordingStatus(WAIT);
1767 }
1768 
1773 Wt::WString G4OpenGLWtViewer::setTempFolderPath(Wt::WString path) {
1774 
1775  if (path == "") {
1776  return "Path does not exist";
1777  }
1778  path = WDir::cleanPath(path);
1779  WFileInfo *d = new WFileInfo(path);
1780  if (!d->exists()) {
1781  return "Path does not exist";
1782  } else if (!d->isDir()) {
1783  return "This is not a directory";
1784  } else if (!d->isReadable()) {
1785  return path +" is read protected";
1786  } else if (!d->isWritable()) {
1787  return path +" is write protected";
1788  }
1789 
1790  if ((fRecordingStep == BAD_TMP)) {
1791  setRecordingStatus(WAIT);
1792  }
1793  fTempFolderPath = path;
1794  return "";
1795 }
1796 
1799 Wt::WString G4OpenGLWtViewer::getTempFolderPath() {
1800  return fTempFolderPath;
1801 }
1802 
1807 Wt::WString G4OpenGLWtViewer::setSaveFileName(Wt::WString path) {
1808 
1809  if (path == "") {
1810  return "Path does not exist";
1811  }
1812 
1813  WFileInfo *file = new WFileInfo(path);
1814  WDir dir = file->dir();
1815  path = WDir::cleanPath(path);
1816  if (file->exists()) {
1817  return "File already exist, please choose a new one";
1818  } else if (!dir.exists()) {
1819  return "Dir does not exist";
1820  } else if (!dir.isReadable()) {
1821  return path +" is read protected";
1822  }
1823 
1824  if ((fRecordingStep == BAD_OUTPUT)) {
1825  setRecordingStatus(STOP);
1826  }
1827  fSaveFileName = path;
1828  return "";
1829 }
1830 
1833 Wt::WString G4OpenGLWtViewer::getSaveFileName() {
1834  return fSaveFileName ;
1835 }
1836 
1841 Wt::WString G4OpenGLWtViewer::createTempFolder() {
1842  fMovieTempFolderPath = "";
1843  //check
1844  Wt::WString tmp = setTempFolderPath(fTempFolderPath);
1845  if (tmp != "") {
1846  return tmp;
1847  }
1848  Wt::WString sep = Wt::WString(WDir::separator());
1849  Wt::WString path = sep+"WtMovie_"+WDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
1850  WDir *d = new WDir(WDir::cleanPath(fTempFolderPath));
1851  // check if it is already present
1852  if (d->exists(path)) {
1853  return "Folder "+path+" already exists.Please remove it first";
1854  }
1855  if (d->mkdir(fTempFolderPath+path)) {
1856  fMovieTempFolderPath = fTempFolderPath+path;
1857  return "";
1858  } else {
1859  return "Can't create "+fTempFolderPath+path;
1860  }
1861  return "-";
1862 }
1863 
1866 Wt::WString G4OpenGLWtViewer::removeTempFolder() {
1867  // remove files in Wt_temp folder
1868  if (fMovieTempFolderPath == "") {
1869  return "";
1870  }
1871  WDir *d = new WDir(WDir::cleanPath(fMovieTempFolderPath));
1872  if (!d->exists()) {
1873  return ""; // already remove
1874  }
1875 
1876  d->setFilter( WDir::Files );
1877  Wt::WStringList subDirList = d->entryList();
1878  int res = true;
1879  Wt::WString error = "";
1880  for (Wt::WStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
1881  const Wt::WString currentFile = *it;
1882  if (!d->remove(currentFile)) {
1883  res = false;
1884  Wt::WString file = fMovieTempFolderPath+currentFile;
1885  error +="Removing file failed : "+file;
1886  } else {
1887  }
1888  }
1889  if (res) {
1890  if (d->rmdir(fMovieTempFolderPath)) {
1891  fMovieTempFolderPath = "";
1892  return "";
1893  } else {
1894  return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
1895  }
1896 
1897  }
1898  return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
1899 }
1900 
1901 
1902 
1903 bool G4OpenGLWtViewer::hasPendingEvents () {
1904 #ifdef _A_FINIR_FIXME
1905  return ((WApplication*)G4Wt::getInstance ())->hasPendingEvents ();
1906 #endif
1907  return false;
1908 }
1909 
1910 bool G4OpenGLWtViewer::generateMpegEncoderParameters () {
1911 
1912  // save the parameter file
1913  FILE* fp;
1914  fp = fopen (Wt::WString(fMovieTempFolderPath+fParameterFileName).toUTF8().c_str(), "w");
1915 
1916  if (fp == NULL) {
1917  setRecordingInfos("Generation of parameter file failed");
1918  return false;
1919  }
1920 
1921  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
1922  fprintf (fp,"#\n");
1923  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
1924  fprintf (fp,"# the copy\n");
1925  fprintf (fp,"#\n");
1926  fprintf (fp,"#\n");
1927  fprintf (fp,"# any line beginning with '#' is a comment\n");
1928  fprintf (fp,"#\n");
1929  fprintf (fp,"# no line should be longer than 255 characters\n");
1930  fprintf (fp,"#\n");
1931  fprintf (fp,"#\n");
1932  fprintf (fp,"# general format of each line is:\n");
1933  fprintf (fp,"# \n");
1934  fprintf (fp,"#\n");
1935  fprintf (fp,"# lines can generally be in any order\n");
1936  fprintf (fp,"#\n");
1937  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
1938  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
1939  fprintf (fp,"#\n");
1940  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
1941  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
1942  fprintf (fp,"# the INPUT parameter.\n");
1943  fprintf (fp,"#\n");
1944  fprintf (fp,"# MUST be in UPPER CASE\n");
1945  fprintf (fp,"#\n");
1946  fprintf (fp,"\n");
1947  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
1948  fprintf (fp,"# for more info.\n");
1949  fprintf (fp,"\n");
1950  fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
1951  fprintf (fp,"OUTPUT %s\n",getSaveFileName().toUTF8().c_str());
1952  fprintf (fp,"\n");
1953  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
1954  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
1955  fprintf (fp,"#\n");
1956  fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
1957  fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
1958  fprintf (fp,"# (must be upper case)\n");
1959  fprintf (fp,"#\n");
1960  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
1961  fprintf (fp,"\n");
1962  fprintf (fp,"#\n");
1963  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
1964  fprintf (fp,"# YUV_SIZE widthxheight\n");
1965  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
1966  fprintf (fp,"# on just one machine\n");
1967  fprintf (fp,"#\n");
1968  fprintf (fp,"YUV_SIZE 352x240\n");
1969  fprintf (fp,"\n");
1970  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
1971  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
1972  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
1973  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
1974  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
1975  fprintf (fp,"# to specify the file order.\n");
1976  fprintf (fp,"\n");
1977  fprintf (fp,"INPUT_FORMAT UCB\n");
1978  fprintf (fp,"\n");
1979  fprintf (fp,"# the conversion statement\n");
1980  fprintf (fp,"#\n");
1981  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
1982  fprintf (fp,"#\n");
1983  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
1984  fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
1985  fprintf (fp,"#\n");
1986  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
1987  fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
1988  fprintf (fp,"#\n");
1989  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
1990  fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
1991  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
1992  fprintf (fp,"#\n");
1993  fprintf (fp,"INPUT_CONVERT * \n");
1994  fprintf (fp,"\n");
1995  fprintf (fp,"# number of frames in a GOP.\n");
1996  fprintf (fp,"#\n");
1997  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
1998  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
1999  fprintf (fp,"#\n");
2000  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2001  fprintf (fp,"#\n");
2002  fprintf (fp,"GOP_SIZE 16\n");
2003  fprintf (fp,"\n");
2004  fprintf (fp,"# number of slices in a frame\n");
2005  fprintf (fp,"#\n");
2006  fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2007  fprintf (fp,"# (which is the height divided by 16)\n");
2008  fprintf (fp,"#\n");
2009  fprintf (fp,"SLICES_PER_FRAME 1\n");
2010  fprintf (fp,"\n");
2011  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2012  fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toUTF8().c_str());
2013  fprintf (fp,"\n");
2014  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2015  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2016  fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2017  fprintf (fp,"INPUT\n");
2018  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2019  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2020  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2021  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2022  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2023  fprintf (fp,"# if you do, too bad!!!\n");
2024  fprintf (fp,"#\n");
2025  fprintf (fp,"#\n");
2026  fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2027  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2028  fprintf (fp,"# of files\n");
2029  fprintf (fp,"END_INPUT\n");
2030  fprintf (fp,"\n");
2031  fprintf (fp,"\n");
2032  fprintf (fp,"\n");
2033  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2034  fprintf (fp,"\n");
2035  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2036  fprintf (fp,"# Should be FULL for computer generated images\n");
2037  fprintf (fp,"PIXEL FULL\n");
2038  fprintf (fp,"\n");
2039  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2040  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2041  fprintf (fp,"RANGE 10\n");
2042  fprintf (fp,"\n");
2043  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2044  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2045  fprintf (fp,"\n");
2046  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2047  fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2048  fprintf (fp,"\n");
2049  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2050  fprintf (fp,"#\n");
2051  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2052  fprintf (fp,"#\n");
2053  fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2054  fprintf (fp,"\n");
2055  fprintf (fp,"#\n");
2056  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2057  fprintf (fp,"# (values must be between 1 and 31)\n");
2058  fprintf (fp,"# These are the Wscale values for the entire frame in variable bit-rate\n");
2059  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2060  fprintf (fp,"#\n");
2061  fprintf (fp,"\n");
2062  fprintf (fp,"# Wscale (Wuantization scale) affects quality and compression,\n");
2063  fprintf (fp,"# but has very little effect on speed.\n");
2064  fprintf (fp,"\n");
2065  fprintf (fp,"IWSCALE 4\n");
2066  fprintf (fp,"PWSCALE 5\n");
2067  fprintf (fp,"BWSCALE 12\n");
2068  fprintf (fp,"\n");
2069  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2070  fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2071  fprintf (fp,"\n");
2072  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2073  fprintf (fp,"\n");
2074  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2075  fprintf (fp,"#BIT_RATE 1000000\n");
2076  fprintf (fp,"\n");
2077  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2078  fprintf (fp,"BUFFER_SIZE 327680\n");
2079  fprintf (fp,"\n");
2080  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2081  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2082  fprintf (fp,"FRAME_RATE 30\n");
2083  fprintf (fp,"\n");
2084  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2085  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IWTABLE, etc.\n");
2086  fprintf (fp,"\n");
2087  fprintf (fp,"\n");
2088  fclose (fp);
2089 
2090  setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2091  setRecordingStatus(READY_TO_ENCODE);
2092  return true;
2093 }
2094 
2095 void G4OpenGLWtViewer::encodeVideo()
2096 {
2097  if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2098  setRecordingStatus(ENCODING);
2099 
2100  fProcess = new WProcess();
2101  WObject ::connect(fProcess,SIGNAL(finished ( int)),
2102  this,SLOT(processEncodeFinished()));
2103  WObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2104  this,SLOT(processEncodeStdout()));
2105  fProcess->setReadChannelMode(WProcess::MergedChannels);
2106  fProcess->start (fEncoderPath, Wt::WStringList(fMovieTempFolderPath+fParameterFileName));
2107  }
2108 }
2109 
2110 
2111 // FIXME : does not work on Wt3
2112 void G4OpenGLWtViewer::processEncodeStdout()
2113 {
2114  Wt::WString tmp = fProcess->readStdout ().data();
2115  int start = tmp.findRev("ESTIMATED TIME");
2116  tmp = tmp.mid(start,tmp.find("\n",start)-start);
2117  setRecordingInfos(tmp);
2118 }
2119 
2120 
2121 void G4OpenGLWtViewer::processEncodeFinished()
2122 {
2123 
2124  Wt::WString txt = "";
2125  txt = getProcessErrorMsg();
2126  if (txt == "") {
2127  setRecordingStatus(SUCCESS);
2128  } else {
2129  setRecordingStatus(FAILED);
2130  }
2131  // setRecordingInfos(txt+removeTempFolder());
2132 }
2133 
2134 
2135 void G4OpenGLWtViewer::processLookForFinished()
2136  {
2137 
2138  Wt::WString txt = getProcessErrorMsg();
2139  if (txt != "") {
2140  fEncoderPath = "";
2141  } else {
2142  fEncoderPath = Wt::WString(fProcess->readAllStandardOutput ().data()).trimmed();
2143  // if not found, return "not found"
2144  if (fEncoderPath.contains(" ")) {
2145  fEncoderPath = "";
2146  } else if (!fEncoderPath.contains("mpeg_encode")) {
2147  fEncoderPath = "";
2148  }
2149  setEncoderPath(fEncoderPath);
2150  }
2151  // init temp folder
2152  setTempFolderPath(WDir::temp ().absolutePath ());
2153 }
2154 
2155 
2156 Wt::WString G4OpenGLWtViewer::getProcessErrorMsg()
2157 {
2158  Wt::WString txt = "";
2159  if (fProcess->exitCode() != 0) {
2160  switch (fProcess->error()) {
2161  case WProcess::FailedToStart:
2162  txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2163  break;
2164  case WProcess::Crashed:
2165  txt = "The process crashed some time after starting successfully.\n";
2166  break;
2167  case WProcess::Timedout:
2168  txt = "The last waitFor...() function timed out. The state of WProcess is unchanged, and you can try calling waitFor...() again.\n";
2169  break;
2170  case WProcess::WriteError:
2171  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";
2172  break;
2173  case WProcess::ReadError:
2174  txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2175  break;
2176  case WProcess::UnknownError:
2177  txt = "An unknown error occurred. This is the default return value of error().\n";
2178  break;
2179  }
2180  }
2181  return txt;
2182 }
2183 #endif
2184 
2185 
2186 
2187 /*
2188 
2189 void MultiLayer::exportToSVG(const Wt::WString& fname)
2190 {
2191  WPicture picture;
2192  WPainter p(&picture);
2193  for (int i=0;i<(int)graphsList->count();i++)
2194  {
2195  Graph *gr=(Graph *)graphsList->at(i);
2196  Plot *myPlot= (Plot *)gr->plotWidget();
2197 
2198  Wt::WPoint pos=gr->pos();
2199 
2200  int width=int(myPlot->frameGeometry().width());
2201  int height=int(myPlot->frameGeometry().height());
2202 
2203  myPlot->print(&p, WRect(pos,WSize(width,height)));
2204  }
2205 
2206  p.end();
2207  picture.save(fname, "svg");
2208 }
2209 */
2210 #endif