1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
29 #include "VVTK_Recorder.h"
31 #include "VVTK_ImageWriter.h"
32 #include "VVTK_ImageWriterMgr.h"
34 #include <vtkObjectFactory.h>
35 #include <vtkObject.h>
36 #include <vtkCallbackCommand.h>
37 #include <vtkRenderWindow.h>
38 #include <vtkTimerLog.h>
39 #include <vtkWindowToImageFilter.h>
40 #include <vtkJPEGWriter.h>
41 #include <vtkImageData.h>
51 #include <qapplication.h>
52 #include <qfileinfo.h>
54 #include "utilities.h"
57 static int MYDEBUG = 0;
59 static int MYDEBUG = 0;
65 //----------------------------------------------------------------------------
68 GetNameJPEG(const std::string& thePreffix,
73 ostringstream aStream;
74 aStream<<thePreffix<<"_"<<setw(6)<<setfill('0')<<theIndex<<".jpeg";
75 theName = aStream.str();
79 //----------------------------------------------------------------------------
80 vtkCxxRevisionMacro(VVTK_Recorder,"$Revision$");
81 vtkStandardNewMacro(VVTK_Recorder);
84 //----------------------------------------------------------------------------
88 myState(VVTK_Recorder_Stop),
91 myProgressiveMode(true),
92 myUseSkippedFrames(true),
94 myCommand(vtkCallbackCommand::New()),
99 myFilter(vtkWindowToImageFilter::New()),
100 myWriterMgr(new VVTK_ImageWriterMgr),
101 myNbWrittenFrames(0),
102 myNameAVIMaker("jpeg2yuv")
104 myCommand->SetClientData(this);
105 myCommand->SetCallback(VVTK_Recorder::ProcessEvents);
109 //----------------------------------------------------------------------------
119 //----------------------------------------------------------------------------
122 ::CheckExistAVIMaker()
126 ostringstream aStream;
127 aStream<<"which "<<myNameAVIMaker<<" >& /dev/null";
128 std::string anAVIMakeCheck = aStream.str();
129 int iErr = system(anAVIMakeCheck.c_str());
135 //----------------------------------------------------------------------------
138 ::SetName(const char* theName)
144 VVTK_Recorder::Name() const
146 return myName.c_str();
150 //----------------------------------------------------------------------------
153 ::SetNbFPS(const double theNbFPS)
166 //----------------------------------------------------------------------------
169 ::SetQuality(int theQuality)
171 myQuality = theQuality;
182 //----------------------------------------------------------------------------
185 ::SetRenderWindow(vtkRenderWindow* theRenderWindow)
187 myRenderWindow = theRenderWindow;
194 return myRenderWindow;
198 //----------------------------------------------------------------------------
201 ::SetProgressiveMode(bool theProgressiveMode)
203 myProgressiveMode = theProgressiveMode;
208 ::GetProgressiveMode() const
210 return myProgressiveMode;
214 //----------------------------------------------------------------------------
217 ::SetUseSkippedFrames(bool theUseSkippedFrames)
219 myUseSkippedFrames = theUseSkippedFrames;
224 ::UseSkippedFrames() const
226 return myUseSkippedFrames;
230 //----------------------------------------------------------------------------
233 ::ErrorStatus() const
235 return myErrorStatus;
246 //----------------------------------------------------------------------------
249 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
250 unsigned long theEvent,
252 void* vtkNotUsed(theCallData))
254 if(vtkObject* anObj = reinterpret_cast<vtkObject*>(theClientData)){
255 if(VVTK_Recorder* aSelf = dynamic_cast<VVTK_Recorder*>(anObj)){
256 if(theEvent==vtkCommand::EndEvent){
257 if(aSelf->State() == VVTK_Recorder::VVTK_Recorder_Record){
266 //----------------------------------------------------------------------------
271 if(myState == VVTK_Recorder_Stop){
273 myState = VVTK_Recorder_Record;
274 myFilter->SetInput(myRenderWindow);
276 myNbWrittenFrames = 0;
277 myRenderWindow->RemoveObserver(myCommand);
278 myRenderWindow->AddObserver(vtkCommand::EndEvent,
281 myRenderWindow->Render();
287 //----------------------------------------------------------------------------
292 QApplication::setOverrideCursor( Qt::waitCursor );
294 if(myState == VVTK_Recorder_Record){
300 if(myUseSkippedFrames)
303 myFrameIndexes.clear();
307 myState = VVTK_Recorder_Stop;
310 QApplication::restoreOverrideCursor();
314 //----------------------------------------------------------------------------
319 myPaused = myPaused ? 0 : 1;
320 if(myPaused && !myFrameIndexes.empty()){
321 myFrameIndexes.back() *= -1;
322 if(MYDEBUG) cout<<"VVTK_Recorder::Pause - myFrameIndexes.back() = "<<myFrameIndexes.back()<<endl;
327 //----------------------------------------------------------------------------
330 GetFrameIndex(double theStartTime,
333 double aTimeNow = vtkTimerLog::GetCurrentTime();
334 double aDelta = aTimeNow - theStartTime;
335 return int(aDelta*theFPS);
345 if(myFrameIndex < 0){
347 myTimeStart = vtkTimerLog::GetCurrentTime();
349 int aFrameIndex = GetFrameIndex(myTimeStart,myNbFPS);
350 if(aFrameIndex <= myFrameIndex)
353 // If there was a "pause" we correct the myTimeStart
354 int aLastFrameIndex = myFrameIndexes.back();
355 if(aLastFrameIndex < 0){
356 myFrameIndexes.back() = abs(myFrameIndexes.back());
357 double aPauseTime = fabs((double)(aFrameIndex - myFrameIndex - 1)) / myNbFPS;
359 cout<<"VVTK_Recorder::DoRecord - aFrameIndex = "<<aFrameIndex<<
360 "; aPauseTime = "<<aPauseTime<<endl;
361 myTimeStart += aPauseTime;
364 aFrameIndex = GetFrameIndex(myTimeStart,myNbFPS);
365 if(aFrameIndex <= myFrameIndex)
368 myFrameIndex = aFrameIndex;
371 myFrameIndexes.push_back(myFrameIndex);
372 if(MYDEBUG) cout<<"VVTK_Recorder::DoRecord - myFrameIndex = "<<myFrameIndex<<endl;
374 myRenderWindow->RemoveObserver(myCommand);
375 myFilter->Modified();
378 GetNameJPEG(myName,myFrameIndex,aName);
382 vtkImageData *anImageData = vtkImageData::New();
383 anImageData->DeepCopy(myFilter->GetOutput());
385 myWriterMgr->StartImageWriter(anImageData,aName,myProgressiveMode,myQuality);
388 myRenderWindow->AddObserver(vtkCommand::EndEvent,
394 //----------------------------------------------------------------------------
399 vtkImageData *anImageData = myFilter->GetOutput();
405 anImageData->UpdateInformation();
406 int *anExtent = anImageData->GetWholeExtent();
407 anImageData->SetUpdateExtent(anExtent[0], anExtent[1],
408 anExtent[2], anExtent[3],
410 anImageData->UpdateData();
414 //----------------------------------------------------------------------------
421 if(myFrameIndexes.size() < 2)
424 size_t anId = 0, anEnd = myFrameIndexes.size() - 1;
425 for(; anId < anEnd; anId++){
426 int aStartIndex = myFrameIndexes[anId];
430 int aFinishIndex = abs(myFrameIndexes[anId + 1]);
431 if(aStartIndex + 1 == aFinishIndex)
434 std::string anInitialName;
435 std::ostringstream aStream;
436 GetNameJPEG(myName,aStartIndex,anInitialName);
437 for(int anIndex = aStartIndex + 1; anIndex < aFinishIndex; anIndex++){
439 std::string anCurrentName;
440 GetNameJPEG(myName,anIndex,anCurrentName);
441 aStream<<"ln -s "<< anInitialName<<" "<<anCurrentName<<";";
442 if(anIndex + 1 < aFinishIndex)
446 std::string aString(aStream.str());
447 system(aString.c_str());
448 if(MYDEBUG) cout<<"VVTK_Recorder::AddSkippedFrames - "<<aString<<endl;
453 //----------------------------------------------------------------------------
459 std::ostringstream aStream;
460 aStream<<myNameAVIMaker<<
463 //" -f "<<int(myNbFPS)<<" "<<
464 " -f "<<myNbFPS<<" "<<
465 " -n "<<myNbWrittenFrames<<" "<<
466 " -j "<<myName<<"_\%06d.jpeg "<<
470 std::string aString(aStream.str());
471 myErrorStatus = system(aString.c_str());
473 if(MYDEBUG) cout<<"VVTK_Recorder::MakeFileAVI - "<<aString<<endl;
475 QFileInfo aFileInfo(myName.c_str());
476 QString aDirPath = aFileInfo.dirPath(TRUE);
477 QString aBaseName = aFileInfo.fileName();
479 QString("(cd ") + aDirPath +
481 " | egrep '" + aBaseName + "_[0-9]*.jpeg'" +
486 QString("rm ") + aDirPath + "/" + aBaseName + "*.jpeg";
488 if(MYDEBUG) cout<<"VVTK_Recorder::MakeFileAVI - "<<aCommand.latin1()<<endl;
489 system(aCommand.latin1());