From f928f8aa34f952c0f61c8813f5a8f0a8054c4f4d Mon Sep 17 00:00:00 2001 From: ouv Date: Tue, 1 Jul 2008 09:53:27 +0000 Subject: [PATCH] VISU 2008 - Moving implementation of the AVI recording from Gauss viewer to standard VTK viewer --- src/LightApp/LightApp_Application.cxx | 27 + src/LightApp/resources/LightApp_msg_en.ts | 32 ++ src/SVTK/Makefile.am | 21 +- src/SVTK/SVTK_ImageWriter.cxx | 103 ++++ src/SVTK/SVTK_ImageWriter.h | 53 ++ src/SVTK/SVTK_ImageWriterMgr.cxx | 95 ++++ src/SVTK/SVTK_ImageWriterMgr.h | 54 ++ src/SVTK/SVTK_MainWindow.cxx | 107 ++++ src/SVTK/SVTK_MainWindow.h | 16 +- src/SVTK/SVTK_Recorder.cxx | 481 ++++++++++++++++++ src/SVTK/SVTK_Recorder.h | 156 ++++++ src/SVTK/SVTK_RecorderDlg.cxx | 212 ++++++++ src/SVTK/SVTK_RecorderDlg.h | 71 +++ src/SVTK/resources/SVTK_images.ts | 16 + src/SVTK/resources/SVTK_msg_en.ts | 100 ++++ .../resources/vtk_view_recording_pause.png | Bin 0 -> 556 bytes .../resources/vtk_view_recording_play.png | Bin 0 -> 550 bytes .../resources/vtk_view_recording_start.png | Bin 0 -> 617 bytes .../resources/vtk_view_recording_stop.png | Bin 0 -> 551 bytes src/SalomeApp/resources/SalomeApp.xml | 4 + 20 files changed, 1543 insertions(+), 5 deletions(-) create mode 100755 src/SVTK/SVTK_ImageWriter.cxx create mode 100755 src/SVTK/SVTK_ImageWriter.h create mode 100755 src/SVTK/SVTK_ImageWriterMgr.cxx create mode 100755 src/SVTK/SVTK_ImageWriterMgr.h create mode 100755 src/SVTK/SVTK_Recorder.cxx create mode 100755 src/SVTK/SVTK_Recorder.h create mode 100644 src/SVTK/SVTK_RecorderDlg.cxx create mode 100644 src/SVTK/SVTK_RecorderDlg.h create mode 100644 src/SVTK/resources/vtk_view_recording_pause.png create mode 100644 src/SVTK/resources/vtk_view_recording_play.png create mode 100644 src/SVTK/resources/vtk_view_recording_start.png create mode 100644 src/SVTK/resources/vtk_view_recording_stop.png diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 1e0f9eb8b..37276950e 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -1884,6 +1884,33 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->setItemProperty( "strings", values, spacemousePref3 ); pref->setItemProperty( "indexes", indices, spacemousePref3 ); + int vtkRec = pref->addPreference( tr( "PREF_FRAME_RECORDING" ), vtkGroup, LightApp_Preferences::GroupBox ); + pref->setItemProperty( "columns", 2, vtkRec ); + + int modePref = pref->addPreference( tr( "PREF_RECORDING_MODE" ), vtkRec, + LightApp_Preferences::Selector, "VTKViewer", "recorder_mode" ); + values.clear(); + values.append( tr( "PREF_SKIPPED_FRAMES" ) ); + values.append( tr( "PREF_ALL_DISLPAYED_FRAMES" ) ); + indices.clear(); + indices.append( 0 ); + indices.append( 1 ); + pref->setItemProperty( "strings", values, modePref ); + pref->setItemProperty( "indexes", indices, modePref ); + + int fpsPref = pref->addPreference( tr( "PREF_FPS" ), vtkRec, + LightApp_Preferences::DblSpin, "VTKViewer", "recorder_fps" ); + pref->setItemProperty( "min", 0.1, fpsPref ); + pref->setItemProperty( "max", 100, fpsPref ); + + int qualityPref = pref->addPreference( tr( "PREF_QUALITY" ), vtkRec, + LightApp_Preferences::IntSpin, "VTKViewer", "recorder_quality" ); + pref->setItemProperty( "min", 1, qualityPref ); + pref->setItemProperty( "max", 100, qualityPref ); + + pref->addPreference( tr( "PREF_PROGRESSIVE" ), vtkRec, + LightApp_Preferences::Bool, "VTKViewer", "recorder_progressive" ); + // Plot2d pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dGroup, LightApp_Preferences::Bool, "Plot2d", "ShowLegend" ); diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 1812cbc5f..b2ebe136f 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -181,6 +181,38 @@ CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITASPREF_SPACEMOUSE_BTN_11 Button 11 + + PREF_FRAME_RECORDING + AVI Recording + + + PREF_ALL_DISLPAYED_FRAMES + Recording all displayed frames + + + PREF_FPS + FPS + + + PREF_GROUP_TTL + Settings + + + PREF_PROGRESSIVE + Progressive + + + PREF_QUALITY + Quality + + + PREF_RECORDING_MODE + Mode + + + PREF_SKIPPED_FRAMES + Recording at a given FPS + PREF_BOTTOM Bottom diff --git a/src/SVTK/Makefile.am b/src/SVTK/Makefile.am index d3d813984..c669c7740 100755 --- a/src/SVTK/Makefile.am +++ b/src/SVTK/Makefile.am @@ -55,7 +55,11 @@ salomeinclude_HEADERS= \ SVTK_SetRotationPointDlg.h \ SVTK_ViewParameterDlg.h \ SVTK_ComboAction.h \ - SVTK_Extension.h + SVTK_Extension.h \ + SVTK_Recorder.h \ + SVTK_RecorderDlg.h \ + SVTK_ImageWriter.h \ + SVTK_ImageWriterMgr.h dist_libSVTK_la_SOURCES= \ SVTK_Prs.cxx \ @@ -85,7 +89,11 @@ dist_libSVTK_la_SOURCES= \ SVTK_SetRotationPointDlg.cxx \ SVTK_ViewParameterDlg.cxx \ SVTK_ComboAction.cxx \ - SVTK_Extension.cxx + SVTK_Extension.cxx \ + SVTK_Recorder.cxx \ + SVTK_RecorderDlg.cxx \ + SVTK_ImageWriter.cxx \ + SVTK_ImageWriterMgr.cxx EXTRA_DIST+= SVTK_SelectorDef.h SVTK_Trihedron.h @@ -105,7 +113,8 @@ MOC_FILES= \ SVTK_View_moc.cxx \ SVTK_SetRotationPointDlg_moc.cxx \ SVTK_ViewParameterDlg_moc.cxx \ - SVTK_ComboAction_moc.cxx + SVTK_ComboAction_moc.cxx \ + SVTK_RecorderDlg_moc.cxx nodist_libSVTK_la_SOURCES= $(MOC_FILES) dist_salomeres_DATA=\ @@ -116,7 +125,11 @@ dist_salomeres_DATA=\ resources/vtk_view_parallel.png \ resources/vtk_view_perspective.png \ resources/vtk_view_parameters.png \ - resources/vtk_view_style_switch.png + resources/vtk_view_style_switch.png \ + resources/vtk_view_recording_start.png \ + resources/vtk_view_recording_play.png \ + resources/vtk_view_recording_pause.png \ + resources/vtk_view_recording_stop.png nodist_salomeres_DATA= \ SVTK_msg_en.qm \ diff --git a/src/SVTK/SVTK_ImageWriter.cxx b/src/SVTK/SVTK_ImageWriter.cxx new file mode 100755 index 000000000..e14e0e528 --- /dev/null +++ b/src/SVTK/SVTK_ImageWriter.cxx @@ -0,0 +1,103 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#include "SVTK_ImageWriter.h" + +#include + +#include +#include +#include +#include + +#ifdef _DEBUG_ +static int MYDEBUG = 0; +#else +static int MYDEBUG = 0; +#endif + + +//---------------------------------------------------------------------------- +SVTK_ImageWriter +::SVTK_ImageWriter(QSemaphore* theSemaphore, + vtkImageData* theImageData, + const std::string& theName, + int theProgressive, + int theQuality): + mySemaphore(theSemaphore), + myImageData(theImageData), + myName(theName), + myProgressive(theProgressive), + myQuality(theQuality), + myConstraint16Flag(true) +{} + +//---------------------------------------------------------------------------- +SVTK_ImageWriter +::~SVTK_ImageWriter() +{ + if(MYDEBUG) cout<<"SVTK_ImageWriter::~SVTK_ImageWriter - this = "< anImageClip; + // + if(myConstraint16Flag){ + int uExtent[6]; + myImageData->UpdateInformation(); + myImageData->GetUpdateExtent(uExtent); + unsigned int width = uExtent[1] - uExtent[0] + 1; + unsigned int height = uExtent[3] - uExtent[2] + 1; + width = (width / 16) * 16; + height= (height / 16) * 16; + uExtent[1] = uExtent[0] + width - 1; + uExtent[3] = uExtent[2] + height - 1; + // + anImageClip = vtkImageClip::New(); + anImageClip->Delete(); + + anImageClip->SetInput(myImageData); + anImageClip->SetOutputWholeExtent(uExtent); + anImageClip->ClipDataOn(); + anImageData = anImageClip->GetOutput(); + } + // + aWriter->WriteToMemoryOff(); + aWriter->SetFileName(myName.c_str()); + aWriter->SetQuality(myQuality); + aWriter->SetProgressive(myProgressive); + aWriter->SetInput(anImageData); + aWriter->Write(); + + aWriter->Delete(); + myImageData->Delete(); + + if(MYDEBUG) cout<<"SVTK_ImageWriter::run "<< + "- this = "< + +#include + +#include + + +#ifdef _DEBUG_ +static int MYDEBUG = 0; +#else +static int MYDEBUG = 0; +#endif + +//---------------------------------------------------------------------------- +SVTK_ImageWriterMgr +::SVTK_ImageWriterMgr() +{ + int aMax = std::numeric_limits::max() / 2; + mySemaphore = new QSemaphore(aMax); + mySemaphore->acquire( aMax ); + if(MYDEBUG) cout<<"SVTK_ImageWriterMgr::SVTK_ImageWriterMgr "<< + //"- total = "<total()<< + "; available = "<available()<start(); + +} + + +//---------------------------------------------------------------------------- +void +SVTK_ImageWriterMgr +::Stop() +{ + if(MYDEBUG) cout<<"SVTK_ImageWriterMgr::Stop "<< + //"- total = "<total()<< + "; available = "<available()<createToolBar( tr("LBL_TOOLBAR_LABEL"), -1, this ); + myRecordingToolBar = toolMgr()->createToolBar( tr("LBL_TOOLBAR_RECORD_LABEL"), -1, this ); createActions( SUIT_Session::session()->activeApplication()->resourceMgr() ); createToolBar(); @@ -103,6 +106,17 @@ void SVTK_MainWindow::Initialize(SVTK_RenderWindowInteractor* theInteractor) ( action( ChangeRotationPointId ), this, "SVTK_SetRotationPointDlg" ); myViewParameterDlg = new SVTK_ViewParameterDlg ( action( ViewParametersId ), this, "SVTK_ViewParameterDlg" ); + + myRecorder = SVTK_Recorder::New(); + //myRecorder->CheckExistAVIMaker(); + //if(myRecorder->ErrorStatus()) + // myRecordingToolBar->setEnabled(false); + + myRecorder->SetNbFPS( 17.3 ); + myRecorder->SetQuality( 100 ); + myRecorder->SetProgressiveMode( true ); + myRecorder->SetUseSkippedFrames( true ); + myRecorder->SetRenderWindow( theInteractor->getRenderWindow() ); } /*! @@ -110,6 +124,8 @@ void SVTK_MainWindow::Initialize(SVTK_RenderWindowInteractor* theInteractor) */ SVTK_MainWindow::~SVTK_MainWindow() { + if(myRecorder) + myRecorder->Delete(); } /*! @@ -576,6 +592,41 @@ void SVTK_MainWindow::createActions(SUIT_ResourceMgr* theResourceMgr) anAction->setCheckable(true); connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchInteractionStyle(bool))); mgr->registerAction( anAction, SwitchInteractionStyleId ); + + // Start recording + myStartAction = new QtxAction(tr("MNU_SVTK_RECORDING_START"), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_RECORDING_START" ) ), + tr( "MNU_SVTK_RECORDING_START" ), 0, this); + myStartAction->setStatusTip(tr("DSC_SVTK_RECORDING_START")); + connect( myStartAction, SIGNAL( triggered ( bool ) ), this, SLOT( onStartRecording() ) ); + mgr->registerAction( myStartAction, StartRecordingId ); + + // Play recording + myPlayAction = new QtxAction(tr("MNU_SVTK_RECORDING_PLAY"), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_RECORDING_PLAY" ) ), + tr( "MNU_SVTK_RECORDING_PLAY" ), 0, this); + myPlayAction->setStatusTip(tr("DSC_SVTK_RECORDING_PLAY")); + myPlayAction->setEnabled( false ); + connect( myPlayAction, SIGNAL( triggered ( bool ) ), this, SLOT( onPlayRecording() ) ); + mgr->registerAction( myPlayAction, PlayRecordingId ); + + // Pause recording + myPauseAction = new QtxAction(tr("MNU_SVTK_RECORDING_PAUSE"), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_RECORDING_PAUSE" ) ), + tr( "MNU_SVTK_RECORDING_PAUSE" ), 0, this); + myPauseAction->setStatusTip(tr("DSC_SVTK_RECORDING_PAUSE")); + myPauseAction->setEnabled( false ); + connect( myPauseAction, SIGNAL( triggered ( bool ) ), this, SLOT( onPauseRecording() ) ); + mgr->registerAction( myPauseAction, PauseRecordingId ); + + // Stop recording + myStopAction = new QtxAction(tr("MNU_SVTK_RECORDING_STOP"), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_RECORDING_STOP" ) ), + tr( "MNU_SVTK_RECORDING_STOP" ), 0, this); + myStopAction->setStatusTip(tr("DSC_SVTK_RECORDING_STOP")); + myStopAction->setEnabled( false ); + connect( myStopAction, SIGNAL( triggered ( bool ) ), this, SLOT( onStopRecording() ) ); + mgr->registerAction( myStopAction, StopRecordingId ); } #if defined(WIN32) && !defined(_DEBUG) @@ -625,6 +676,11 @@ void SVTK_MainWindow::createToolBar() mgr->append( ViewParametersId, myToolBar ); mgr->append( ProjectionModeId, myToolBar ); + + mgr->append( StartRecordingId, myRecordingToolBar ); + mgr->append( PlayRecordingId, myRecordingToolBar ); + mgr->append( PauseRecordingId, myRecordingToolBar ); + mgr->append( StopRecordingId, myRecordingToolBar ); } /*! @@ -948,3 +1004,54 @@ QtxAction* SVTK_MainWindow::action( int id ) const { return dynamic_cast( toolMgr()->action( id ) ); } + +void SVTK_MainWindow::onStartRecording() +{ + myRecorder->CheckExistAVIMaker(); + if (myRecorder->ErrorStatus()) { + SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_AVI_MAKER") ); + } + else { + SVTK_RecorderDlg* aRecorderDlg = new SVTK_RecorderDlg( this, myRecorder ); + + if( !aRecorderDlg->exec() ) + return; + + myStartAction->setEnabled( false ); + myPlayAction->setEnabled( false ); + myPauseAction->setEnabled( true ); + myStopAction->setEnabled( true ); + + myRecorder->Record(); + } +} + +void SVTK_MainWindow::onPlayRecording() +{ + myStartAction->setEnabled( false ); + myPlayAction->setEnabled( false ); + myPauseAction->setEnabled( true ); + myStopAction->setEnabled( true ); + + myRecorder->Pause(); +} + +void SVTK_MainWindow::onPauseRecording() +{ + myStartAction->setEnabled( false ); + myPlayAction->setEnabled( true ); + myPauseAction->setEnabled( false ); + myStopAction->setEnabled( true ); + + myRecorder->Pause(); +} + +void SVTK_MainWindow::onStopRecording() +{ + myStartAction->setEnabled( true ); + myPlayAction->setEnabled( false ); + myPauseAction->setEnabled( false ); + myStopAction->setEnabled( false ); + + myRecorder->Stop(); +} diff --git a/src/SVTK/SVTK_MainWindow.h b/src/SVTK/SVTK_MainWindow.h index 6f4ec2ce0..e94cb37c6 100644 --- a/src/SVTK/SVTK_MainWindow.h +++ b/src/SVTK/SVTK_MainWindow.h @@ -52,6 +52,7 @@ class SVTK_ViewParameterDlg; class SVTK_Renderer; class SVTK_Selector; class SVTK_KeyFreeInteractorStyle; +class SVTK_Recorder; class VTKViewer_Trihedron; class VTKViewer_Actor; @@ -221,6 +222,11 @@ public: void onSwitchInteractionStyle(bool theOn); + void onStartRecording(); + void onPlayRecording(); + void onPauseRecording(); + void onStopRecording(); + public: QImage dumpView(); @@ -239,7 +245,8 @@ public: ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ResetId, ViewTrihedronId, NonIsometric, GraduatedAxes, UpdateRate, - ProjectionModeId, ViewParametersId, SwitchInteractionStyleId }; + ProjectionModeId, ViewParametersId, SwitchInteractionStyleId, + StartRecordingId, PlayRecordingId, PauseRecordingId, StopRecordingId }; SUIT_ViewWindow* myViewWindow; @@ -251,9 +258,16 @@ public: vtkSmartPointer myEventDispatcher; int myToolBar; + int myRecordingToolBar; SVTK_RenderWindowInteractor* myInteractor; vtkSmartPointer myKeyFreeInteractorStyle; + + SVTK_Recorder* myRecorder; + QtxAction* myStartAction; + QtxAction* myPlayAction; + QtxAction* myPauseAction; + QtxAction* myStopAction; }; #ifdef WIN32 diff --git a/src/SVTK/SVTK_Recorder.cxx b/src/SVTK/SVTK_Recorder.cxx new file mode 100755 index 000000000..67aac1de0 --- /dev/null +++ b/src/SVTK/SVTK_Recorder.cxx @@ -0,0 +1,481 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#include "SVTK_Recorder.h" + +#include "SVTK_ImageWriter.h" +#include "SVTK_ImageWriterMgr.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include +#include +#include + +//#include "utilities.h" + +#ifdef _DEBUG_ +static int MYDEBUG = 0; +#else +static int MYDEBUG = 0; +#endif + + +namespace +{ + //---------------------------------------------------------------------------- + inline + void + GetNameJPEG(const std::string& thePreffix, + const int theIndex, + std::string& theName) + { + using namespace std; + ostringstream aStream; + aStream<SetClientData(this); + myCommand->SetCallback(SVTK_Recorder::ProcessEvents); +} + + +//---------------------------------------------------------------------------- +SVTK_Recorder +::~SVTK_Recorder() +{ + myCommand->Delete(); + myFilter->Delete(); + delete myWriterMgr; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::CheckExistAVIMaker() +{ + myErrorStatus = 0; + using namespace std; + ostringstream aStream; + aStream<<"which "<& /dev/null"; + std::string anAVIMakeCheck = aStream.str(); + int iErr = system(anAVIMakeCheck.c_str()); + if(iErr != 0) + myErrorStatus = 127; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::SetName(const char* theName) +{ + myName = theName; +} + +const char* +SVTK_Recorder::Name() const +{ + return myName.c_str(); +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::SetNbFPS(const double theNbFPS) +{ + myNbFPS = theNbFPS; +} + +double +SVTK_Recorder +::NbFPS() const +{ + return myNbFPS; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::SetQuality(int theQuality) +{ + myQuality = theQuality; +} + +int +SVTK_Recorder +::GetQuality() const +{ + return myQuality; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::SetRenderWindow(vtkRenderWindow* theRenderWindow) +{ + myRenderWindow = theRenderWindow; +} + +vtkRenderWindow* +SVTK_Recorder +::RenderWindow() +{ + return myRenderWindow; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::SetProgressiveMode(bool theProgressiveMode) +{ + myProgressiveMode = theProgressiveMode; +} + +bool +SVTK_Recorder +::GetProgressiveMode() const +{ + return myProgressiveMode; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::SetUseSkippedFrames(bool theUseSkippedFrames) +{ + myUseSkippedFrames = theUseSkippedFrames; +} + +bool +SVTK_Recorder +::UseSkippedFrames() const +{ + return myUseSkippedFrames; +} + + +//---------------------------------------------------------------------------- +int +SVTK_Recorder +::ErrorStatus() const +{ + return myErrorStatus; +} + +int +SVTK_Recorder +::State() const +{ + return myState; +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::ProcessEvents(vtkObject* vtkNotUsed(theObject), + unsigned long theEvent, + void* theClientData, + void* vtkNotUsed(theCallData)) +{ + if(vtkObject* anObj = reinterpret_cast(theClientData)){ + if(SVTK_Recorder* aSelf = dynamic_cast(anObj)){ + if(theEvent==vtkCommand::EndEvent){ + if(aSelf->State() == SVTK_Recorder::SVTK_Recorder_Record){ + aSelf->DoRecord(); + } + } + } + } +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::Record() +{ + if(myState == SVTK_Recorder_Stop){ + if(myRenderWindow){ + myState = SVTK_Recorder_Record; + myFilter->SetInput(myRenderWindow); + myFrameIndex = -1; + myNbWrittenFrames = 0; + myRenderWindow->RemoveObserver(myCommand); + myRenderWindow->AddObserver(vtkCommand::EndEvent, + myCommand, + myPriority); + myRenderWindow->Render(); + } + } +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::Stop() +{ + QApplication::setOverrideCursor( Qt::WaitCursor ); + + if(myState == SVTK_Recorder_Record){ + if(!myPaused) + DoRecord(); + + myWriterMgr->Stop(); + + if(myUseSkippedFrames) + AddSkippedFrames(); + + myFrameIndexes.clear(); + + MakeFileAVI(); + } + myState = SVTK_Recorder_Stop; + myPaused = 0; + + QApplication::restoreOverrideCursor(); +} + + +//---------------------------------------------------------------------------- +void +SVTK_Recorder +::Pause() +{ + myPaused = myPaused ? 0 : 1; + if(myPaused && !myFrameIndexes.empty()){ + myFrameIndexes.back() *= -1; + if(MYDEBUG) cout<<"SVTK_Recorder::Pause - myFrameIndexes.back() = "< +#include +#include + +#include + +class vtkRenderWindow; +class vtkCallbackCommand; +class vtkWindowToImageFilter; +class SVTK_ImageWriterMgr; + +class SVTK_Recorder : public vtkObject +{ + protected: + enum State { + SVTK_Recorder_Unknown=0, + SVTK_Recorder_Record, + SVTK_Recorder_Stop + }; + + public: + static SVTK_Recorder *New(); + vtkTypeRevisionMacro(SVTK_Recorder,vtkObject); + + void + SetRenderWindow(vtkRenderWindow* theRenderWindow); + + vtkRenderWindow* + RenderWindow(); + + void + SetName(const char *theName); + + const char* + Name() const; + + void + SetNbFPS(const double theNbFPS); + + double + NbFPS() const; + + void + SetQuality(int theQuality); + + int + GetQuality() const; + + void + SetProgressiveMode(bool theProgressiveMode); + + bool + GetProgressiveMode() const; + + void + SetUseSkippedFrames(bool theUseSkippedFrames); + + bool + UseSkippedFrames() const; + + void + Record(); + + void + Pause(); + + void + Stop(); + + int + State() const; + + int + ErrorStatus() const; + + void + CheckExistAVIMaker(); + +protected : + SVTK_Recorder(); + + ~SVTK_Recorder(); + + void + DoRecord(); + + void + MakeFileAVI(); + + void + AddSkippedFrames(); + + void + PreWrite(); + + static + void + ProcessEvents(vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* theCallData); + +protected : + int myState; + int myPaused; + int myErrorStatus; + + float myPriority; + double myTimeStart; + + int myFrameIndex; + int myNbWrittenFrames; + + double myNbFPS; + int myQuality; + bool myProgressiveMode; + + typedef std::vector TFrameIndexes; + TFrameIndexes myFrameIndexes; + bool myUseSkippedFrames; + + std::string myName; + std::string myNameAVIMaker; + + vtkCallbackCommand *myCommand; + vtkRenderWindow *myRenderWindow; + vtkWindowToImageFilter *myFilter; + SVTK_ImageWriterMgr *myWriterMgr; + +private: + SVTK_Recorder(const SVTK_Recorder&); //Not implemented + void operator=(const SVTK_Recorder&); //Not implemented +}; + +#endif diff --git a/src/SVTK/SVTK_RecorderDlg.cxx b/src/SVTK/SVTK_RecorderDlg.cxx new file mode 100644 index 000000000..cdf320857 --- /dev/null +++ b/src/SVTK/SVTK_RecorderDlg.cxx @@ -0,0 +1,212 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#include "SVTK_RecorderDlg.h" +#include "SVTK_Recorder.h" + +#include +#include +#include +#include + +#include +#include + +//#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + * Constructor + */ +SVTK_RecorderDlg::SVTK_RecorderDlg( QWidget* theParent, SVTK_Recorder* theRecorder ): + QDialog( theParent ), + myRecorder( theRecorder ) +{ + setWindowTitle( tr( "DLG_RECORDER_TITLE" ) ); + + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + + QVBoxLayout* aTopLayout = new QVBoxLayout( this ); + aTopLayout->setSpacing( 6 ); + aTopLayout->setMargin( 6 ); + + // Settings + QGroupBox* mySettingsBox = new QGroupBox( tr( "SETTINGS" ), this ); + + QGridLayout* aSettingsLayout = new QGridLayout( mySettingsBox ); + aSettingsLayout->setSpacing( 6 ); + aSettingsLayout->setMargin( 11 ); + + QLabel* aFileNameLabel = new QLabel( tr( "FILE_NAME" ), mySettingsBox ); + myFileNameLineEdit = new QLineEdit( mySettingsBox ); + myFileNameLineEdit->setMinimumWidth( 250 ); + myFileNameLineEdit->setReadOnly( true ); + + QLabel* aRecordingModeLabel = new QLabel( tr( "RECORDING_MODE" ), mySettingsBox ); + myRecordingModeComboBox = new QComboBox( mySettingsBox ); + myRecordingModeComboBox->addItem( tr( "SKIPPED_FRAMES" ) ); + myRecordingModeComboBox->addItem( tr( "ALL_DISLPAYED_FRAMES" ) ); + myRecordingModeComboBox->setCurrentIndex( aResourceMgr->integerValue( "VTKViewer", "recorder_mode", 1 ) ); + + QLabel* aFPSLabel = new QLabel( tr( "FPS" ), mySettingsBox ); + myFPSSpinBox = new QtxDoubleSpinBox( 0.1, 100.0, 1.0, mySettingsBox ); + myFPSSpinBox->setValue( aResourceMgr->doubleValue( "VTKViewer", "recorder_fps", 10.0 ) ); + + QLabel* aQualityLabel = new QLabel( tr( "QUALITY" ), mySettingsBox ); + myQualitySpinBox = new QtxIntSpinBox( 1, 100, 1, mySettingsBox ); + myQualitySpinBox->setValue( aResourceMgr->integerValue( "VTKViewer", "recorder_quality", 80 ) ); + + myProgressiveCheckBox = new QCheckBox( tr( "PROGRESSIVE" ), mySettingsBox ); + myProgressiveCheckBox->setChecked( aResourceMgr->booleanValue( "VTKViewer", "recorder_progressive", false ) ); + + aSettingsLayout->addWidget( aFileNameLabel, 0, 0 ); + aSettingsLayout->addWidget( myFileNameLineEdit, 1, 0, 1, 2 ); + aSettingsLayout->addWidget( aRecordingModeLabel, 2, 0 ); + aSettingsLayout->addWidget( myRecordingModeComboBox, 2, 1 ); + aSettingsLayout->addWidget( aFPSLabel, 3, 0 ); + aSettingsLayout->addWidget( myFPSSpinBox, 3, 1 ); + aSettingsLayout->addWidget( aQualityLabel, 4, 0 ); + aSettingsLayout->addWidget( myQualitySpinBox, 4, 1 ); + aSettingsLayout->addWidget( myProgressiveCheckBox, 5, 0 ); + + aTopLayout->addWidget( mySettingsBox ); + + // Start / Close + QGroupBox* CommonGroup = new QGroupBox( this ); + QGridLayout* CommonGroupLayout = new QGridLayout( CommonGroup ); + CommonGroupLayout->setAlignment( Qt::AlignTop ); + CommonGroupLayout->setSpacing( 6 ); + CommonGroupLayout->setMargin( 11 ); + + QPushButton* aStartButton = new QPushButton( tr( "START" ), CommonGroup ); + aStartButton->setAutoDefault( true ); + aStartButton->setDefault( true ); + CommonGroupLayout->addWidget( aStartButton, 0, 0 ); + CommonGroupLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 ); + + QPushButton* aCloseButton = new QPushButton( tr( "CLOSE" ), CommonGroup ); + aCloseButton->setAutoDefault( true ); + CommonGroupLayout->addWidget( aCloseButton, 0, 2 ); + + QPushButton* aHelpButton = new QPushButton( tr( "HELP" ), CommonGroup ); + aHelpButton->setAutoDefault( true ); + CommonGroupLayout->addWidget( aHelpButton, 0, 3 ); + + aTopLayout->addWidget( CommonGroup ); + + connect( aStartButton, SIGNAL( clicked() ), this, SLOT( onStart() ) ); + connect( aCloseButton, SIGNAL( clicked() ), this, SLOT( onClose() ) ); + connect( aHelpButton, SIGNAL( clicked() ), this, SLOT( onHelp() ) ); +} + +SVTK_RecorderDlg::~SVTK_RecorderDlg() +{ +} + +void SVTK_RecorderDlg::onStart() +{ + if( myFileName.isNull() ) + return; + + myRecorder->SetName( (const char*)myFileName.toLatin1() ); + + myRecorder->SetUseSkippedFrames( myRecordingModeComboBox->currentIndex() == 0 ); + myRecorder->SetNbFPS( myFPSSpinBox->value() ); + myRecorder->SetQuality( myQualitySpinBox->value() ); + myRecorder->SetProgressiveMode( myProgressiveCheckBox->isChecked() ); + + accept(); + +} + +void SVTK_RecorderDlg::onClose() +{ + reject(); +} + +void SVTK_RecorderDlg::onHelp() +{ + /* + QString aHelpFileName = "animation_in_gauss_viewer.htm"; + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(app->activeModule() ? app->moduleName(app->activeModule()->moduleName()) : QString(""), aHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"), + QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName) ); + } + */ +} + +bool SVTK_RecorderDlg::onBrowseFile() +{ + QStringList aFilter; + aFilter.append( tr( "FLT_AVI_FILES" ) ); + aFilter.append( tr( "FLT_ALL_FILES" ) ); + + QString aFileName = SUIT_FileDlg::getFileName( this, getenv( "HOME" ), aFilter, + tr( "FILE_NAME" ), false ); + + if( aFileName.isNull() ) + return false; + + myFileName = aFileName; + myFileNameLineEdit->setText( aFileName.section( '/', -1 ) ); + + return true; +} + +int SVTK_RecorderDlg::exec() +{ + if( !onBrowseFile() ) + { + reject(); + return 0; + } + return QDialog::exec(); +} + +void SVTK_RecorderDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) + { + e->accept(); + onHelp(); + } +} diff --git a/src/SVTK/SVTK_RecorderDlg.h b/src/SVTK/SVTK_RecorderDlg.h new file mode 100644 index 000000000..93e19e660 --- /dev/null +++ b/src/SVTK/SVTK_RecorderDlg.h @@ -0,0 +1,71 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#ifndef SVTK_RECORDERDLG_H +#define SVTK_RECORDERDLG_H + +#include + +class QCheckBox; +class QComboBox; +class QGroupBox; +class QLCDNumber; +class QLineEdit; +class QPushButton; +class QTimer; + +class QtxDoubleSpinBox; +class QtxIntSpinBox; + +class SVTK_Recorder; + +class SVTK_RecorderDlg : public QDialog +{ + Q_OBJECT + +public: + SVTK_RecorderDlg( QWidget*, SVTK_Recorder* ); + ~SVTK_RecorderDlg(); + + int exec(); + + QString fileName() const { return myFileName; } + +private: + virtual void keyPressEvent( QKeyEvent* ); + +protected slots: + void onStart(); + void onClose(); + void onHelp(); + + bool onBrowseFile(); + +private: + SVTK_Recorder* myRecorder; + QString myFileName; + + QLineEdit* myFileNameLineEdit; + + QComboBox* myRecordingModeComboBox; + QtxDoubleSpinBox* myFPSSpinBox; + QtxIntSpinBox* myQualitySpinBox; + QCheckBox* myProgressiveCheckBox; +}; + +#endif diff --git a/src/SVTK/resources/SVTK_images.ts b/src/SVTK/resources/SVTK_images.ts index f354781bd..38b7285ff 100644 --- a/src/SVTK/resources/SVTK_images.ts +++ b/src/SVTK/resources/SVTK_images.ts @@ -33,5 +33,21 @@ ICON_SVTK_STYLE_SWITCH vtk_view_style_switch.png + + ICON_SVTK_RECORDING_START + vtk_view_recording_start.png + + + ICON_SVTK_RECORDING_PLAY + vtk_view_recording_play.png + + + ICON_SVTK_RECORDING_PAUSE + vtk_view_recording_pause.png + + + ICON_SVTK_RECORDING_STOP + vtk_view_recording_stop.png + diff --git a/src/SVTK/resources/SVTK_msg_en.ts b/src/SVTK/resources/SVTK_msg_en.ts index 66d24473b..7235f9196 100644 --- a/src/SVTK/resources/SVTK_msg_en.ts +++ b/src/SVTK/resources/SVTK_msg_en.ts @@ -293,6 +293,47 @@ MNU_SVTK_UPDATE_RATE Update rate + + DSC_SVTK_RECORDING_START + Start recording + + + MNU_SVTK_RECORDING_START + Start recording + + + DSC_SVTK_RECORDING_PLAY + Play recording + + + MNU_SVTK_RECORDING_PLAY + Play recording + + + DSC_SVTK_RECORDING_PAUSE + Pause recording + + + MNU_SVTK_RECORDING_PAUSE + Pause recording + + + DSC_SVTK_RECORDING_STOP + Stop recording + + + MNU_SVTK_RECORDING_STOP + Stop recording + + + LBL_TOOLBAR_RECORD_LABEL + Recording Operations + + + MSG_NO_AVI_MAKER + Tool jpeg2yuv, necessary for AVI recording, is not available. +Please, refer to the documentation. + SVTK_NonIsometricDlg @@ -317,6 +358,65 @@ Scaling + + SVTK_RecorderDlg + + ALL_DISLPAYED_FRAMES + Recording all displayed frames + + + CLOSE + Close + + + DLG_RECORDER_TITLE + Recorder + + + FILE_NAME + Save to file : + + + FLT_ALL_FILES + All Files (*.*) + + + FLT_AVI_FILES + AVI Files (*.avi) + + + FPS + FPS : + + + HELP + Help + + + PROGRESSIVE + Progressive + + + QUALITY + Quality : + + + RECORDING_MODE + Mode : + + + SETTINGS + Settings + + + SKIPPED_FRAMES + Recording at a given FPS + + + START + Start + + SVTK_SetRotationPointDlg diff --git a/src/SVTK/resources/vtk_view_recording_pause.png b/src/SVTK/resources/vtk_view_recording_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..f181a0f6b9038256b163f5c8c31c1c4c43122da2 GIT binary patch literal 556 zcmV+{0@MA8P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ-qDe$SRCwBA{Qv(y10?_;fS4F41ONdk-9#DdJp z%*_1H%*+gC|NZ-yVaALZj43H8|9}4c$?)ylH-@iYzcTFDv4asL5A!-e0D&1W3{w2{ z>-YcXA3pz|kdOdUp&S(z_5aJ4Z~u?qdHmnT#s(|~#N04F00D&J1(2;EgZ}}E@87?J zggihtgT(&)`^WI-&mXWD5KF-H00a<<0l$9zf*ADgKiJ7YpaL=AKf})-KfxA&#DJIw zrUxK^Pz(V16{Pqt&^C~NK>$R9T=VVg7nlJk03d)c41l@d$B!RiHptmuzI+5OalM{2*ZG;+%&Kzm~%nwsm--uHX|b= zh5-Np#E5JvP=P*>N&sR5sL%x{Hb4_w0MvI8!~qB(7BmCD0P!6pK8XDSi`W+!2OxmZ uUBC@ZWjsg*eu46l#a;mQffEWqfB^t(nFsGL;X&E}0000?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx-l>?&hd0{45_%4^ymM7duCMzg@zdt8Y~QqE*lvc7>_V~V&Yl8WXXg#@(m10E_}^r z&Ybz*)6>KA|KH!_8J5Lr%7$zVECSrS9I8@nXZ-v8{QUp;{dI;qaeE}zJ2Eh~BryaC z-_Vvya^i{Hde&k3pY$Jpet!PHzy7~b&b>X7t078G9NYh2;o(9~6BZV)U22AZm_Oa$ zSNmIDrS8vabM2Awsev9_WQG#`t|Ti9bHQG(OxdKVPyhZvWvAoEZo9?Bm;T=j?2Aeut@&3fYVt z3L?yP|Nou+Ah_b?!`<6?CQE5aIy9EQzNS0ln7)E^;}5AK*S1r3d4lgu6 ja)(?NcalnEP&mNgRd8K}Pmd88Zww5cu6{1-oD!M<#+BBT literal 0 HcmV?d00001 diff --git a/src/SVTK/resources/vtk_view_recording_start.png b/src/SVTK/resources/vtk_view_recording_start.png new file mode 100644 index 0000000000000000000000000000000000000000..5b71dc511c498b6bfbc5a5d8d86dee85ade8141a GIT binary patch literal 617 zcmV-v0+#)WP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ--$_J4RCwBA{Qv(y10?_;fS4F41ONdk-9#DdIW zWMqW1OG``t|M~NW;m4033}3%~WmvRm5hJ>0koN%shy|OeAkB>e0u29u|7KudV`KQw z!ou+0*Z2SC&6|0E(qEC)0t66-7mA9C{x|aRK{Nwx{|~}He=;ls8fa^4`vs_k8(BR- z05KxRLPkc$|2|Ps28MtC7#M&CfHi;r&cN{P8^b@KA>V;s@_YWA;nb;9V3&aO0t66> z7eIdf&&kQa@b@nR!>?a(1HJ>QOi0|&0P@h) z)vW>f_aD$ZAT_sc-GXTb1>O!24HW+h5J2b#FhJuOYzUO*fw>M@Gb|bb0tj15{0db7 z(?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx-l>?&h>P045_%4^ymM7duCMzg@zdt8Y~QqE*lvc7-!6D7G_8g;Aj%xQ>S}jlL!l| z@SmqU4dy?UUsdJlVEzIK$Alz%_en!KS}0r3anr-7*yS&D3p zNA}nKQ1k!WTt?f6j4T3Oj0(|pOot!-{r&xcMsp_1P9BlD_WSA& ze_(Q8NNhPcy_lMS?**nDhDn?(I*2k;>rd>gTe~DWM4fiQUWB literal 0 HcmV?d00001 diff --git a/src/SalomeApp/resources/SalomeApp.xml b/src/SalomeApp/resources/SalomeApp.xml index 3ff2c7220..05f863cd7 100644 --- a/src/SalomeApp/resources/SalomeApp.xml +++ b/src/SalomeApp/resources/SalomeApp.xml @@ -105,6 +105,10 @@ + + + +
-- 2.39.2