G4OpenGLWtViewer.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // G4OpenGLWtViewer : Class to provide Wt specific
00031 //                     functionality for OpenGL in GEANT4
00032 //
00033 // 27/06/2003 : G.Barrand : implementation (at last !).
00034 
00035 #ifdef G4VIS_BUILD_OPENGLWT_DRIVER
00036 
00037 #include "G4OpenGLWtViewer.hh"
00038 #include "G4VViewer.hh"
00039 #include "G4VSceneHandler.hh"
00040 #include "G4OpenGLSceneHandler.hh"
00041 
00042 #include "G4ios.hh"
00043 #include "G4VisExtent.hh"
00044 #include "G4LogicalVolume.hh"
00045 #include "G4VSolid.hh"
00046 #include "G4Point3D.hh"
00047 #include "G4Normal3D.hh"
00048 #include "G4Scene.hh"
00049 //#include "G4OpenGLWtExportDialog.hh"
00050 //#include "G4OpenGLWtMovieDialog.hh"
00051 #include "G4UnitsTable.hh"
00052 #include "G4Wt.hh"
00053 #include "G4UIWt.hh"
00054 #include "G4UImanager.hh"
00055 #include "G4UIcommandTree.hh"
00056 
00057 #include <WT/WHBoxLayout>
00058 #include <WT/WApplication>
00059 
00060 
00061 
00062 
00064 
00067 void G4OpenGLWtViewer::SetView (
00068 ) 
00069 
00070 
00071 {
00072   G4OpenGLViewer::SetView ();
00073 }
00074 
00075 
00076 
00077 
00079 void G4OpenGLWtViewer::CreateMainWindow (
00080   Wt::WGLWidget* glWidget
00081  ,Wt::WString name
00082 ) 
00083 
00084 
00085 {
00086 #ifdef G4DEBUG_VIS_OGL
00087   printf("G4OpenGLWtViewer::CreateMainWindow \n");
00088 #endif
00089 
00090   if(fWindow) return; //Done.
00091 
00092   fWindow = glWidget ;
00093   //  fWindow->makeCurrent();
00094 
00095   //G4Wt* interactorManager = G4Wt::getInstance ();
00096 
00097   ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY());
00098     
00099   // FIXME L.Garnier 9/11/09 Has to be check !!! 
00100   // Wt UI with Wt Vis
00101   // Wt UI with X Vis
00102   // X UI with Wt Vis
00103   // X UI with X Vis
00104   // Ne marche pas avec un UIBatch !! (ecran blanc)
00105 
00106   // return false if G4UIWt was not launch
00107   
00108   fGLWindow = fWindow;
00109     // FIXME::   fGLWindow->resize(getWinWidth(), getWinHeight());
00110 
00111   if(!fWindow) return;
00112   
00113 #ifdef _A_FINIR_FIXME
00114   if (!fContextMenu) 
00115     createPopupMenu();
00116 #endif
00117 
00118   // FIXME::  updateWWidget();
00119 
00120 }
00121 
00124 // void G4OpenGLWtViewer::dialogClosed() {
00125 //   //  fGLWindow = NULL;
00126 // }
00127 
00129 G4OpenGLWtViewer::G4OpenGLWtViewer (
00130                                     G4OpenGLSceneHandler& scene
00131                                     )
00132   :G4VViewer (scene, -1)
00133   ,G4OpenGLViewer (scene)
00134   ,fWindow(0)
00135   ,fRecordFrameNumber(0)
00136  //#ifdef _A_FINIR_FIXME  ,fContextMenu(0)
00137   ,fMouseAction(STYLE1)
00138   ,fDeltaRotation(1)
00139   ,fDeltaSceneTranslation(0.01)
00140   ,fDeltaDepth(0.01)
00141   ,fDeltaZoom(0.05)
00142   ,fDeltaMove(0.05)
00143   ,fHoldKeyEvent(false)
00144   ,fHoldMoveEvent(false)
00145   ,fHoldRotateEvent(false)
00146   ,fAutoMove(false)
00147   ,fEncoderPath("")
00148   ,fTempFolderPath("")
00149   ,fMovieTempFolderPath("")
00150   ,fSaveFileName("")
00151   ,fParameterFileName("mpeg_encode_parameter_file.par")
00152   ,fMovieParametersDialog(NULL)
00153   ,fRecordingStep(WAIT)
00154   ,fProcess(NULL)
00155   ,fNbMaxFramesPerSec(100)
00156   ,fNbMaxAnglePerSec(360)
00157   ,fLaunchSpinDelay(100)
00158   ,fXRot(0)
00159   ,fYRot(0)
00160   ,fNoKeyPress(true)
00161   ,fAltKeyPress(false)
00162   ,fControlKeyPress(false)
00163   ,fShiftKeyPress(false)
00164 {
00165 
00166   // launch Wt if not
00167   G4Wt::getInstance ();
00168 
00169 #ifdef G4DEBUG_VIS_OGL
00170   printf("G4OpenGLWtViewer::Create \n");
00171 #endif
00172   fLastPos3 = Wt::WPoint(-1,-1);    
00173   fLastPos2 = Wt::WPoint(-1,-1);    
00174   fLastPos1 = Wt::WPoint(-1,-1);    
00175   
00176 #ifdef _A_FINIR_FIXME
00177   initMovieParameters();
00178 #endif
00179 
00180   fLastEventTime = new Wt::WTime();
00181 
00182 #ifdef G4DEBUG_VIS_OGL
00183   printf("G4OpenGLWtViewer::G4OpenGLWtViewer END\n");
00184 #endif
00185 }
00186 
00188 G4OpenGLWtViewer::~G4OpenGLWtViewer (
00189 ) 
00190 
00191 
00192 {
00193 #ifdef _A_FINIR_FIXME
00194   G4cout <<removeTempFolder().toUTF8().c_str() <<G4endl;
00195 #endif
00196 }
00197 
00198 
00199 #ifdef _A_FINIR_FIXME
00200 
00203 void G4OpenGLWtViewer::createPopupMenu()    {
00204 
00205   fContextMenu = new WMenu("All");
00206 
00207   WMenu *mMouseAction = fContextMenu->addMenu("&Mouse actions");
00208 
00209   fRotateAction = mMouseAction->addAction("Rotate");
00210   fMoveAction = mMouseAction->addAction("Move");
00211   fPickAction = mMouseAction->addAction("Pick");
00212   WAction *shortcutsAction = mMouseAction->addAction("Show shortcuts");
00213 
00214   fRotateAction->setCheckable(true);
00215   fMoveAction->setCheckable(false);
00216   fPickAction->setCheckable(false);
00217   shortcutsAction->setCheckable(false);
00218 
00219   fRotateAction->setChecked(true);
00220   fMoveAction->setChecked(false);
00221   fPickAction->setChecked(false);
00222   shortcutsAction->setChecked(false);
00223 
00224   WObject ::connect(fRotateAction, 
00225                     SIGNAL(triggered(bool)),
00226                     this, 
00227                     SLOT(actionMouseRotate()));
00228 
00229   WObject ::connect(fMoveAction, 
00230                     SIGNAL(triggered(bool)),
00231                     this, 
00232                     SLOT(actionMouseMove()));
00233 
00234   WObject ::connect(fPickAction, 
00235                     SIGNAL(triggered(bool)),
00236                     this, 
00237                     SLOT(actionMousePick()));
00238 
00239   WObject ::connect(shortcutsAction, 
00240                     SIGNAL(triggered(bool)),
00241                     this, 
00242                     SLOT(showShortcuts()));
00243 
00244   // === Style Menu ===
00245   WMenu *mStyle = fContextMenu->addMenu("&Style");
00246 
00247   WMenu *mRepresentation = mStyle->addMenu("&Representation");
00248   WMenu *mProjection = mStyle->addMenu("&Projection");
00249   WAction *polyhedron = mRepresentation->addAction("Polyhedron");
00250   WAction *nurbs = mRepresentation->addAction("NURBS");
00251 
00252   WAction *ortho = mProjection->addAction("Orthographic");
00253   WAction *perspective = mProjection->addAction("Persepective");
00254 
00255   // INIT mRepresentation
00256   G4ViewParameters::RepStyle style;
00257   style = fVP.GetRepStyle();
00258   if (style == G4ViewParameters::polyhedron) {
00259     createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),1);
00260   } else if (style == G4ViewParameters::nurbs) {
00261     createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),2);
00262   } else {
00263     mRepresentation->clear();
00264   }
00265 
00266   // INIT mProjection
00267   if (fVP.GetFieldHalfAngle() == 0) {
00268     createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),1);
00269   } else {
00270     createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),2);
00271   }
00272 
00273   // === Drawing Menu ===
00274   WMenu *mDrawing = mStyle->addMenu("&Drawing");
00275 
00276   fDrawingWireframe = mDrawing->addAction("Wireframe");
00277   fDrawingWireframe->setCheckable(true);
00278 
00279   fDrawingLineRemoval = mDrawing->addAction("Hidden line removal");
00280   fDrawingLineRemoval->setCheckable(true);
00281 
00282   fDrawingSurfaceRemoval = mDrawing->addAction("Hidden Surface removal");
00283   fDrawingSurfaceRemoval->setCheckable(true);
00284 
00285   fDrawingLineSurfaceRemoval = mDrawing->addAction("Hidden line and surface removal");
00286   fDrawingLineSurfaceRemoval->setCheckable(true);
00287 
00288   // INIT Drawing
00289   G4ViewParameters::DrawingStyle d_style;
00290   d_style = fVP.GetDrawingStyle();
00291   
00292   if (d_style == G4ViewParameters::wireframe) {
00293     fDrawingWireframe->setChecked(true);
00294   } else if (d_style == G4ViewParameters::hlr) {
00295     fDrawingLineRemoval->setChecked(true);
00296   } else if (d_style == G4ViewParameters::hsr) {
00297     fDrawingSurfaceRemoval->setChecked(true);
00298   } else if (d_style == G4ViewParameters::hlhsr) {
00299     fDrawingLineSurfaceRemoval->setChecked(true);
00300   } else {
00301     mDrawing->clear();
00302   }
00303   WObject ::connect(fDrawingWireframe, 
00304                     SIGNAL(triggered(bool)),
00305                     this, 
00306                     SLOT(actionDrawingWireframe()));
00307   WObject ::connect(fDrawingLineRemoval, 
00308                     SIGNAL(triggered(bool)),
00309                     this, 
00310                     SLOT(actionDrawingLineRemoval()));
00311   WObject ::connect(fDrawingSurfaceRemoval, 
00312                     SIGNAL(triggered(bool)),
00313                     this, 
00314                     SLOT(actionDrawingSurfaceRemoval()));
00315   WObject ::connect(fDrawingLineSurfaceRemoval, 
00316                     SIGNAL(triggered(bool)),
00317                     this, 
00318                     SLOT(actionDrawingLineSurfaceRemoval()));
00319 
00320   // Background Color
00321 
00322   WAction *backgroundColorChooser ;
00323 
00324   // === Action Menu ===
00325   backgroundColorChooser = mStyle->addAction("Background color");
00326   WObject ::connect(backgroundColorChooser, 
00327                     SIGNAL(triggered()),
00328                     this,
00329                     SLOT(actionChangeBackgroundColor()));
00330 
00331   // Text Color
00332 
00333   WAction *textColorChooser ;
00334   // === Action Menu ===
00335   textColorChooser = mStyle->addAction("Text color");
00336   WObject ::connect(textColorChooser, 
00337                     SIGNAL(triggered()),
00338                     this,
00339                     SLOT(actionChangeTextColor()));
00340 
00341   // Default Color
00342 
00343   WAction *defaultColorChooser ;
00344   // === Action Menu ===
00345   defaultColorChooser = mStyle->addAction("Default color");
00346   WObject ::connect(defaultColorChooser, 
00347                     SIGNAL(triggered()),
00348                     this,
00349                     SLOT(actionChangeDefaultColor()));
00350 
00351 
00352   // === Action Menu ===
00353   WMenu *mActions = fContextMenu->addMenu("&Actions");
00354   WAction *createEPS = mActions->addAction("Save as ...");
00355   WObject ::connect(createEPS, 
00356                     SIGNAL(triggered()),
00357                     this,
00358                     SLOT(actionSaveImage()));
00359 
00360   // === Action Menu ===
00361   WAction *movieParameters = mActions->addAction("Movie parameters...");
00362   WObject ::connect(movieParameters, 
00363                     SIGNAL(triggered()),
00364                     this,
00365                     SLOT(actionMovieParameters()));
00366 
00367 
00368 
00369 
00370   // === Special Menu ===
00371   WMenu *mSpecial = fContextMenu->addMenu("S&pecial");
00372   WMenu *mTransparency = mSpecial->addMenu("Transparency");
00373   WAction *transparencyOn = mTransparency->addAction("On");
00374   WAction *transparencyOff = mTransparency->addAction("Off");
00375 
00376   if (transparency_enabled == false) {
00377     createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),2);
00378   } else if (transparency_enabled == true) {
00379     createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),1);
00380   } else {
00381     mSpecial->clear();
00382   }
00383 
00384 
00385   WMenu *mAntialiasing = mSpecial->addMenu("Antialiasing");
00386   WAction *antialiasingOn = mAntialiasing->addAction("On");
00387   WAction *antialiasingOff = mAntialiasing->addAction("Off");
00388 
00389   if (antialiasing_enabled == false) {
00390     createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),2);
00391   } else if (antialiasing_enabled == true) {
00392     createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),1);
00393   } else {
00394     mAntialiasing->clear();
00395   }
00396 
00397   WMenu *mHaloing = mSpecial->addMenu("Haloing");
00398   WAction *haloingOn = mHaloing->addAction("On");
00399   WAction *haloingOff = mHaloing->addAction("Off");
00400 
00401   if (haloing_enabled == false) {
00402     createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),2);
00403   } else if (haloing_enabled == true) {
00404     createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),1);
00405   } else {
00406     mHaloing->clear();
00407   }
00408 
00409   WMenu *mAux = mSpecial->addMenu("Auxiliary edges");
00410   WAction *auxOn = mAux->addAction("On");
00411   WAction *auxOff = mAux->addAction("Off");
00412   if (!fVP.IsAuxEdgeVisible()) {
00413     createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),1);
00414   } else {
00415     createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),2);
00416   }
00417 
00418 
00419 
00420   WMenu *mFullScreen = mSpecial->addMenu("&Full screen");
00421   fFullScreenOn = mFullScreen->addAction("On");
00422   fFullScreenOff = mFullScreen->addAction("Off");
00423   createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(bool)),2);
00424 
00425 }
00426 
00427 
00428 void G4OpenGLWtViewer::G4manageContextMenuEvent(WContextMenuEvent *e)
00429 {
00430   if (!fGLWindow) {
00431     G4cerr << "Visualization window not defined, please choose one before" << G4endl;
00432   } else {
00433   
00434     if (!fContextMenu) 
00435       createPopupMenu();
00436     
00437     // launch menu
00438     if ( fContextMenu ) {
00439       fContextMenu->exec( e->globalPos() );
00440       //    delete fContextMenu;
00441     }
00442   }
00443   e->accept();
00444 }
00445 
00446 
00455 void G4OpenGLWtViewer::createRadioAction(WAction *action1,WAction *action2, const std::string& method,unsigned int nCheck) {
00456 
00457   action1->setCheckable(true);
00458   action2->setCheckable(true);
00459 
00460   if (nCheck ==1)
00461     action1->setChecked (true);
00462   else
00463     action2->setChecked (true);
00464    
00465   WObject ::connect(action1, SIGNAL(triggered(bool)),action2, SLOT(toggle()));
00466   WObject ::connect(action2, SIGNAL(triggered(bool)),action1, SLOT(toggle()));
00467 
00468   WObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
00469 
00470 }
00471 
00475 void G4OpenGLWtViewer::actionMouseRotate() {
00476   emit toggleMouseAction(STYLE1);
00477 }
00478 
00479 
00483 void G4OpenGLWtViewer::actionMouseMove() {
00484   emit toggleMouseAction(STYLE2);
00485 }
00486 
00487 
00491 void G4OpenGLWtViewer::actionMousePick() {
00492   emit toggleMouseAction(STYLE3);
00493 }
00494 
00495 
00499 void G4OpenGLWtViewer::actionDrawingWireframe() {
00500   emit toggleDrawingAction(1);
00501 }
00502 
00506 void G4OpenGLWtViewer::actionDrawingLineRemoval() {
00507   emit toggleDrawingAction(2);
00508 }
00509 
00513 void G4OpenGLWtViewer::actionDrawingSurfaceRemoval() {
00514   emit toggleDrawingAction(3);
00515 }
00516 
00520 void G4OpenGLWtViewer::actionDrawingLineSurfaceRemoval() {
00521   emit toggleDrawingAction(4);
00522 }
00523 
00524 
00529 void G4OpenGLWtViewer::toggleMouseAction(mouseActions aAction) {
00530   
00531   if ((aAction == STYLE1) || //initialize all
00532       (aAction == STYLE2) ||
00533       (aAction == STYLE3))  {
00534     fRotateAction->setChecked (false);
00535     fMoveAction->setChecked (false);
00536     fPickAction->setChecked (false);
00537     fVP.SetPicking(false);
00538     fMouseAction = aAction;
00539   }
00540   // rotate
00541   if (aAction == STYLE1) {  // rotate
00542     showShortcuts();
00543     fRotateAction->setChecked (true);
00544   } else  if (aAction == STYLE2) { //move
00545     fMoveAction->setChecked (true);
00546   } else  if (aAction == STYLE3) { //pick
00547     fPickAction->setChecked (true);
00548     fVP.SetPicking(true);
00549   }
00550 }
00551 
00552 #endif
00553 
00556 void G4OpenGLWtViewer::showShortcuts() {
00557   G4cout << "========= Mouse Shortcuts =========" << G4endl;
00558   if (fMouseAction == STYLE1) {  // rotate
00559     G4cout << "Click and move mouse to rotate volume " << G4endl;
00560     G4cout << "ALT + Click and move mouse to rotate volume (View Direction)" << G4endl;
00561     G4cout << "CTRL + Click and zoom mouse to zoom in/out" << G4endl;
00562     G4cout << "SHIFT + Click and zoommove camera point of view" << G4endl;
00563   } else  if (fMouseAction == STYLE2) { //move
00564     G4cout << "Move camera point of view with mouse" << G4endl;
00565   } else  if (fMouseAction == STYLE3) { //pick
00566     G4cout << "Click and pick " << G4endl;
00567   }
00568   G4cout << "========= Move Shortcuts =========" << G4endl;
00569   G4cout << "Press left/right arrows to move volume left/right" << G4endl;
00570   G4cout << "Press up/down arrows to move volume up/down" << G4endl;
00571   G4cout << "Press '+'/'-' to move volume toward/forward" << G4endl;
00572   G4cout <<  G4endl;
00573   G4cout << "========= Rotation (Theta/Phi) Shortcuts =========" << G4endl;
00574   G4cout << "Press SHIFT + left/right arrows to rotate volume left/right" << G4endl;
00575   G4cout << "Press SHIFT + up/down arrows to rotate volume up/down" << G4endl;
00576   G4cout <<  G4endl;
00577   G4cout << "========= Rotation (View Direction) Shortcuts =========" << G4endl;
00578   G4cout << "Press ALT + left/right to rotate volume around vertical direction" << G4endl;
00579   G4cout << "Press ALT + up/down to rotate volume around horizontal direction" << G4endl;
00580   G4cout <<  G4endl;
00581   G4cout << "========= Zoom View =========" << G4endl;
00582   G4cout << "Press CTRL + '+'/'-' to zoom into volume" << G4endl;
00583   G4cout <<  G4endl;
00584   G4cout << "========= Misc =========" << G4endl;
00585   G4cout << "Press ALT +/- to slow/speed rotation/move" << G4endl;
00586   G4cout << "Press H to reset view" << G4endl;
00587   G4cout << "Press Esc to exit FullScreen" << G4endl;
00588   G4cout <<  G4endl;
00589   G4cout << "========= Video =========" << G4endl;
00590   G4cout << "In video mode : " << G4endl;
00591   G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
00592   G4cout << " Press RETURN to Stop video recording " << G4endl;
00593   G4cout <<  G4endl;
00594 }
00595 
00596 
00597 
00598 #ifdef _A_FINIR_FIXME
00599 
00610 void G4OpenGLWtViewer::toggleDrawingAction(int aAction) {
00611 
00612   G4ViewParameters::DrawingStyle d_style = G4ViewParameters::wireframe;
00613   
00614 
00615   // initialize
00616   if ((aAction >0) && (aAction <5)) {
00617     fDrawingWireframe->setChecked (false);
00618     fDrawingLineRemoval->setChecked (false);
00619     fDrawingSurfaceRemoval->setChecked (false);
00620     fDrawingLineSurfaceRemoval->setChecked (false);
00621   }
00622   if (aAction ==1) {
00623     fDrawingWireframe->setChecked (true);
00624 
00625     d_style = G4ViewParameters::wireframe;
00626 
00627   } else  if (aAction ==2) {
00628     fDrawingLineRemoval->setChecked (true);
00629 
00630     d_style = G4ViewParameters::hlr;
00631 
00632   } else  if (aAction ==3) {
00633     fDrawingSurfaceRemoval->setChecked (true);
00634 
00635     d_style = G4ViewParameters::hsr;
00636 
00637   } else  if (aAction ==4) {
00638     fDrawingLineSurfaceRemoval->setChecked (true);
00639     d_style = G4ViewParameters::hlhsr;
00640   }
00641   fVP.SetDrawingStyle(d_style);
00642 
00643   updateWWidget();
00644 }
00645 
00646 
00657 void G4OpenGLWtViewer::toggleRepresentation(bool check) {
00658 
00659   G4ViewParameters::RepStyle style;
00660   if (check == 1) {
00661     style = G4ViewParameters::polyhedron;
00662   } else {
00663     style = G4ViewParameters::nurbs;
00664   }
00665   fVP.SetRepStyle (style);
00666 
00667   updateWWidget();
00668 }
00669 
00680 void G4OpenGLWtViewer::toggleProjection(bool check) {
00681 
00682   if (check == 1) {
00683     G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection o");
00684   } else {
00685     G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection p");
00686   }  
00687   updateWWidget();
00688 }
00689 
00690 
00695 void G4OpenGLWtViewer::toggleTransparency(bool check) {
00696   
00697   if (check) {
00698     transparency_enabled = false;
00699   } else {
00700     transparency_enabled = true;
00701   }
00702   SetNeedKernelVisit (true);
00703   updateWWidget();
00704 }
00705 
00710 void G4OpenGLWtViewer::toggleAntialiasing(bool check) {
00711 
00712   if (!check) {
00713     antialiasing_enabled = false;
00714     glDisable (GL_LINE_SMOOTH);
00715     glDisable (GL_POLYGON_SMOOTH);
00716   } else {
00717     antialiasing_enabled = true;
00718     glEnable (GL_LINE_SMOOTH);
00719     glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
00720     glEnable (GL_POLYGON_SMOOTH);
00721     glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
00722   }
00723 
00724   updateWWidget();
00725 }
00726 
00731 //FIXME : I SEE NOTHING...
00732 void G4OpenGLWtViewer::toggleHaloing(bool check) {
00733   if (check) {
00734     haloing_enabled = false;
00735   } else {
00736     haloing_enabled = true;
00737   }
00738 
00739   updateWWidget();
00740 
00741 }
00742 
00747 void G4OpenGLWtViewer::toggleAux(bool check) {
00748   if (check) {
00749     fVP.SetAuxEdgeVisible(true);
00750   } else {
00751     fVP.SetAuxEdgeVisible(false);
00752   }
00753   SetNeedKernelVisit (true);
00754   updateWWidget();
00755 }
00756 
00760 void G4OpenGLWtViewer::toggleFullScreen(bool check) {
00761   if (check != fGLWindow->isFullScreen()) { //toggle
00762     fGLWindow->setWindowState(fGLWindow->windowState() ^ Wt::WindowFullScreen);
00763     G4cerr << "This version of Wt could not do fullScreen. Resizing the widget is the only solution available." << G4endl;
00764   }
00765 }
00766 #endif
00767 
00768 #ifdef _A_FINIR_FIXME
00769 void G4OpenGLWtViewer::savePPMToTemp() {
00770   if (fMovieTempFolderPath == "") {
00771     return;
00772   }
00773   Wt::WString fileName ="Test"+Wt::WString::number(fRecordFrameNumber)+".ppm";
00774   Wt::WString filePath =fMovieTempFolderPath+fileName;
00775 
00776   WImage image;
00777   image = fWindow->grabFrameBuffer();
00778   bool res = false;
00779   
00780   res = image.save(filePath,0);
00781   if (res == false) { 
00782     resetRecording();
00783     setRecordingInfos("Can't save tmp file "+filePath);
00784     return;
00785   }
00786   
00787   setRecordingInfos("File "+fileName+" saved");
00788   fRecordFrameNumber++;
00789 }
00790 
00791 
00792 
00793 void G4OpenGLWtViewer::actionSaveImage() {
00794   Wt::WString filters;
00795   WList<WByteArray> formats =  WImageWriter::supportedImageFormats ();
00796   for (int i = 0; i < formats.size(); ++i) {
00797     filters +=formats.at(i) + ";;";
00798   }
00799   filters += "eps;;";
00800   filters += "ps;;";
00801   filters += "pdf";
00802   Wt::WString* selectedFormat = new Wt::WString();
00803   std::string name;
00804   name =  WFileDialog::getSaveFileName ( fGLWindow,
00805                                                     tr("Save as ..."),
00806                                                     ".",
00807                                                     filters,
00808                                                     selectedFormat ).toUTF8().c_str(); 
00809   // bmp jpg jpeg png ppm xbm xpm
00810   if (name.empty()) {
00811     return;
00812   }
00813   name += "." + selectedFormat->toUTF8();
00814   Wt::WString format = selectedFormat->toLower();
00815   setPrintFilename(name.c_str(),0);
00816   G4OpenGLWtExportDialog* exportDialog= new G4OpenGLWtExportDialog(fGLWindow,format,fWindow->height(),fWindow->width());
00817   if(  exportDialog->exec()) {
00818 
00819     WImage image;
00820     bool res = false;
00821     if ((exportDialog->getWidth() !=fWindow->width()) ||
00822         (exportDialog->getHeight() !=fWindow->height())) {
00823       setPrintSize(exportDialog->getWidth(),exportDialog->getHeight());
00824       if ((format != Wt::WString("eps")) && (format != Wt::WString("ps"))) {
00825       G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
00826       
00827       //    rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
00828       //      WGLWidget* glResized = fWindow;
00829 
00830       // FIXME :
00831       // L.Garnier : I've try to implement change size function, but the problem is 
00832       // the renderPixmap function call the WGLWidget to resize and it doesn't draw
00833       // the content of this widget... It only draw the background.
00834 
00835       //      fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
00836 
00837       //      WPixmap pixmap = fWindow->renderPixmap ();
00838       
00839       //      image = pixmap->toImage();
00840       //      glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
00841       //      image = glResized->grabFrameBuffer();
00842       }      
00843     } else {
00844       image = fWindow->grabFrameBuffer();
00845     }    
00846     if (format == Wt::WString("eps")) {
00847       fVectoredPs = exportDialog->getVectorEPS();
00848       printEPS();
00849     } else if (format == "ps") {
00850       fVectoredPs = true;
00851       printEPS();
00852     } else if (format == "pdf") {
00853 
00854       res = printPDF(name,exportDialog->getNbColor(),image);
00855 
00856     } else if ((format == "tif") ||
00857                (format == "tiff") ||
00858                (format == "jpg") ||
00859                (format == "jpeg") ||
00860                (format == "png") ||
00861                (format == "pbm") ||
00862                (format == "pgm") ||
00863                (format == "ppm") ||
00864                (format == "bmp") ||
00865                (format == "xbm") ||
00866                (format == "xpm")) {
00867       res = image.save(Wt::WString(name.c_str()),0,exportDialog->getSliderValue());
00868     } else {
00869       G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
00870     }
00871     if ((format == Wt::WString("eps")) && (format == Wt::WString("ps"))) {
00872       if (res == false) {
00873         G4cerr << "Error while saving file... "<<name.c_str()<< G4endl;
00874       } else {
00875         G4cout << "File "<<name.c_str()<<" has been saved " << G4endl;
00876       }
00877     }
00878     
00879   } else { // cancel selected
00880     return;
00881   }
00882   
00883 }
00884 #endif
00885 
00886 
00887 #ifdef _A_FINIR_FIXME
00888 void G4OpenGLWtViewer::actionChangeBackgroundColor() {
00889 
00890   //   //I need to revisit the kernel if the background colour changes and
00891   //   //hidden line removal is enabled, because hlr drawing utilises the
00892   //   //background colour in its drawing...
00893   //   // (Note added by JA 13/9/2005) Background now handled in view
00894   //   // parameters.  A kernel visit is triggered on change of background.
00895 
00896   WColor color;
00897   color = WColorDialog::getColor(Wt::black, fGLWindow);
00898   if (color.isValid()) {
00899     Wt::WString com = "/vis/viewer/set/background ";
00900     Wt::WString num;
00901     com += num.setNum(((float)color.red())/256)+" ";
00902     com += num.setNum(((float)color.green())/256)+" ";
00903     com += num.setNum(((float)color.blue())/256)+" ";
00904     G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
00905     updateWWidget();
00906   }
00907 }
00908 
00909 void G4OpenGLWtViewer::actionChangeTextColor() {
00910 
00911   WColor color;
00912   color = WColorDialog::getColor(Wt::yellow, fGLWindow);
00913   if (color.isValid()) {
00914     Wt::WString com = "/vis/viewer/set/defaultTextColour ";
00915     Wt::WString num;
00916     com += num.setNum(((float)color.red())/256)+" ";
00917     com += num.setNum(((float)color.green())/256)+" ";
00918     com += num.setNum(((float)color.blue())/256)+" ";
00919     G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
00920     updateWWidget();
00921   }
00922 }
00923 
00924 void G4OpenGLWtViewer::actionChangeDefaultColor() {
00925 
00926   WColor color;
00927   color = WColorDialog::getColor(Wt::white, fGLWindow);
00928   printf("actionChangeDefaultColor\n");
00929   if (color.isValid()) {
00930     Wt::WString com = "/vis/viewer/set/defaultColour ";
00931     Wt::WString num;
00932     com += num.setNum(((float)color.red())/256)+" ";
00933     com += num.setNum(((float)color.green())/256)+" ";
00934     com += num.setNum(((float)color.blue())/256)+" ";
00935     G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
00936     updateWWidget();
00937   }
00938 }
00939 
00940 
00941 void G4OpenGLWtViewer::actionMovieParameters() {
00942   showMovieParametersDialog();
00943 }
00944 
00945 
00946 void G4OpenGLWtViewer::showMovieParametersDialog() {
00947   if (!fMovieParametersDialog) {
00948     fMovieParametersDialog= new G4OpenGLWtMovieDialog(this,fGLWindow);
00949     displayRecordingStatus();
00950     fMovieParametersDialog->checkEncoderSwParameters();
00951     fMovieParametersDialog->checkSaveFileNameParameters();
00952     fMovieParametersDialog->checkTempFolderParameters();
00953     if (getEncoderPath() == "") {
00954       setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
00955     }
00956   }
00957   fMovieParametersDialog->show();
00958 }
00959 #endif
00960 
00961 /*
00962 // 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
00963 
00964 void Graph::exportToSVG(const Wt::WString& fname)
00965 {
00966   // enable workaround for Wt3 misalignments
00967   WwtPainter::setSVGMode(true);
00968   WPicture picture;
00969   WPainter p(&picture);
00970   d_plot->print(&p, d_plot->rect());
00971   p.end();
00972 
00973   picture.save(fname, "svg");
00974 }
00975 */
00976 
00977 
00978 
00979 void G4OpenGLWtViewer::FinishView()
00980 {
00981   glFlush ();
00982 
00983   // L. Garnier 10/2009 : Not necessary and cause problems on mac OS X 10.6
00984   //  fWindow->swapBuffers ();
00985 }
00986 
00991 void G4OpenGLWtViewer::G4MousePressEvent(Wt::WMouseEvent *event)
00992 {
00993     if (event->button() & Wt::WMouseEvent::LeftButton) {
00994 #ifdef _A_FINIR_FIXME
00995     fWindow->setMouseTracking(true);
00996 #endif
00997     fAutoMove = false; // stop automove
00998     fLastPos1 = Wt::WPoint(event->widget().x,event->widget().y);
00999     fLastPos2 = fLastPos1;
01000     fLastPos3 = fLastPos2;
01001     fLastEventTime->start();
01002     if (fMouseAction == STYLE3){  // pick
01003       Pick(event->widget().x,event->widget().y);
01004     }
01005   }
01006 }
01007 
01010 void G4OpenGLWtViewer::G4MouseReleaseEvent()
01011 {
01012   fSpinningDelay = fLastEventTime->elapsed();
01013   Wt::WPoint delta = Wt::WPoint(fLastPos3.x()-fLastPos1.x(),fLastPos3.y()-fLastPos1.y());
01014   if ((delta.x() == 0) && (delta.y() == 0)) {
01015     return;
01016   }
01017   if (fSpinningDelay < fLaunchSpinDelay ) {
01018     fAutoMove = true;
01019     Wt::WTime lastMoveTime;
01020     lastMoveTime.start();
01021     // try to addapt speed move/rotate looking to drawing speed
01022     float correctionFactor = 5;
01023     while (fAutoMove) {
01024       if ( lastMoveTime.elapsed () >= (int)(1000/fNbMaxFramesPerSec)) {
01025         float lTime = 1000/((float)lastMoveTime.elapsed ());
01026         if (((((float)delta.x())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
01027             ((((float)delta.x())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
01028           correctionFactor = (float)delta.x()*(lTime/fNbMaxAnglePerSec);
01029           if (delta.x() <0 ) {
01030             correctionFactor = -correctionFactor;
01031           }
01032         }
01033         if (((((float)delta.y())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
01034             ((((float)delta.y())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
01035           correctionFactor = (float)delta.y()*(lTime/fNbMaxAnglePerSec);
01036           if (delta.y() <0 ) {
01037             correctionFactor = -correctionFactor;
01038           }
01039         }
01040                 
01041         // Check Wt Versions for META Keys
01042                 
01043         // Click and move mouse to rotate volume
01044         // ALT + Click and move mouse to rotate volume (View Direction)
01045         // SHIFT + Click and move camera point of view
01046         // CTRL + Click and zoom mouse to zoom in/out
01047 
01048         if (fMouseAction == STYLE1) {  // rotate
01049           if (fNoKeyPress) {
01050             rotateWtScene(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
01051           } else if (fAltKeyPress) {
01052             rotateWtSceneInViewDirection(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
01053           }
01054           
01055         } else if (fMouseAction == STYLE2) {  // move
01056           moveScene(-((float)delta.x())/correctionFactor,-((float)delta.y())/correctionFactor,0,true);
01057         }
01058         lastMoveTime.start();
01059       }
01060 #ifdef _A_FINIR_FIXME
01061       ((Wt::WApplication*)G4Wt::getInstance ())->processEvents();
01062 #endif
01063     }
01064   }
01065 #ifdef _A_FINIR_FIXME
01066   fWindow->setMouseTracking(false);
01067 #endif
01068 }
01069 
01070 
01071 void G4OpenGLWtViewer::G4MouseDoubleClickEvent()
01072 {
01073 #ifdef _A_FINIR_FIXME
01074   fWindow->setMouseTracking(true);
01075 #endif
01076 }
01077 
01078 
01086  void G4OpenGLWtViewer::G4MouseMoveEvent(Wt::WMouseEvent *event)
01087 {
01088   
01089   Wt::WMouseEvent::Button mButtons = event->button();
01090 
01091 #ifdef _A_FINIR_FIXME
01092   updateKeyModifierState(event->modifiers());
01093 #endif
01094 
01095   if (fAutoMove) {
01096     return;
01097   }
01098 
01099   fLastPos3 = fLastPos2;
01100   fLastPos2 = fLastPos1;
01101   fLastPos1 = Wt::WPoint(event->widget().x, event->widget().y);
01102 
01103   int deltaX = fLastPos2.x()-fLastPos1.x();
01104   int deltaY = fLastPos2.y()-fLastPos1.y();
01105 
01106   if (fMouseAction == STYLE1) {  // rotate
01107     if (mButtons & Wt::WMouseEvent::LeftButton) {
01108       if (fNoKeyPress) {
01109         rotateWtScene(((float)deltaX),((float)deltaY));
01110       } else if (fAltKeyPress) {
01111         rotateWtSceneInViewDirection(((float)deltaX),((float)deltaY));
01112       } else if (fShiftKeyPress) {
01113         unsigned int sizeWin;
01114         sizeWin = getWinWidth();
01115         if (getWinHeight() < getWinWidth()) {
01116           sizeWin = getWinHeight();
01117         }
01118 
01119         // L.Garnier : 08/2010 100 is the good value, but don't ask me why !
01120         float factor = ((float)100/(float)sizeWin) ;
01121         moveScene(-(float)deltaX*factor,-(float)deltaY*factor,0,false);
01122       } else if (fControlKeyPress) {
01123         fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+((float)deltaY))); 
01124       }
01125     }
01126   } else if (fMouseAction == STYLE2) {  // move
01127     if (mButtons & Wt::WMouseEvent::LeftButton) {
01128       moveScene(-deltaX,-deltaY,0,true);
01129     }
01130   }
01131 
01132   fLastEventTime->start();
01133 }
01134 
01135 
01143 void G4OpenGLWtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
01144 {
01145   if (fHoldMoveEvent)
01146     return;
01147   fHoldMoveEvent = true;
01148 
01149   G4double coefTrans = 0;
01150   GLdouble coefDepth = 0;
01151   if(mouseMove) {
01152     coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinWidth());
01153     if (getWinHeight() <getWinWidth()) {
01154       coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
01155     }
01156   } else {
01157     coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
01158     coefDepth = getSceneDepth()*fDeltaDepth;
01159   }
01160   fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
01161   updateWWidget();
01162   if (fAutoMove)
01163 #ifdef _A_FINIR_FIXME
01164     ((WApplication*)G4Wt::getInstance ())->processEvents();
01165 #endif
01166   
01167   fHoldMoveEvent = false;
01168 }
01169 
01170 
01176 void G4OpenGLWtViewer::rotateWtScene(float dx, float dy)
01177 {
01178   if (fHoldRotateEvent)
01179     return;
01180   fHoldRotateEvent = true;
01181   
01182   if( dx != 0) {
01183     rotateScene(dx,0);
01184   }
01185   if( dy != 0) {
01186     rotateScene(0,dy);
01187   }
01188   updateWWidget();
01189   
01190   fHoldRotateEvent = false;
01191 }
01192 
01198 void G4OpenGLWtViewer::rotateWtSceneInViewDirection(float dx, float dy)
01199 {
01200   if (fHoldRotateEvent)
01201     return;
01202   fHoldRotateEvent = true;
01203   
01204   fXRot +=dx;
01205   fYRot +=dy;
01206   
01207   rotateSceneInViewDirection(dx/100,dy/100);
01208   
01209   updateWWidget();
01210   
01211   fHoldRotateEvent = false;
01212 }
01213 
01219 void G4OpenGLWtViewer::rotateWtCamera(float dx, float dy)
01220 {
01221   if (fHoldRotateEvent)
01222     return;
01223   fHoldRotateEvent = true;
01224 
01225   rotateScene(dx,dy);
01226   updateWWidget();
01227   
01228   fHoldRotateEvent = false;
01229 }
01230 
01236 void G4OpenGLWtViewer::rotateWtCameraInViewDirection(float dx, float dy)
01237 {
01238   if (fHoldRotateEvent)
01239     return;
01240   fHoldRotateEvent = true;
01241 
01242   fVP.SetUpVector(G4Vector3D(0.0, 1.0, 0.0));
01243   fVP.SetViewAndLights (G4Vector3D(0.0, 0.0, 1.0));
01244 
01245 
01246   fXRot +=dx;
01247   fYRot +=dy;
01248 
01249   rotateSceneInViewDirection(fXRot/100,fYRot/100);
01250 
01251   updateWWidget();
01252   
01253   fHoldRotateEvent = false;
01254 }
01255 
01256 
01257 
01258 
01259 
01264 void G4OpenGLWtViewer::rescaleImage(
01265  int /* aWidth */
01266 ,int /* aHeight */
01267 ){
01268   //  GLfloat* feedback_buffer;
01269   //  GLint returned;
01270   //  FILE* file;
01271   
01272 //   feedback_buffer = new GLfloat[size];
01273 //   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
01274 //   glRenderMode (GL_FEEDBACK);
01275   
01276 //   DrawView();
01277 //   returned = glRenderMode (GL_RENDER);
01278 
01279 }
01280 
01281 
01282 
01283 #ifdef _A_FINIR_FIXME
01284 
01290 bool G4OpenGLWtViewer::printPDF (
01291  const std::string aFilename
01292 ,int aInColor
01293 ,WImage aImage
01294 )
01295 {
01296 
01297   WPrinter printer;
01298   //  printer.setPageSize(pageSize);
01299 
01300   // FIXME : L. Garnier 4/12/07
01301   // This is not working, it does nothing. Image is staying in color mode
01302   // So I have desactivate the B/W button in GUI
01303   if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
01304     aImage = aImage.convertToFormat ( aImage.format(), Wt::MonoOnly);
01305   }
01306 
01307 
01308   if (aFilename.substr(aFilename.size()-3) == ".ps") {
01309 #if WT_VERSION > 0x040200
01310     printer.setOutputFormat(WPrinter::PostScriptFormat);
01311 #endif
01312   } else {
01313 #if WT_VERSION > 0x040100
01314     printer.setOutputFormat(WPrinter::PdfFormat);
01315 #endif
01316   }
01317 #if WT_VERSION > 0x040100
01318   printer.setOutputFileName(Wt::WString(aFilename.c_str()));
01319 #endif
01320   //  printer.setFullPage ( true);
01321   WPainter paint(&printer);
01322   paint.drawImage (0,0,aImage);
01323   paint.end();
01324   return true;
01325 }
01326 
01327 
01328 
01329 void G4OpenGLWtViewer::G4wheelEvent (Wt::WWheelEvent * event) 
01330 {
01331   fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200)); 
01332   updateWWidget();
01333 }
01334 #endif
01335 
01336  void G4OpenGLWtViewer::G4keyPressEvent (Wt::WKeyEvent * event) 
01337 {
01338   if (fHoldKeyEvent)
01339     return;
01340 
01341   fHoldKeyEvent = true;
01342 
01343   
01344   // with no modifiers
01345 #ifdef _A_FINIR_FIXME
01346   updateKeyModifierState(event->modifiers());
01347 #endif
01348   if ((fNoKeyPress)) { // || (event->modifiers() == Wt::KeyboardModifier )) {
01349     if (event->key() == Wt::Key_Down) { // go down
01350       moveScene(0,1,0,false);
01351     }
01352     else if (event->key() == Wt::Key_Up) {  // go up
01353       moveScene(0,-1,0,false);
01354     }
01355     if (event->key() == Wt::Key_Left) { // go left
01356       moveScene(-1,0,0,false);
01357     }
01358     else if (event->key() == Wt::Key_Right) { // go right
01359       moveScene(1,0,0,false);
01360     }
01361     if (event->text() == Wt::WString("-") ) { // go backward
01362       moveScene(0,0,1,false);
01363     }
01364     else if (event->text() == Wt::WString("+")) { // go forward
01365       moveScene(0,0,-1,false);
01366     }
01367 
01368     // escaped from full screen
01369     if (event->key() == Wt::Key_Escape) {
01370 #ifdef _A_FINIR_FIXME
01371       toggleFullScreen(false);
01372 #endif
01373     }
01374   }    
01375   // several case here : If return is pressed, in every case -> display the movie parameters dialog
01376   // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
01377   // If encoder not found-> does nothing.Only display a message in status box
01378   // If all ok-> generate parameter file
01379   // If ok -> put encoder button enabled
01380   
01381 #ifdef _A_FINIR_FIXME
01382   if ( (event->key() == Wt::Key_Enter)){ // end of video
01383     stopVideo();
01384   }
01385   if (event->key() == Wt::Key_Space){ // start/pause of video
01386     startPauseVideo();
01387   }
01388 #endif
01389   
01390   // H : Return Home view
01391   if (event->key() == Wt::Key_H){ // go Home
01392     fDeltaRotation = 1;
01393     fDeltaSceneTranslation = 0.01;
01394     fDeltaDepth = 0.01;
01395     fDeltaZoom = 0.05;
01396     fDeltaMove = 0.05;
01397     
01398     fVP.SetZoomFactor(1.);
01399     fVP.SetUpVector(G4Vector3D (0., 1., 0.));
01400     fVP.SetViewAndLights (G4Vector3D (0., 0., 1.));
01401 
01402     updateWWidget();
01403   }
01404 
01405   // Shift Modifier
01406   if (fShiftKeyPress) {
01407     if (event->key() == Wt::Key_Down) { // rotate phi
01408       rotateWtScene(0,-fDeltaRotation);
01409     }
01410     else if (event->key() == Wt::Key_Up) { // rotate phi
01411       rotateWtScene(0,fDeltaRotation);
01412     }
01413     if (event->key() == Wt::Key_Left) { // rotate theta
01414       rotateWtScene(fDeltaRotation,0);
01415     }
01416     else if (event->key() == Wt::Key_Right) { // rotate theta
01417       rotateWtScene(-fDeltaRotation,0);
01418     }
01419 
01420   // Alt Modifier
01421   }
01422   if ((fAltKeyPress)) {
01423     if (event->key() == Wt::Key_Down) { // rotate phi
01424       rotateWtSceneInViewDirection(0,-fDeltaRotation);
01425     }
01426     else if (event->key() == Wt::Key_Up) { // rotate phi
01427       rotateWtSceneInViewDirection(0,fDeltaRotation);
01428     }
01429     if (event->key() == Wt::Key_Left) { // rotate theta
01430       rotateWtSceneInViewDirection(fDeltaRotation,0);
01431     }
01432     else if (event->key() == Wt::Key_Right) { // rotate theta
01433       rotateWtSceneInViewDirection(-fDeltaRotation,0);
01434     }
01435 
01436     // Rotatio +/-
01437     if (event->text() == Wt::WString("+")) {
01438       fDeltaRotation = fDeltaRotation/0.7;
01439       G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
01440     }
01441     else if (event->text() == Wt::WString("-")) {
01442       fDeltaRotation = fDeltaRotation*0.7;
01443       G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
01444     }
01445 
01446   // Control Modifier OR Command on MAC
01447   }
01448   if ((fControlKeyPress)) {
01449     if (event->text() == Wt::WString("+")) {
01450       fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom)); 
01451       updateWWidget();
01452     }
01453     else if (event->text() == Wt::WString("-")) {
01454       fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom)); 
01455       updateWWidget();
01456     }
01457   }  
01458   
01459   fHoldKeyEvent = false;
01460 }
01461   
01462 
01463 #ifdef _A_FINIR_FIXME
01464 void  G4OpenGLWtViewer::updateKeyModifierState(Wt::KeyboardModifiers modifier) {
01465   // Check Wt Versions for META Keys
01466     
01467   fNoKeyPress = true;
01468   fAltKeyPress = false;
01469   fShiftKeyPress = false;
01470   fControlKeyPress = false;
01471   
01472   if (modifier & Wt::AltModifier ) {
01473     fAltKeyPress = true;
01474     fNoKeyPress = false;
01475   }
01476   if (modifier & Wt::ShiftModifier ) {
01477     fShiftKeyPress = true;
01478     fNoKeyPress = false;
01479   }
01480   if (modifier & Wt::ControlModifier ) {
01481     fControlKeyPress = true;
01482     fNoKeyPress = false;
01483   }
01484 }
01485 
01488 void G4OpenGLWtViewer::stopVideo() {
01489 
01490  // if encoder parameter is wrong, display parameters dialog and return
01491   if (!fMovieParametersDialog) {
01492     showMovieParametersDialog();
01493   }
01494   setRecordingStatus(STOP);
01495 
01496   if (fRecordFrameNumber >0) {
01497     // check parameters if they were modified (Re APPLY them...)
01498     if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
01499       setRecordingStatus(BAD_ENCODER);
01500     }  else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
01501       setRecordingStatus(BAD_OUTPUT);
01502     }
01503   } else {
01504     resetRecording();
01505     setRecordingInfos("No frame to encode.");
01506   }
01507 }
01508 
01511 void G4OpenGLWtViewer::saveVideo() {
01512 
01513   // if encoder parameter is wrong, display parameters dialog and return
01514   if (!fMovieParametersDialog) {
01515     showMovieParametersDialog();
01516   }
01517 
01518   fMovieParametersDialog->checkEncoderSwParameters();
01519   fMovieParametersDialog->checkSaveFileNameParameters();
01520   
01521   if (fRecordingStep == STOP) {
01522     setRecordingStatus(SAVE);
01523     generateMpegEncoderParameters();
01524     encodeVideo();
01525   }
01526 }
01527 
01528 
01531 void G4OpenGLWtViewer::startPauseVideo() {
01532    
01533   // first time, if temp parameter is wrong, display parameters dialog and return
01534 
01535   if (( fRecordingStep == WAIT)) {
01536     if ( fRecordFrameNumber == 0) {
01537       if (getTempFolderPath() == "") { // BAD_OUTPUT
01538         showMovieParametersDialog();
01539         setRecordingInfos("You should specified the temp folder in order to make movie");
01540         return;
01541       } else  {
01542         // remove temp folder if it was create
01543         Wt::WString tmp = removeTempFolder();
01544         if (tmp !="") {
01545           setRecordingInfos(tmp);
01546           return;
01547         }
01548         tmp = createTempFolder();
01549         if (tmp != "") {
01550           setRecordingInfos("Can't create temp folder."+tmp);
01551           return;
01552         }
01553       }
01554     }
01555   }
01556   if ((fRecordingStep == WAIT)) {
01557     setRecordingStatus(START); 
01558   } else if (fRecordingStep == START) {
01559     setRecordingStatus(PAUSE);
01560   } else if (fRecordingStep == PAUSE) {
01561     setRecordingStatus(CONTINUE);
01562   } else if (fRecordingStep == CONTINUE) {
01563     setRecordingStatus(PAUSE);
01564   }
01565 }
01566 
01567 void G4OpenGLWtViewer::setRecordingStatus(RECORDING_STEP step) {
01568 
01569   fRecordingStep = step;
01570   displayRecordingStatus();
01571 }
01572 
01573 
01574 void G4OpenGLWtViewer::displayRecordingStatus() {
01575   
01576   Wt::WString txtStatus = "";
01577   if (fRecordingStep == WAIT) {
01578     txtStatus  = "Waiting to start...";
01579     fRecordFrameNumber = 0; // reset the frame number
01580   } else if (fRecordingStep == START) {
01581     txtStatus  = "Start Recording...";
01582   } else if (fRecordingStep == PAUSE) {
01583     txtStatus  = "Pause Recording...";
01584   } else if (fRecordingStep == CONTINUE) {
01585     txtStatus  = "Continue Recording...";
01586   } else if (fRecordingStep == STOP) {
01587     txtStatus  = "Stop Recording...";
01588   } else if (fRecordingStep == READY_TO_ENCODE) {
01589     txtStatus  = "Ready to Encode...";
01590   } else if (fRecordingStep == ENCODING) {
01591     txtStatus  = "Encoding...";
01592   } else if (fRecordingStep == FAILED) {
01593     txtStatus  = "Failed to encode...";
01594   } else if ((fRecordingStep == BAD_ENCODER)
01595          || (fRecordingStep == BAD_OUTPUT)
01596              || (fRecordingStep == BAD_TMP)) {
01597     txtStatus  = "Correct above errors first";
01598   } else if (fRecordingStep == SUCCESS) {
01599     txtStatus  = "File encoded successfully";
01600   } else {
01601   }
01602 
01603   if (fMovieParametersDialog) {
01604     fMovieParametersDialog->setRecordingStatus(txtStatus);
01605   } else {
01606     G4cout << txtStatus.toUTF8().c_str() << G4endl;
01607   }
01608   setRecordingInfos("");
01609 }
01610 
01611 
01612 void G4OpenGLWtViewer::setRecordingInfos(Wt::WString txt) {
01613   if (fMovieParametersDialog) {
01614     fMovieParametersDialog->setRecordingInfos(txt);
01615   } else {
01616     G4cout << txt.toUTF8().c_str() << G4endl;
01617   }
01618 }
01619 
01622 void G4OpenGLWtViewer::initMovieParameters() {
01623   //init encoder
01624   
01625    //look for encoderPath
01626      fProcess = new WProcess();
01627      
01628      WObject ::connect(fProcess,SIGNAL(finished ( int)),
01629                        this,SLOT(processLookForFinished()));
01630      fProcess->setReadChannelMode(WProcess::MergedChannels);
01631      fProcess->start ("which mpeg_encode");
01632   
01633 }
01634 
01637 Wt::WString G4OpenGLWtViewer::getEncoderPath() {
01638   return fEncoderPath;
01639 }
01640  
01641 
01646 Wt::WString G4OpenGLWtViewer::setEncoderPath(Wt::WString path) {
01647   if (path == "") {
01648     return "File does not exist";
01649   }
01650 
01651   path =  WDir::cleanPath(path);
01652   WFileInfo *f = new WFileInfo(path);
01653   if (!f->exists()) {
01654     return "File does not exist";
01655   } else if (f->isDir()) {
01656     return "This is a directory";
01657   } else if (!f->isExecutable()) {
01658     return "File exist but is not executable";
01659   } else if (!f->isFile()) {
01660     return "This is not a file";
01661   }
01662   fEncoderPath = path;
01663 
01664   if ((fRecordingStep == BAD_ENCODER)) {
01665     setRecordingStatus(STOP);
01666   } 
01667   return "";
01668 }
01669 
01670 
01671 bool G4OpenGLWtViewer::isRecording(){
01672   if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
01673     return true;
01674   }
01675   return false;
01676 }
01677 
01678 bool G4OpenGLWtViewer::isPaused(){
01679   if (fRecordingStep == PAUSE) {
01680     return true;
01681   }
01682   return false;
01683 }
01684 
01685 bool G4OpenGLWtViewer::isEncoding(){
01686   if (fRecordingStep == ENCODING) {
01687     return true;
01688   }
01689   return false;
01690 }
01691 
01692 bool G4OpenGLWtViewer::isWaiting(){
01693   if (fRecordingStep == WAIT) {
01694     return true;
01695   }
01696   return false;
01697 }
01698 
01699 bool G4OpenGLWtViewer::isStopped(){
01700   if (fRecordingStep == STOP) {
01701     return true;
01702   }
01703   return false;
01704 }
01705 
01706 bool G4OpenGLWtViewer::isFailed(){
01707   if (fRecordingStep == FAILED) {
01708     return true;
01709   }
01710   return false;
01711 }
01712 
01713 bool G4OpenGLWtViewer::isSuccess(){
01714   if (fRecordingStep == SUCCESS) {
01715     return true;
01716   }
01717   return false;
01718 }
01719 
01720 bool G4OpenGLWtViewer::isBadEncoder(){
01721   if (fRecordingStep == BAD_ENCODER) {
01722     return true;
01723   }
01724   return false;
01725 }
01726 bool G4OpenGLWtViewer::isBadTmp(){
01727   if (fRecordingStep == BAD_TMP) {
01728     return true;
01729   }
01730   return false;
01731 }
01732 bool G4OpenGLWtViewer::isBadOutput(){
01733   if (fRecordingStep == BAD_OUTPUT) {
01734     return true;
01735   }
01736   return false;
01737 }
01738 
01739 void G4OpenGLWtViewer::setBadEncoder(){
01740   fRecordingStep = BAD_ENCODER;
01741   displayRecordingStatus();
01742 }
01743 void G4OpenGLWtViewer::setBadTmp(){
01744   fRecordingStep = BAD_TMP;
01745   displayRecordingStatus();
01746 }
01747 void G4OpenGLWtViewer::setBadOutput(){
01748   fRecordingStep = BAD_OUTPUT;
01749   displayRecordingStatus();
01750 }
01751 
01752 void G4OpenGLWtViewer::setWaiting(){
01753   fRecordingStep = WAIT;
01754   displayRecordingStatus();
01755 }
01756 
01757 
01758 bool G4OpenGLWtViewer::isReadyToEncode(){
01759   if (fRecordingStep == READY_TO_ENCODE) {
01760     return true;
01761   }
01762   return false;
01763 }
01764 
01765 void G4OpenGLWtViewer::resetRecording() {
01766     setRecordingStatus(WAIT);
01767 }
01768 
01773 Wt::WString G4OpenGLWtViewer::setTempFolderPath(Wt::WString path) {
01774 
01775   if (path == "") {
01776     return "Path does not exist";
01777   }
01778   path =  WDir::cleanPath(path);
01779   WFileInfo *d = new WFileInfo(path);
01780   if (!d->exists()) {
01781     return "Path does not exist";
01782   } else if (!d->isDir()) {
01783     return "This is not a directory";
01784   } else if (!d->isReadable()) {
01785     return path +" is read protected";
01786   } else if (!d->isWritable()) {
01787     return path +" is write protected";
01788   }
01789   
01790   if ((fRecordingStep == BAD_TMP)) {
01791     setRecordingStatus(WAIT); 
01792   }
01793   fTempFolderPath = path;
01794   return "";
01795 }
01796 
01799 Wt::WString G4OpenGLWtViewer::getTempFolderPath() {
01800   return fTempFolderPath;
01801 }
01802  
01807 Wt::WString G4OpenGLWtViewer::setSaveFileName(Wt::WString path) {
01808 
01809   if (path == "") {
01810     return "Path does not exist";
01811   }
01812   
01813   WFileInfo *file = new WFileInfo(path);
01814   WDir dir = file->dir();
01815   path =  WDir::cleanPath(path);
01816   if (file->exists()) {
01817     return "File already exist, please choose a new one";
01818   } else if (!dir.exists()) {
01819     return "Dir does not exist";
01820   } else if (!dir.isReadable()) {
01821     return path +" is read protected";
01822   }
01823   
01824   if ((fRecordingStep == BAD_OUTPUT)) {
01825     setRecordingStatus(STOP); 
01826   }
01827   fSaveFileName = path;
01828   return "";
01829 }
01830 
01833 Wt::WString G4OpenGLWtViewer::getSaveFileName() {
01834   return fSaveFileName ;
01835 }
01836 
01841 Wt::WString G4OpenGLWtViewer::createTempFolder() {
01842   fMovieTempFolderPath = "";
01843   //check
01844   Wt::WString tmp = setTempFolderPath(fTempFolderPath);
01845   if (tmp != "") {
01846     return tmp;
01847   }
01848   Wt::WString sep = Wt::WString(WDir::separator());
01849   Wt::WString path = sep+"WtMovie_"+WDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep; 
01850   WDir *d = new WDir(WDir::cleanPath(fTempFolderPath));
01851   // check if it is already present
01852   if (d->exists(path)) {
01853     return "Folder "+path+" already exists.Please remove it first";
01854   }
01855   if (d->mkdir(fTempFolderPath+path)) {
01856     fMovieTempFolderPath = fTempFolderPath+path;
01857     return "";
01858   } else {
01859     return "Can't create "+fTempFolderPath+path;
01860   }
01861   return "-";
01862 }
01863 
01866 Wt::WString G4OpenGLWtViewer::removeTempFolder() {
01867         // remove files in Wt_temp folder
01868   if (fMovieTempFolderPath == "") {
01869     return "";
01870   }
01871   WDir *d = new WDir(WDir::cleanPath(fMovieTempFolderPath));
01872   if (!d->exists()) {
01873     return "";  // already remove
01874   }
01875 
01876   d->setFilter( WDir::Files );
01877   Wt::WStringList subDirList = d->entryList();
01878   int res = true;
01879   Wt::WString error = "";
01880   for (Wt::WStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
01881     const Wt::WString currentFile = *it;
01882       if (!d->remove(currentFile)) {
01883         res = false;
01884         Wt::WString file = fMovieTempFolderPath+currentFile;
01885         error +="Removing file failed : "+file;
01886       } else {
01887       }
01888   }
01889   if (res) {
01890     if (d->rmdir(fMovieTempFolderPath)) {
01891       fMovieTempFolderPath = "";
01892       return "";
01893     } else {
01894       return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
01895     }
01896 
01897   }
01898   return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
01899 }
01900 
01901 
01902 
01903 bool G4OpenGLWtViewer::hasPendingEvents () {
01904 #ifdef _A_FINIR_FIXME
01905   return ((WApplication*)G4Wt::getInstance ())->hasPendingEvents ();
01906 #endif
01907   return false;
01908 }
01909 
01910 bool G4OpenGLWtViewer::generateMpegEncoderParameters () {
01911 
01912                 // save the parameter file
01913   FILE* fp;
01914   fp = fopen (Wt::WString(fMovieTempFolderPath+fParameterFileName).toUTF8().c_str(), "w");
01915 
01916   if (fp == NULL) {
01917     setRecordingInfos("Generation of parameter file failed");
01918     return false;
01919   }
01920 
01921   fprintf (fp,"# parameter file template with lots of comments to assist you\n");
01922   fprintf (fp,"#\n");
01923   fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
01924   fprintf (fp,"# the copy\n");
01925   fprintf (fp,"#\n");
01926   fprintf (fp,"#\n");
01927   fprintf (fp,"# any line beginning with '#' is a comment\n");
01928   fprintf (fp,"#\n");
01929   fprintf (fp,"# no line should be longer than 255 characters\n");
01930   fprintf (fp,"#\n");
01931   fprintf (fp,"#\n");
01932   fprintf (fp,"# general format of each line is:\n");
01933   fprintf (fp,"#          \n");
01934   fprintf (fp,"#\n");
01935   fprintf (fp,"# lines can generally be in any order\n");
01936   fprintf (fp,"#\n");
01937   fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
01938   fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
01939   fprintf (fp,"#\n");
01940   fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
01941   fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
01942   fprintf (fp,"# the INPUT parameter.\n");
01943   fprintf (fp,"#\n");
01944   fprintf (fp,"#  MUST be in UPPER CASE\n");
01945   fprintf (fp,"#\n");
01946   fprintf (fp,"\n");
01947   fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
01948   fprintf (fp,"# for more info.\n");
01949   fprintf (fp,"\n");
01950   fprintf (fp,"PATTERN          IBBPBBPBBPBBPBBP\n");
01951   fprintf (fp,"OUTPUT           %s\n",getSaveFileName().toUTF8().c_str());
01952   fprintf (fp,"\n");
01953   fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
01954   fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
01955   fprintf (fp,"#\n");
01956   fprintf (fp,"# You must specify the type of the input files.  The choices are:\n");
01957   fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
01958   fprintf (fp,"#        (must be upper case)\n");
01959   fprintf (fp,"#\n");
01960   fprintf (fp,"BASE_FILE_FORMAT PPM\n");
01961   fprintf (fp,"\n");
01962   fprintf (fp,"#\n");
01963   fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
01964   fprintf (fp,"# YUV_SIZE       widthxheight\n");
01965   fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
01966   fprintf (fp,"# on just one machine\n");
01967   fprintf (fp,"#\n");
01968   fprintf (fp,"YUV_SIZE 352x240\n");
01969   fprintf (fp,"\n");
01970   fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
01971   fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
01972   fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
01973   fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
01974   fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
01975   fprintf (fp,"# to specify the file order.\n");
01976   fprintf (fp,"\n");
01977   fprintf (fp,"INPUT_FORMAT UCB\n");
01978   fprintf (fp,"\n");
01979   fprintf (fp,"# the conversion statement\n");
01980   fprintf (fp,"#\n");
01981   fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
01982   fprintf (fp,"#\n");
01983   fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
01984   fprintf (fp,"#        INPUT_CONVERT   giftoppm *\n");
01985   fprintf (fp,"#\n");
01986   fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
01987   fprintf (fp,"#        INPUT_CONVERT   cat *.Y *.U *.V\n");
01988   fprintf (fp,"#\n");
01989   fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
01990   fprintf (fp,"#        INPUT_CONVERT   goto frame *; grabppm\n");
01991   fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
01992   fprintf (fp,"#\n");
01993   fprintf (fp,"INPUT_CONVERT    * \n");
01994   fprintf (fp,"\n");
01995   fprintf (fp,"# number of frames in a GOP.\n");
01996   fprintf (fp,"#\n");
01997   fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
01998   fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
01999   fprintf (fp,"#\n");
02000   fprintf (fp,"# later, will add more flexible GOP signalling\n");
02001   fprintf (fp,"#\n");
02002   fprintf (fp,"GOP_SIZE 16\n");
02003   fprintf (fp,"\n");
02004   fprintf (fp,"# number of slices in a frame\n");
02005   fprintf (fp,"#\n");
02006   fprintf (fp,"# 1 is a good number.  another possibility is the number of macroblock rows\n");
02007   fprintf (fp,"# (which is the height divided by 16)\n");
02008   fprintf (fp,"#\n");
02009   fprintf (fp,"SLICES_PER_FRAME 1\n");
02010   fprintf (fp,"\n");
02011   fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
02012   fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.toUTF8().c_str());
02013   fprintf (fp,"\n");
02014   fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
02015   fprintf (fp,"# from a simple one-per-line listing, to the following \n");
02016   fprintf (fp,"# way of numbering them.  See the manual for more information.\n");
02017   fprintf (fp,"INPUT\n");
02018   fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
02019   fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
02020   fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
02021   fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
02022   fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
02023   fprintf (fp,"# if you do, too bad!!!\n");
02024   fprintf (fp,"#\n");
02025   fprintf (fp,"#\n");
02026   fprintf (fp,"Test*.ppm        [0-%d]\n",fRecordFrameNumber-1);
02027   fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
02028   fprintf (fp,"# of files\n");
02029   fprintf (fp,"END_INPUT\n");
02030   fprintf (fp,"\n");
02031   fprintf (fp,"\n");
02032   fprintf (fp,"\n");
02033   fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
02034   fprintf (fp,"\n");
02035   fprintf (fp,"# FULL or HALF -- must be upper case\n");
02036   fprintf (fp,"# Should be FULL for computer generated images\n");
02037   fprintf (fp,"PIXEL            FULL\n");
02038   fprintf (fp,"\n");
02039   fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
02040   fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
02041   fprintf (fp,"RANGE            10\n");
02042   fprintf (fp,"\n");
02043   fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
02044   fprintf (fp,"# with some affect on compression and almost none on quality.\n");
02045   fprintf (fp,"\n");
02046   fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
02047   fprintf (fp,"PSEARCH_ALG      LOGARITHMIC\n");
02048   fprintf (fp,"\n");
02049   fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
02050   fprintf (fp,"#\n");
02051   fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
02052   fprintf (fp,"#\n");
02053   fprintf (fp,"BSEARCH_ALG      SIMPLE\n");
02054   fprintf (fp,"\n");
02055   fprintf (fp,"#\n");
02056   fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
02057   fprintf (fp,"# (values must be between 1 and 31)\n");
02058   fprintf (fp,"# These are the Wscale values for the entire frame in variable bit-rate\n");
02059   fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
02060   fprintf (fp,"#\n");
02061   fprintf (fp,"\n");
02062   fprintf (fp,"# Wscale (Wuantization scale) affects quality and compression,\n");
02063   fprintf (fp,"# but has very little effect on speed.\n");
02064   fprintf (fp,"\n");
02065   fprintf (fp,"IWSCALE          4\n");
02066   fprintf (fp,"PWSCALE          5\n");
02067   fprintf (fp,"BWSCALE          12\n");
02068   fprintf (fp,"\n");
02069   fprintf (fp,"# this must be ORIGINAL or DECODED\n");
02070   fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");
02071   fprintf (fp,"\n");
02072   fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
02073   fprintf (fp,"\n");
02074   fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
02075   fprintf (fp,"#BIT_RATE  1000000\n");
02076   fprintf (fp,"\n");
02077   fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
02078   fprintf (fp,"BUFFER_SIZE 327680\n");
02079   fprintf (fp,"\n");
02080   fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
02081   fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
02082   fprintf (fp,"FRAME_RATE 30\n");
02083   fprintf (fp,"\n");
02084   fprintf (fp,"# There are many more options, see the users manual for examples....\n");
02085   fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IWTABLE, etc.\n");
02086   fprintf (fp,"\n");
02087   fprintf (fp,"\n");
02088   fclose (fp);
02089 
02090   setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
02091   setRecordingStatus(READY_TO_ENCODE);
02092   return true;
02093 }
02094 
02095 void G4OpenGLWtViewer::encodeVideo()
02096 {
02097   if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
02098     setRecordingStatus(ENCODING);
02099     
02100     fProcess = new WProcess();
02101     WObject ::connect(fProcess,SIGNAL(finished ( int)),
02102                       this,SLOT(processEncodeFinished()));
02103     WObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
02104                       this,SLOT(processEncodeStdout()));
02105     fProcess->setReadChannelMode(WProcess::MergedChannels);
02106     fProcess->start (fEncoderPath, Wt::WStringList(fMovieTempFolderPath+fParameterFileName));
02107   }
02108 }
02109 
02110 
02111 // FIXME : does not work on Wt3
02112 void G4OpenGLWtViewer::processEncodeStdout()
02113 {
02114   Wt::WString tmp = fProcess->readStdout ().data();
02115   int start = tmp.findRev("ESTIMATED TIME");
02116   tmp = tmp.mid(start,tmp.find("\n",start)-start);
02117   setRecordingInfos(tmp);
02118 }
02119 
02120 
02121 void G4OpenGLWtViewer::processEncodeFinished()
02122 {
02123 
02124   Wt::WString txt = "";
02125   txt = getProcessErrorMsg();
02126   if (txt == "") {
02127     setRecordingStatus(SUCCESS);
02128   } else {
02129     setRecordingStatus(FAILED);
02130   }
02131   //  setRecordingInfos(txt+removeTempFolder());
02132 }
02133 
02134 
02135 void G4OpenGLWtViewer::processLookForFinished() 
02136  {
02137 
02138   Wt::WString txt = getProcessErrorMsg();
02139   if (txt != "") {
02140     fEncoderPath = "";
02141   } else {
02142     fEncoderPath = Wt::WString(fProcess->readAllStandardOutput ().data()).trimmed();
02143     // if not found, return "not found"
02144     if (fEncoderPath.contains(" ")) {
02145       fEncoderPath = "";
02146     } else if (!fEncoderPath.contains("mpeg_encode")) {
02147       fEncoderPath = "";
02148     }
02149     setEncoderPath(fEncoderPath);
02150   }
02151   // init temp folder
02152   setTempFolderPath(WDir::temp ().absolutePath ());
02153 }
02154 
02155 
02156 Wt::WString G4OpenGLWtViewer::getProcessErrorMsg()
02157 {
02158   Wt::WString txt = "";
02159   if (fProcess->exitCode() != 0) {
02160     switch (fProcess->error()) {
02161     case WProcess::FailedToStart:
02162       txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
02163       break;
02164     case WProcess::Crashed:
02165       txt = "The process crashed some time after starting successfully.\n";
02166       break;
02167     case WProcess::Timedout:
02168       txt = "The last waitFor...() function timed out. The state of WProcess is unchanged, and you can try calling waitFor...() again.\n";
02169       break;
02170     case WProcess::WriteError:
02171       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";
02172       break;
02173     case WProcess::ReadError:
02174       txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
02175       break;
02176     case WProcess::UnknownError:
02177       txt = "An unknown error occurred. This is the default return value of error().\n";
02178       break;
02179     }
02180   }
02181    return txt;
02182 }
02183 #endif
02184 
02185 
02186 
02187 /*
02188   
02189 void MultiLayer::exportToSVG(const Wt::WString& fname)
02190 {
02191   WPicture picture;
02192   WPainter p(&picture);
02193   for (int i=0;i<(int)graphsList->count();i++)
02194     {
02195       Graph *gr=(Graph *)graphsList->at(i);
02196       Plot *myPlot= (Plot *)gr->plotWidget();
02197       
02198       Wt::WPoint pos=gr->pos();
02199       
02200       int width=int(myPlot->frameGeometry().width());
02201       int height=int(myPlot->frameGeometry().height());
02202       
02203       myPlot->print(&p, WRect(pos,WSize(width,height)));
02204     }
02205   
02206   p.end();
02207   picture.save(fname, "svg");
02208 }
02209 */
02210 #endif

Generated on Mon May 27 17:49:11 2013 for Geant4 by  doxygen 1.4.7