1 // SALOME VTKViewer : build VTK viewer into Salome desktop
\r
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
\r
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
\r
6 // This library is free software; you can redistribute it and/or
\r
7 // modify it under the terms of the GNU Lesser General Public
\r
8 // License as published by the Free Software Foundation; either
\r
9 // version 2.1 of the License.
\r
11 // This library is distributed in the hope that it will be useful,
\r
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
14 // Lesser General Public License for more details.
\r
16 // You should have received a copy of the GNU Lesser General Public
\r
17 // License along with this library; if not, write to the Free Software
\r
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
\r
29 #include "VVTK_Recorder.h"
\r
31 #include "VVTK_ImageWriter.h"
\r
32 #include "VVTK_ImageWriterMgr.h"
\r
34 #include <vtkObjectFactory.h>
\r
35 #include <vtkObject.h>
\r
36 #include <vtkCallbackCommand.h>
\r
37 #include <vtkRenderWindow.h>
\r
38 #include <vtkTimerLog.h>
\r
39 #include <vtkWindowToImageFilter.h>
\r
40 #include <vtkJPEGWriter.h>
\r
41 #include <vtkImageData.h>
\r
48 #include <qapplication.h>
\r
49 #include <qfileinfo.h>
\r
51 #include "utilities.h"
\r
54 static int MYDEBUG = 0;
\r
56 static int MYDEBUG = 0;
\r
62 //----------------------------------------------------------------------------
\r
65 GetNameJPEG(const std::string& thePreffix,
\r
67 std::string& theName)
\r
69 using namespace std;
\r
70 ostringstream aStream;
\r
71 aStream<<thePreffix<<"_"<<setw(6)<<setfill('0')<<theIndex<<".jpeg";
\r
72 theName = aStream.str();
\r
76 //----------------------------------------------------------------------------
\r
77 vtkCxxRevisionMacro(VVTK_Recorder,"$Revision$");
\r
78 vtkStandardNewMacro(VVTK_Recorder);
\r
81 //----------------------------------------------------------------------------
\r
84 myRenderWindow(NULL),
\r
85 myState(VVTK_Recorder_Stop),
\r
88 myProgressiveMode(true),
\r
89 myUseSkippedFrames(true),
\r
91 myCommand(vtkCallbackCommand::New()),
\r
96 myFilter(vtkWindowToImageFilter::New()),
\r
97 myWriterMgr(new VVTK_ImageWriterMgr),
\r
98 myNbWrittenFrames(0),
\r
99 myNameAVIMaker("jpeg2yuv")
\r
101 myCommand->SetClientData(this);
\r
102 myCommand->SetCallback(VVTK_Recorder::ProcessEvents);
\r
106 //----------------------------------------------------------------------------
\r
110 myCommand->Delete();
\r
111 myFilter->Delete();
\r
112 delete myWriterMgr;
\r
116 //----------------------------------------------------------------------------
\r
119 ::CheckExistAVIMaker()
\r
122 using namespace std;
\r
123 ostringstream aStream;
\r
124 aStream<<"which "<<myNameAVIMaker<<" >& /dev/null";
\r
125 std::string anAVIMakeCheck = aStream.str();
\r
126 int iErr = system(anAVIMakeCheck.c_str());
\r
128 myErrorStatus = 127;
\r
132 //----------------------------------------------------------------------------
\r
135 ::SetName(const char* theName)
\r
141 VVTK_Recorder::Name() const
\r
143 return myName.c_str();
\r
147 //----------------------------------------------------------------------------
\r
150 ::SetNbFPS(const double theNbFPS)
\r
152 myNbFPS = theNbFPS;
\r
163 //----------------------------------------------------------------------------
\r
166 ::SetQuality(int theQuality)
\r
168 myQuality = theQuality;
\r
173 ::GetQuality() const
\r
179 //----------------------------------------------------------------------------
\r
182 ::SetRenderWindow(vtkRenderWindow* theRenderWindow)
\r
184 myRenderWindow = theRenderWindow;
\r
191 return myRenderWindow;
\r
195 //----------------------------------------------------------------------------
\r
198 ::SetProgressiveMode(bool theProgressiveMode)
\r
200 myProgressiveMode = theProgressiveMode;
\r
205 ::GetProgressiveMode() const
\r
207 return myProgressiveMode;
\r
211 //----------------------------------------------------------------------------
\r
214 ::SetUseSkippedFrames(bool theUseSkippedFrames)
\r
216 myUseSkippedFrames = theUseSkippedFrames;
\r
221 ::UseSkippedFrames() const
\r
223 return myUseSkippedFrames;
\r
227 //----------------------------------------------------------------------------
\r
230 ::ErrorStatus() const
\r
232 return myErrorStatus;
\r
243 //----------------------------------------------------------------------------
\r
246 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
\r
247 unsigned long theEvent,
\r
248 void* theClientData,
\r
249 void* vtkNotUsed(theCallData))
\r
251 if(vtkObject* anObj = reinterpret_cast<vtkObject*>(theClientData)){
\r
252 if(VVTK_Recorder* aSelf = dynamic_cast<VVTK_Recorder*>(anObj)){
\r
253 if(theEvent==vtkCommand::EndEvent){
\r
254 if(aSelf->State() == VVTK_Recorder::VVTK_Recorder_Record){
\r
263 //----------------------------------------------------------------------------
\r
268 if(myState == VVTK_Recorder_Stop){
\r
269 if(myRenderWindow){
\r
270 myState = VVTK_Recorder_Record;
\r
271 myFilter->SetInput(myRenderWindow);
\r
273 myNbWrittenFrames = 0;
\r
274 myRenderWindow->RemoveObserver(myCommand);
\r
275 myRenderWindow->AddObserver(vtkCommand::EndEvent,
\r
278 myRenderWindow->Render();
\r
284 //----------------------------------------------------------------------------
\r
289 QApplication::setOverrideCursor( Qt::waitCursor );
\r
291 if(myState == VVTK_Recorder_Record){
\r
295 myWriterMgr->Stop();
\r
297 if(myUseSkippedFrames)
\r
298 AddSkippedFrames();
\r
300 myFrameIndexes.clear();
\r
304 myState = VVTK_Recorder_Stop;
\r
307 QApplication::restoreOverrideCursor();
\r
311 //----------------------------------------------------------------------------
\r
316 myPaused = myPaused ? 0 : 1;
\r
317 if(myPaused && !myFrameIndexes.empty()){
\r
318 size_t aLastId = myFrameIndexes.size() - 1;
\r
319 myFrameIndexes[aLastId] *= -1;
\r
324 //----------------------------------------------------------------------------
\r
332 if(myFrameIndex < 0){
\r
334 myTimeStart = vtkTimerLog::GetCurrentTime();
\r
336 double aTimeNow = vtkTimerLog::GetCurrentTime();
\r
337 double aDelta = aTimeNow - myTimeStart;
\r
341 int aFrameIndex = int(aDelta*myNbFPS);
\r
342 if(aFrameIndex == myFrameIndex)
\r
345 myFrameIndex = aFrameIndex;
\r
348 myFrameIndexes.push_back(myFrameIndex);
\r
349 if(MYDEBUG) cout<<"VVTK_Recorder::DoRecord - myFrameIndex = "<<myFrameIndex<<endl;
\r
351 myRenderWindow->RemoveObserver(myCommand);
\r
352 myFilter->Modified();
\r
355 GetNameJPEG(myName,myFrameIndex,aName);
\r
359 vtkImageData *anImageData = vtkImageData::New();
\r
360 anImageData->DeepCopy(myFilter->GetOutput());
\r
362 myWriterMgr->StartImageWriter(anImageData,aName,myProgressiveMode,myQuality);
\r
363 myNbWrittenFrames++;
\r
365 myRenderWindow->AddObserver(vtkCommand::EndEvent,
\r
371 //----------------------------------------------------------------------------
\r
376 vtkImageData *anImageData = myFilter->GetOutput();
\r
379 myErrorStatus = 20;
\r
382 anImageData->UpdateInformation();
\r
383 int *anExtent = anImageData->GetWholeExtent();
\r
384 anImageData->SetUpdateExtent(anExtent[0], anExtent[1],
\r
385 anExtent[2], anExtent[3],
\r
387 anImageData->UpdateData();
\r
391 //----------------------------------------------------------------------------
\r
394 ::AddSkippedFrames()
\r
398 if(myFrameIndexes.size() < 2)
\r
401 size_t anId = 0, anEnd = myFrameIndexes.size() - 1;
\r
402 for(; anId < anEnd; anId++){
\r
403 int aStartIndex = myFrameIndexes[anId];
\r
404 if(aStartIndex < 0)
\r
407 int aFinishIndex = abs(myFrameIndexes[anId + 1]);
\r
408 if(aStartIndex + 1 == aFinishIndex)
\r
411 std::string anInitialName;
\r
412 std::ostringstream aStream;
\r
413 GetNameJPEG(myName,aStartIndex,anInitialName);
\r
414 for(int anIndex = aStartIndex + 1; anIndex < aFinishIndex; anIndex++){
\r
415 myNbWrittenFrames++;
\r
416 std::string anCurrentName;
\r
417 GetNameJPEG(myName,anIndex,anCurrentName);
\r
418 aStream<<"ln -s "<< anInitialName<<" "<<anCurrentName<<";";
\r
419 if(anIndex + 1 < aFinishIndex)
\r
423 std::string aString(aStream.str());
\r
424 system(aString.c_str());
\r
425 if(MYDEBUG) cout<<"VVTK_Recorder::AddSkippedFrames - "<<aString<<endl;
\r
430 //----------------------------------------------------------------------------
\r
436 std::ostringstream aStream;
\r
437 aStream<<myNameAVIMaker<<
\r
440 //" -f "<<int(myNbFPS)<<" "<<
\r
441 " -f "<<myNbFPS<<" "<<
\r
442 " -n "<<myNbWrittenFrames<<" "<<
\r
443 " -j "<<myName<<"_\%06d.jpeg "<<
\r
447 std::string aString(aStream.str());
\r
448 myErrorStatus = system(aString.c_str());
\r
450 if(MYDEBUG) cout<<"VVTK_Recorder::MakeFileAVI - "<<aString<<endl;
\r
452 QFileInfo aFileInfo(myName);
\r
453 QString aDirPath = aFileInfo.dirPath(TRUE);
\r
454 QString aBaseName = aFileInfo.fileName();
\r
455 QString aCommand =
\r
456 QString("(cd ") + aDirPath +
\r
458 " | egrep '" + aBaseName + "_[0-9]*.jpeg'" +
\r
462 if(MYDEBUG) cout<<"VVTK_Recorder::MakeFileAVI - "<<aCommand.latin1()<<endl;
\r
463 system(aCommand.latin1());
\r