35#ifdef G4VIS_BUILD_OPENGLWT_DRIVER
57#include <WT/WHBoxLayout>
58#include <WT/WApplication>
67void G4OpenGLWtViewer::SetView (
72 G4OpenGLViewer::SetView ();
79void G4OpenGLWtViewer::CreateMainWindow (
80 Wt::WGLWidget* glWidget
87 printf(
"G4OpenGLWtViewer::CreateMainWindow \n");
97 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY());
129G4OpenGLWtViewer::G4OpenGLWtViewer (
130 G4OpenGLSceneHandler& scene
133 ,G4OpenGLViewer (scene)
135 ,fRecordFrameNumber(0)
137 ,fMouseAction(STYLE1)
139 ,fDeltaSceneTranslation(0.01)
143 ,fHoldKeyEvent(false)
144 ,fHoldMoveEvent(false)
145 ,fHoldRotateEvent(false)
149 ,fMovieTempFolderPath(
"")
151 ,fParameterFileName(
"mpeg_encode_parameter_file.par")
152 ,fMovieParametersDialog(NULL)
153 ,fRecordingStep(WAIT)
155 ,fNbMaxFramesPerSec(100)
156 ,fNbMaxAnglePerSec(360)
157 ,fLaunchSpinDelay(100)
162 ,fControlKeyPress(false)
163 ,fShiftKeyPress(false)
167 G4Wt::getInstance ();
169#ifdef G4DEBUG_VIS_OGL
170 printf(
"G4OpenGLWtViewer::Create \n");
172 fLastPos3 = Wt::WPoint(-1,-1);
173 fLastPos2 = Wt::WPoint(-1,-1);
174 fLastPos1 = Wt::WPoint(-1,-1);
177 initMovieParameters();
180 fLastEventTime =
new Wt::WTime();
182#ifdef G4DEBUG_VIS_OGL
183 printf(
"G4OpenGLWtViewer::G4OpenGLWtViewer END\n");
188G4OpenGLWtViewer::~G4OpenGLWtViewer (
203void G4OpenGLWtViewer::createPopupMenu() {
205 fContextMenu =
new WMenu(
"All");
207 WMenu *mMouseAction = fContextMenu->addMenu(
"&Mouse actions");
209 fRotateAction = mMouseAction->addAction(
"Rotate");
210 fMoveAction = mMouseAction->addAction(
"Move");
211 fPickAction = mMouseAction->addAction(
"Pick");
212 WAction *shortcutsAction = mMouseAction->addAction(
"Show shortcuts");
214 fRotateAction->setCheckable(
true);
215 fMoveAction->setCheckable(
false);
216 fPickAction->setCheckable(
false);
217 shortcutsAction->setCheckable(
false);
219 fRotateAction->setChecked(
true);
220 fMoveAction->setChecked(
false);
221 fPickAction->setChecked(
false);
222 shortcutsAction->setChecked(
false);
224 WObject ::connect(fRotateAction,
225 SIGNAL(triggered(
bool)),
227 SLOT(actionMouseRotate()));
229 WObject ::connect(fMoveAction,
230 SIGNAL(triggered(
bool)),
232 SLOT(actionMouseMove()));
234 WObject ::connect(fPickAction,
235 SIGNAL(triggered(
bool)),
237 SLOT(actionMousePick()));
239 WObject ::connect(shortcutsAction,
240 SIGNAL(triggered(
bool)),
242 SLOT(showShortcuts()));
245 WMenu *mStyle = fContextMenu->addMenu(
"&Style");
247 WMenu *mRepresentation = mStyle->addMenu(
"&Representation");
248 WMenu *mProjection = mStyle->addMenu(
"&Projection");
249 WAction *polyhedron = mRepresentation->addAction(
"Polyhedron");
250 WAction *nurbs = mRepresentation->addAction(
"NURBS");
252 WAction *ortho = mProjection->addAction(
"Orthographic");
253 WAction *perspective = mProjection->addAction(
"Persepective");
257 style = fVP.GetRepStyle();
259 createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(
bool)),1);
261 createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(
bool)),2);
263 mRepresentation->clear();
267 if (fVP.GetFieldHalfAngle() == 0) {
268 createRadioAction(ortho, perspective,SLOT(toggleProjection(
bool)),1);
270 createRadioAction(ortho, perspective,SLOT(toggleProjection(
bool)),2);
274 WMenu *mDrawing = mStyle->addMenu(
"&Drawing");
276 fDrawingWireframe = mDrawing->addAction(
"Wireframe");
277 fDrawingWireframe->setCheckable(
true);
279 fDrawingLineRemoval = mDrawing->addAction(
"Hidden line removal");
280 fDrawingLineRemoval->setCheckable(
true);
282 fDrawingSurfaceRemoval = mDrawing->addAction(
"Hidden Surface removal");
283 fDrawingSurfaceRemoval->setCheckable(
true);
285 fDrawingLineSurfaceRemoval = mDrawing->addAction(
"Hidden line and surface removal");
286 fDrawingLineSurfaceRemoval->setCheckable(
true);
290 d_style = fVP.GetDrawingStyle();
293 fDrawingWireframe->setChecked(
true);
295 fDrawingLineRemoval->setChecked(
true);
297 fDrawingSurfaceRemoval->setChecked(
true);
299 fDrawingLineSurfaceRemoval->setChecked(
true);
303 WObject ::connect(fDrawingWireframe,
304 SIGNAL(triggered(
bool)),
306 SLOT(actionDrawingWireframe()));
307 WObject ::connect(fDrawingLineRemoval,
308 SIGNAL(triggered(
bool)),
310 SLOT(actionDrawingLineRemoval()));
311 WObject ::connect(fDrawingSurfaceRemoval,
312 SIGNAL(triggered(
bool)),
314 SLOT(actionDrawingSurfaceRemoval()));
315 WObject ::connect(fDrawingLineSurfaceRemoval,
316 SIGNAL(triggered(
bool)),
318 SLOT(actionDrawingLineSurfaceRemoval()));
322 WAction *backgroundColorChooser ;
325 backgroundColorChooser = mStyle->addAction(
"Background color");
326 WObject ::connect(backgroundColorChooser,
329 SLOT(actionChangeBackgroundColor()));
333 WAction *textColorChooser ;
335 textColorChooser = mStyle->addAction(
"Text color");
336 WObject ::connect(textColorChooser,
339 SLOT(actionChangeTextColor()));
343 WAction *defaultColorChooser ;
345 defaultColorChooser = mStyle->addAction(
"Default color");
346 WObject ::connect(defaultColorChooser,
349 SLOT(actionChangeDefaultColor()));
353 WMenu *mActions = fContextMenu->addMenu(
"&Actions");
354 WAction *createEPS = mActions->addAction(
"Save as ...");
355 WObject ::connect(createEPS,
358 SLOT(actionSaveImage()));
361 WAction *movieParameters = mActions->addAction(
"Movie parameters...");
362 WObject ::connect(movieParameters,
365 SLOT(actionMovieParameters()));
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");
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);
385 WMenu *mAntialiasing = mSpecial->addMenu(
"Antialiasing");
386 WAction *antialiasingOn = mAntialiasing->addAction(
"On");
387 WAction *antialiasingOff = mAntialiasing->addAction(
"Off");
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);
394 mAntialiasing->clear();
397 WMenu *mHaloing = mSpecial->addMenu(
"Haloing");
398 WAction *haloingOn = mHaloing->addAction(
"On");
399 WAction *haloingOff = mHaloing->addAction(
"Off");
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);
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);
415 createRadioAction(auxOn,auxOff,SLOT(toggleAux(
bool)),2);
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);
428void G4OpenGLWtViewer::G4manageContextMenuEvent(WContextMenuEvent *e)
431 G4cerr <<
"Visualization window not defined, please choose one before" <<
G4endl;
438 if ( fContextMenu ) {
439 fContextMenu->exec( e->globalPos() );
455void G4OpenGLWtViewer::createRadioAction(WAction *action1,WAction *action2,
const std::string& method,
unsigned int nCheck) {
457 action1->setCheckable(
true);
458 action2->setCheckable(
true);
461 action1->setChecked (
true);
463 action2->setChecked (
true);
465 WObject ::connect(action1, SIGNAL(triggered(
bool)),action2, SLOT(toggle()));
466 WObject ::connect(action2, SIGNAL(triggered(
bool)),action1, SLOT(toggle()));
468 WObject ::connect(action1, SIGNAL(toggled(
bool)),
this, method.c_str());
475void G4OpenGLWtViewer::actionMouseRotate() {
476 emit toggleMouseAction(STYLE1);
483void G4OpenGLWtViewer::actionMouseMove() {
484 emit toggleMouseAction(STYLE2);
491void G4OpenGLWtViewer::actionMousePick() {
492 emit toggleMouseAction(STYLE3);
499void G4OpenGLWtViewer::actionDrawingWireframe() {
500 emit toggleDrawingAction(1);
506void G4OpenGLWtViewer::actionDrawingLineRemoval() {
507 emit toggleDrawingAction(2);
513void G4OpenGLWtViewer::actionDrawingSurfaceRemoval() {
514 emit toggleDrawingAction(3);
520void G4OpenGLWtViewer::actionDrawingLineSurfaceRemoval() {
521 emit toggleDrawingAction(4);
529void G4OpenGLWtViewer::toggleMouseAction(mouseActions aAction) {
531 if ((aAction == STYLE1) ||
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;
541 if (aAction == STYLE1) {
543 fRotateAction->setChecked (
true);
544 }
else if (aAction == STYLE2) {
545 fMoveAction->setChecked (
true);
546 }
else if (aAction == STYLE3) {
547 fPickAction->setChecked (
true);
548 fVP.SetPicking(
true);
556void G4OpenGLWtViewer::showShortcuts() {
557 G4cout <<
"========= Mouse Shortcuts =========" <<
G4endl;
558 if (fMouseAction == STYLE1) {
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) {
564 G4cout <<
"Move camera point of view with mouse" <<
G4endl;
565 }
else if (fMouseAction == STYLE3) {
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;
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;
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;
582 G4cout <<
"Press CTRL + '+'/'-' to zoom into volume" <<
G4endl;
585 G4cout <<
"Press ALT +/- to slow/speed rotation/move" <<
G4endl;
591 G4cout <<
" Press SPACE to Start/Pause video recording " <<
G4endl;
592 G4cout <<
" Press RETURN to Stop video recording " <<
G4endl;
610void G4OpenGLWtViewer::toggleDrawingAction(
int aAction) {
616 if ((aAction >0) && (aAction <5)) {
617 fDrawingWireframe->setChecked (
false);
618 fDrawingLineRemoval->setChecked (
false);
619 fDrawingSurfaceRemoval->setChecked (
false);
620 fDrawingLineSurfaceRemoval->setChecked (
false);
623 fDrawingWireframe->setChecked (
true);
627 }
else if (aAction ==2) {
628 fDrawingLineRemoval->setChecked (
true);
632 }
else if (aAction ==3) {
633 fDrawingSurfaceRemoval->setChecked (
true);
637 }
else if (aAction ==4) {
638 fDrawingLineSurfaceRemoval->setChecked (
true);
641 fVP.SetDrawingStyle(d_style);
657void G4OpenGLWtViewer::toggleRepresentation(
bool check) {
665 fVP.SetRepStyle (style);
680void G4OpenGLWtViewer::toggleProjection(
bool check) {
695void G4OpenGLWtViewer::toggleTransparency(
bool check) {
698 transparency_enabled =
false;
700 transparency_enabled =
true;
702 SetNeedKernelVisit (
true);
710void G4OpenGLWtViewer::toggleAntialiasing(
bool check) {
713 antialiasing_enabled =
false;
714 glDisable (GL_LINE_SMOOTH);
715 glDisable (GL_POLYGON_SMOOTH);
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);
732void G4OpenGLWtViewer::toggleHaloing(
bool check) {
734 haloing_enabled =
false;
736 haloing_enabled =
true;
747void G4OpenGLWtViewer::toggleAux(
bool check) {
749 fVP.SetAuxEdgeVisible(
true);
751 fVP.SetAuxEdgeVisible(
false);
753 SetNeedKernelVisit (
true);
760void G4OpenGLWtViewer::toggleFullScreen(
bool check) {
761 if (check != fGLWindow->isFullScreen()) {
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;
769void G4OpenGLWtViewer::savePPMToTemp() {
770 if (fMovieTempFolderPath ==
"") {
773 Wt::WString fileName =
"Test"+Wt::WString::number(fRecordFrameNumber)+
".ppm";
774 Wt::WString filePath =fMovieTempFolderPath+fileName;
777 image = fWindow->grabFrameBuffer();
780 res = image.save(filePath,0);
783 setRecordingInfos(
"Can't save tmp file "+filePath);
787 setRecordingInfos(
"File "+fileName+
" saved");
788 fRecordFrameNumber++;
793void G4OpenGLWtViewer::actionSaveImage() {
795 WList<WByteArray> formats = WImageWriter::supportedImageFormats ();
796 for (
int i = 0; i < formats.size(); ++i) {
797 filters +=formats.at(i) +
";;";
802 Wt::WString* selectedFormat =
new Wt::WString();
804 name = WFileDialog::getSaveFileName ( fGLWindow,
808 selectedFormat ).toUTF8().c_str();
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()) {
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;
844 image = fWindow->grabFrameBuffer();
846 if (format == Wt::WString(
"eps")) {
847 fVectoredPs = exportDialog->getVectorEPS();
849 }
else if (format ==
"ps") {
852 }
else if (format ==
"pdf") {
854 res = printPDF(name,exportDialog->getNbColor(),image);
856 }
else if ((format ==
"tif") ||
857 (format ==
"tiff") ||
859 (format ==
"jpeg") ||
867 res = image.save(Wt::WString(name.c_str()),0,exportDialog->getSliderValue());
869 G4cerr <<
"This version of G4UI Could not generate the selected format" <<
G4endl;
871 if ((format == Wt::WString(
"eps")) && (format == Wt::WString(
"ps"))) {
873 G4cerr <<
"Error while saving file... "<<name.c_str()<<
G4endl;
875 G4cout <<
"File "<<name.c_str()<<
" has been saved " <<
G4endl;
888void G4OpenGLWtViewer::actionChangeBackgroundColor() {
897 color = WColorDialog::getColor(Wt::black, fGLWindow);
898 if (color.isValid()) {
899 Wt::WString com =
"/vis/viewer/set/background ";
901 com += num.setNum(((
float)color.red())/256)+
" ";
902 com += num.setNum(((
float)color.green())/256)+
" ";
903 com += num.setNum(((
float)color.blue())/256)+
" ";
909void G4OpenGLWtViewer::actionChangeTextColor() {
912 color = WColorDialog::getColor(Wt::yellow, fGLWindow);
913 if (color.isValid()) {
914 Wt::WString com =
"/vis/viewer/set/defaultTextColour ";
916 com += num.setNum(((
float)color.red())/256)+
" ";
917 com += num.setNum(((
float)color.green())/256)+
" ";
918 com += num.setNum(((
float)color.blue())/256)+
" ";
924void G4OpenGLWtViewer::actionChangeDefaultColor() {
927 color = WColorDialog::getColor(Wt::white, fGLWindow);
928 printf(
"actionChangeDefaultColor\n");
929 if (color.isValid()) {
930 Wt::WString com =
"/vis/viewer/set/defaultColour ";
932 com += num.setNum(((
float)color.red())/256)+
" ";
933 com += num.setNum(((
float)color.green())/256)+
" ";
934 com += num.setNum(((
float)color.blue())/256)+
" ";
941void G4OpenGLWtViewer::actionMovieParameters() {
942 showMovieParametersDialog();
946void 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/");
957 fMovieParametersDialog->show();
979void G4OpenGLWtViewer::FinishView()
991void G4OpenGLWtViewer::G4MousePressEvent(Wt::WMouseEvent *event)
993 if (event->button() & Wt::WMouseEvent::LeftButton) {
995 fWindow->setMouseTracking(
true);
998 fLastPos1 = Wt::WPoint(event->widget().x,event->widget().y);
999 fLastPos2 = fLastPos1;
1000 fLastPos3 = fLastPos2;
1001 fLastEventTime->start();
1002 if (fMouseAction == STYLE3){
1003 Pick(event->widget().x,event->widget().y);
1010void G4OpenGLWtViewer::G4MouseReleaseEvent()
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)) {
1017 if (fSpinningDelay < fLaunchSpinDelay ) {
1019 Wt::WTime lastMoveTime;
1020 lastMoveTime.start();
1022 float correctionFactor = 5;
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;
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;
1048 if (fMouseAction == STYLE1) {
1050 rotateWtScene(((
float)delta.x())/correctionFactor,((
float)delta.y())/correctionFactor);
1051 }
else if (fAltKeyPress) {
1052 rotateWtSceneInViewDirection(((
float)delta.x())/correctionFactor,((
float)delta.y())/correctionFactor);
1055 }
else if (fMouseAction == STYLE2) {
1056 moveScene(-((
float)delta.x())/correctionFactor,-((
float)delta.y())/correctionFactor,0,
true);
1058 lastMoveTime.start();
1060#ifdef _A_FINIR_FIXME
1061 ((Wt::WApplication*)G4Wt::getInstance ())->processEvents();
1065#ifdef _A_FINIR_FIXME
1066 fWindow->setMouseTracking(
false);
1071void G4OpenGLWtViewer::G4MouseDoubleClickEvent()
1073#ifdef _A_FINIR_FIXME
1074 fWindow->setMouseTracking(
true);
1086 void G4OpenGLWtViewer::G4MouseMoveEvent(Wt::WMouseEvent *event)
1089 Wt::WMouseEvent::Button mButtons =
event->button();
1091#ifdef _A_FINIR_FIXME
1092 updateKeyModifierState(event->modifiers());
1099 fLastPos3 = fLastPos2;
1100 fLastPos2 = fLastPos1;
1101 fLastPos1 = Wt::WPoint(event->widget().x, event->widget().y);
1103 int deltaX = fLastPos2.x()-fLastPos1.x();
1104 int deltaY = fLastPos2.y()-fLastPos1.y();
1106 if (fMouseAction == STYLE1) {
1107 if (mButtons & Wt::WMouseEvent::LeftButton) {
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();
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)));
1126 }
else if (fMouseAction == STYLE2) {
1127 if (mButtons & Wt::WMouseEvent::LeftButton) {
1128 moveScene(-deltaX,-deltaY,0,
true);
1132 fLastEventTime->start();
1143void G4OpenGLWtViewer::moveScene(
float dx,
float dy,
float dz,
bool mouseMove)
1147 fHoldMoveEvent =
true;
1150 GLdouble coefDepth = 0;
1153 if (getWinHeight() <getWinWidth()) {
1157 coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1158 coefDepth = getSceneDepth()*fDeltaDepth;
1160 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1163#ifdef _A_FINIR_FIXME
1164 ((WApplication*)G4Wt::getInstance ())->processEvents();
1167 fHoldMoveEvent =
false;
1176void G4OpenGLWtViewer::rotateWtScene(
float dx,
float dy)
1178 if (fHoldRotateEvent)
1180 fHoldRotateEvent =
true;
1190 fHoldRotateEvent =
false;
1198void G4OpenGLWtViewer::rotateWtSceneInViewDirection(
float dx,
float dy)
1200 if (fHoldRotateEvent)
1202 fHoldRotateEvent =
true;
1207 rotateSceneInViewDirection(dx/100,dy/100);
1211 fHoldRotateEvent =
false;
1219void G4OpenGLWtViewer::rotateWtCamera(
float dx,
float dy)
1221 if (fHoldRotateEvent)
1223 fHoldRotateEvent =
true;
1228 fHoldRotateEvent =
false;
1236void G4OpenGLWtViewer::rotateWtCameraInViewDirection(
float dx,
float dy)
1238 if (fHoldRotateEvent)
1240 fHoldRotateEvent =
true;
1243 fVP.SetViewAndLights (
G4Vector3D(0.0, 0.0, 1.0));
1249 rotateSceneInViewDirection(fXRot/100,fYRot/100);
1253 fHoldRotateEvent =
false;
1264void G4OpenGLWtViewer::rescaleImage(
1283#ifdef _A_FINIR_FIXME
1290bool G4OpenGLWtViewer::printPDF (
1291 const std::string aFilename
1303 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1304 aImage = aImage.convertToFormat ( aImage.format(), Wt::MonoOnly);
1308 if (aFilename.substr(aFilename.size()-3) ==
".ps") {
1309#if WT_VERSION > 0x040200
1310 printer.setOutputFormat(WPrinter::PostScriptFormat);
1313#if WT_VERSION > 0x040100
1314 printer.setOutputFormat(WPrinter::PdfFormat);
1317#if WT_VERSION > 0x040100
1318 printer.setOutputFileName(Wt::WString(aFilename.c_str()));
1321 WPainter paint(&printer);
1322 paint.drawImage (0,0,aImage);
1329void G4OpenGLWtViewer::G4wheelEvent (Wt::WWheelEvent * event)
1331 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1336 void G4OpenGLWtViewer::G4keyPressEvent (Wt::WKeyEvent * event)
1341 fHoldKeyEvent =
true;
1345#ifdef _A_FINIR_FIXME
1346 updateKeyModifierState(event->modifiers());
1348 if ((fNoKeyPress)) {
1349 if (event->key() == Wt::Key_Down) {
1350 moveScene(0,1,0,
false);
1352 else if (event->key() == Wt::Key_Up) {
1353 moveScene(0,-1,0,
false);
1355 if (event->key() == Wt::Key_Left) {
1356 moveScene(-1,0,0,
false);
1358 else if (event->key() == Wt::Key_Right) {
1359 moveScene(1,0,0,
false);
1361 if (event->text() == Wt::WString(
"-") ) {
1362 moveScene(0,0,1,
false);
1364 else if (event->text() == Wt::WString(
"+")) {
1365 moveScene(0,0,-1,
false);
1369 if (event->key() == Wt::Key_Escape) {
1370#ifdef _A_FINIR_FIXME
1371 toggleFullScreen(
false);
1381#ifdef _A_FINIR_FIXME
1382 if ( (event->key() == Wt::Key_Enter)){
1385 if (event->key() == Wt::Key_Space){
1391 if (event->key() == Wt::Key_H){
1393 fDeltaSceneTranslation = 0.01;
1398 fVP.SetZoomFactor(1.);
1400 fVP.SetViewAndLights (
G4Vector3D (0., 0., 1.));
1406 if (fShiftKeyPress) {
1407 if (event->key() == Wt::Key_Down) {
1408 rotateWtScene(0,-fDeltaRotation);
1410 else if (event->key() == Wt::Key_Up) {
1411 rotateWtScene(0,fDeltaRotation);
1413 if (event->key() == Wt::Key_Left) {
1414 rotateWtScene(fDeltaRotation,0);
1416 else if (event->key() == Wt::Key_Right) {
1417 rotateWtScene(-fDeltaRotation,0);
1422 if ((fAltKeyPress)) {
1423 if (event->key() == Wt::Key_Down) {
1424 rotateWtSceneInViewDirection(0,-fDeltaRotation);
1426 else if (event->key() == Wt::Key_Up) {
1427 rotateWtSceneInViewDirection(0,fDeltaRotation);
1429 if (event->key() == Wt::Key_Left) {
1430 rotateWtSceneInViewDirection(fDeltaRotation,0);
1432 else if (event->key() == Wt::Key_Right) {
1433 rotateWtSceneInViewDirection(-fDeltaRotation,0);
1437 if (event->text() == Wt::WString(
"+")) {
1438 fDeltaRotation = fDeltaRotation/0.7;
1439 G4cout <<
"Auto-rotation set to : " << fDeltaRotation <<
G4endl;
1441 else if (event->text() == Wt::WString(
"-")) {
1442 fDeltaRotation = fDeltaRotation*0.7;
1443 G4cout <<
"Auto-rotation set to : " << fDeltaRotation <<
G4endl;
1448 if ((fControlKeyPress)) {
1449 if (event->text() == Wt::WString(
"+")) {
1450 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1453 else if (event->text() == Wt::WString(
"-")) {
1454 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1459 fHoldKeyEvent =
false;
1463#ifdef _A_FINIR_FIXME
1464void G4OpenGLWtViewer::updateKeyModifierState(Wt::KeyboardModifiers modifier) {
1468 fAltKeyPress =
false;
1469 fShiftKeyPress =
false;
1470 fControlKeyPress =
false;
1472 if (modifier & Wt::AltModifier ) {
1473 fAltKeyPress =
true;
1474 fNoKeyPress =
false;
1476 if (modifier & Wt::ShiftModifier ) {
1477 fShiftKeyPress =
true;
1478 fNoKeyPress =
false;
1480 if (modifier & Wt::ControlModifier ) {
1481 fControlKeyPress =
true;
1482 fNoKeyPress =
false;
1488void G4OpenGLWtViewer::stopVideo() {
1491 if (!fMovieParametersDialog) {
1492 showMovieParametersDialog();
1494 setRecordingStatus(STOP);
1496 if (fRecordFrameNumber >0) {
1498 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1499 setRecordingStatus(BAD_ENCODER);
1500 }
else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1501 setRecordingStatus(BAD_OUTPUT);
1505 setRecordingInfos(
"No frame to encode.");
1511void G4OpenGLWtViewer::saveVideo() {
1514 if (!fMovieParametersDialog) {
1515 showMovieParametersDialog();
1518 fMovieParametersDialog->checkEncoderSwParameters();
1519 fMovieParametersDialog->checkSaveFileNameParameters();
1521 if (fRecordingStep == STOP) {
1522 setRecordingStatus(SAVE);
1523 generateMpegEncoderParameters();
1531void G4OpenGLWtViewer::startPauseVideo() {
1535 if (( fRecordingStep == WAIT)) {
1536 if ( fRecordFrameNumber == 0) {
1537 if (getTempFolderPath() ==
"") {
1538 showMovieParametersDialog();
1539 setRecordingInfos(
"You should specified the temp folder in order to make movie");
1543 Wt::WString tmp = removeTempFolder();
1545 setRecordingInfos(tmp);
1548 tmp = createTempFolder();
1550 setRecordingInfos(
"Can't create temp folder."+tmp);
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);
1567void G4OpenGLWtViewer::setRecordingStatus(RECORDING_STEP step) {
1569 fRecordingStep = step;
1570 displayRecordingStatus();
1574void G4OpenGLWtViewer::displayRecordingStatus() {
1576 Wt::WString txtStatus =
"";
1577 if (fRecordingStep == WAIT) {
1578 txtStatus =
"Waiting to start...";
1579 fRecordFrameNumber = 0;
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";
1603 if (fMovieParametersDialog) {
1604 fMovieParametersDialog->setRecordingStatus(txtStatus);
1608 setRecordingInfos(
"");
1612void G4OpenGLWtViewer::setRecordingInfos(Wt::WString txt) {
1613 if (fMovieParametersDialog) {
1614 fMovieParametersDialog->setRecordingInfos(txt);
1622void G4OpenGLWtViewer::initMovieParameters() {
1626 fProcess =
new WProcess();
1628 WObject ::connect(fProcess,SIGNAL(finished (
int)),
1629 this,SLOT(processLookForFinished()));
1630 fProcess->setReadChannelMode(WProcess::MergedChannels);
1631 fProcess->start (
"which mpeg_encode");
1637Wt::WString G4OpenGLWtViewer::getEncoderPath() {
1638 return fEncoderPath;
1646Wt::WString G4OpenGLWtViewer::setEncoderPath(Wt::WString path) {
1648 return "File does not exist";
1651 path = WDir::cleanPath(path);
1652 WFileInfo *f =
new WFileInfo(path);
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";
1662 fEncoderPath = path;
1664 if ((fRecordingStep == BAD_ENCODER)) {
1665 setRecordingStatus(STOP);
1671bool G4OpenGLWtViewer::isRecording(){
1672 if ((fRecordingStep ==
START) || (fRecordingStep == CONTINUE)) {
1678bool G4OpenGLWtViewer::isPaused(){
1679 if (fRecordingStep == PAUSE) {
1685bool G4OpenGLWtViewer::isEncoding(){
1692bool G4OpenGLWtViewer::isWaiting(){
1693 if (fRecordingStep == WAIT) {
1699bool G4OpenGLWtViewer::isStopped(){
1700 if (fRecordingStep == STOP) {
1706bool G4OpenGLWtViewer::isFailed(){
1707 if (fRecordingStep == FAILED) {
1713bool G4OpenGLWtViewer::isSuccess(){
1714 if (fRecordingStep == SUCCESS) {
1720bool G4OpenGLWtViewer::isBadEncoder(){
1721 if (fRecordingStep == BAD_ENCODER) {
1726bool G4OpenGLWtViewer::isBadTmp(){
1727 if (fRecordingStep == BAD_TMP) {
1732bool G4OpenGLWtViewer::isBadOutput(){
1733 if (fRecordingStep == BAD_OUTPUT) {
1739void G4OpenGLWtViewer::setBadEncoder(){
1740 fRecordingStep = BAD_ENCODER;
1741 displayRecordingStatus();
1743void G4OpenGLWtViewer::setBadTmp(){
1744 fRecordingStep = BAD_TMP;
1745 displayRecordingStatus();
1747void G4OpenGLWtViewer::setBadOutput(){
1748 fRecordingStep = BAD_OUTPUT;
1749 displayRecordingStatus();
1752void G4OpenGLWtViewer::setWaiting(){
1753 fRecordingStep = WAIT;
1754 displayRecordingStatus();
1758bool G4OpenGLWtViewer::isReadyToEncode(){
1759 if (fRecordingStep == READY_TO_ENCODE) {
1765void G4OpenGLWtViewer::resetRecording() {
1766 setRecordingStatus(WAIT);
1773Wt::WString G4OpenGLWtViewer::setTempFolderPath(Wt::WString path) {
1776 return "Path does not exist";
1778 path = WDir::cleanPath(path);
1779 WFileInfo *d =
new WFileInfo(path);
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";
1790 if ((fRecordingStep == BAD_TMP)) {
1791 setRecordingStatus(WAIT);
1793 fTempFolderPath = path;
1799Wt::WString G4OpenGLWtViewer::getTempFolderPath() {
1800 return fTempFolderPath;
1807Wt::WString G4OpenGLWtViewer::setSaveFileName(Wt::WString path) {
1810 return "Path does not exist";
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";
1824 if ((fRecordingStep == BAD_OUTPUT)) {
1825 setRecordingStatus(STOP);
1827 fSaveFileName = path;
1833Wt::WString G4OpenGLWtViewer::getSaveFileName() {
1834 return fSaveFileName ;
1841Wt::WString G4OpenGLWtViewer::createTempFolder() {
1842 fMovieTempFolderPath =
"";
1844 Wt::WString tmp = setTempFolderPath(fTempFolderPath);
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));
1852 if (d->exists(path)) {
1853 return "Folder "+path+
" already exists.Please remove it first";
1855 if (d->mkdir(fTempFolderPath+path)) {
1856 fMovieTempFolderPath = fTempFolderPath+path;
1859 return "Can't create "+fTempFolderPath+path;
1866Wt::WString G4OpenGLWtViewer::removeTempFolder() {
1868 if (fMovieTempFolderPath ==
"") {
1871 WDir *d =
new WDir(WDir::cleanPath(fMovieTempFolderPath));
1876 d->setFilter( WDir::Files );
1877 Wt::WStringList subDirList = d->entryList();
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)) {
1884 Wt::WString file = fMovieTempFolderPath+currentFile;
1885 error +=
"Removing file failed : "+file;
1890 if (d->rmdir(fMovieTempFolderPath)) {
1891 fMovieTempFolderPath =
"";
1894 return "Dir "+fMovieTempFolderPath+
" should be empty, but could not remove it";
1898 return "Could not remove "+fMovieTempFolderPath+
" because of the following errors :"+error;
1903bool G4OpenGLWtViewer::hasPendingEvents () {
1904#ifdef _A_FINIR_FIXME
1905 return ((WApplication*)G4Wt::getInstance ())->hasPendingEvents ();
1910bool G4OpenGLWtViewer::generateMpegEncoderParameters () {
1914 fp = fopen (Wt::WString(fMovieTempFolderPath+fParameterFileName).toUTF8().c_str(),
"w");
1917 setRecordingInfos(
"Generation of parameter file failed");
1921 fprintf (fp,
"# parameter file template with lots of comments to assist you\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");
1927 fprintf (fp,
"# any line beginning with '#' is a comment\n");
1929 fprintf (fp,
"# no line should be longer than 255 characters\n");
1932 fprintf (fp,
"# general format of each line is:\n");
1933 fprintf (fp,
"# \n");
1935 fprintf (fp,
"# lines can generally be in any order\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");
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");
1944 fprintf (fp,
"# MUST be in UPPER CASE\n");
1947 fprintf (fp,
"# Pattern affects speed, quality and compression. See the User's Guide\n");
1948 fprintf (fp,
"# for more info.\n");
1950 fprintf (fp,
"PATTERN IBBPBBPBBPBBPBBP\n");
1951 fprintf (fp,
"OUTPUT %s\n",getSaveFileName().toUTF8().c_str());
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");
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");
1960 fprintf (fp,
"BASE_FILE_FORMAT PPM\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");
1968 fprintf (fp,
"YUV_SIZE 352x240\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");
1977 fprintf (fp,
"INPUT_FORMAT UCB\n");
1979 fprintf (fp,
"# the conversion statement\n");
1981 fprintf (fp,
"# Each occurrence of '*' will be replaced by the input file\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");
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");
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");
1993 fprintf (fp,
"INPUT_CONVERT * \n");
1995 fprintf (fp,
"# number of frames in a GOP.\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");
2000 fprintf (fp,
"# later, will add more flexible GOP signalling\n");
2002 fprintf (fp,
"GOP_SIZE 16\n");
2004 fprintf (fp,
"# number of slices in a frame\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");
2009 fprintf (fp,
"SLICES_PER_FRAME 1\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());
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");
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");
2033 fprintf (fp,
"# Many of the remaining options have to do with the motion search and qscale\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");
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");
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");
2046 fprintf (fp,
"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2047 fprintf (fp,
"PSEARCH_ALG LOGARITHMIC\n");
2049 fprintf (fp,
"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2051 fprintf (fp,
"# note that EXHAUSTIVE is really, really, really slow\n");
2053 fprintf (fp,
"BSEARCH_ALG SIMPLE\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");
2062 fprintf (fp,
"# Wscale (Wuantization scale) affects quality and compression,\n");
2063 fprintf (fp,
"# but has very little effect on speed.\n");
2065 fprintf (fp,
"IWSCALE 4\n");
2066 fprintf (fp,
"PWSCALE 5\n");
2067 fprintf (fp,
"BWSCALE 12\n");
2069 fprintf (fp,
"# this must be ORIGINAL or DECODED\n");
2070 fprintf (fp,
"REFERENCE_FRAME ORIGINAL\n");
2072 fprintf (fp,
"# for parallel parameters see parallel.param in the exmaples subdirectory\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");
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");
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");
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");
2090 setRecordingInfos(
"Parameter file "+fParameterFileName+
" generated in "+fMovieTempFolderPath);
2091 setRecordingStatus(READY_TO_ENCODE);
2095void G4OpenGLWtViewer::encodeVideo()
2097 if ((getEncoderPath() !=
"") && (getSaveFileName() !=
"")) {
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));
2112void G4OpenGLWtViewer::processEncodeStdout()
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);
2121void G4OpenGLWtViewer::processEncodeFinished()
2124 Wt::WString txt =
"";
2125 txt = getProcessErrorMsg();
2127 setRecordingStatus(SUCCESS);
2129 setRecordingStatus(FAILED);
2135void G4OpenGLWtViewer::processLookForFinished()
2138 Wt::WString txt = getProcessErrorMsg();
2142 fEncoderPath = Wt::WString(fProcess->readAllStandardOutput ().data()).trimmed();
2144 if (fEncoderPath.contains(
" ")) {
2146 }
else if (!fEncoderPath.contains(
"mpeg_encode")) {
2149 setEncoderPath(fEncoderPath);
2152 setTempFolderPath(WDir::temp ().absolutePath ());
2156Wt::WString G4OpenGLWtViewer::getProcessErrorMsg()
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";
2164 case WProcess::Crashed:
2165 txt =
"The process crashed some time after starting successfully.\n";
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";
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";
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";
2176 case WProcess::UnknownError:
2177 txt =
"An unknown error occurred. This is the default return value of error().\n";
HepGeom::Vector3D< G4double > G4Vector3D
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
G4int ApplyCommand(const char *aCommand)
static G4UImanager * GetUIpointer()