1 // Copyright (C) 2003 CEA/DEN, EDF R&D
5 // File : VISU_TimeAnimation.cxx
6 // Author : Vitaly SMETANNIKOV
9 #include "VISU_TimeAnimation.h"
11 #include "VISUConfig.hh"
13 #include "VISU_Result_i.hh"
14 #include "VISU_Prs3d_i.hh"
15 #include "VISU_Mesh_i.hh"
16 #include "VISU_ScalarMap_i.hh"
17 #include "VISU_IsoSurfaces_i.hh"
18 #include "VISU_DeformedShape_i.hh"
19 #include "VISU_ScalarMapOnDeformedShape_i.hh"
20 #include "VISU_CutPlanes_i.hh"
21 #include "VISU_Plot3D_i.hh"
22 #include "VISU_CutLines_i.hh"
23 #include "VISU_Vectors_i.hh"
24 #include "VISU_StreamLines_i.hh"
25 #include "VISU_GaussPoints_i.hh"
26 #include "VISU_ViewManager_i.hh"
27 #include "VISU_View_i.hh"
29 #include "VISU_ScalarBarActor.hxx"
30 #include "VISU_Actor.h"
32 #include "SalomeApp_Study.h"
34 #include "SVTK_ViewWindow.h"
36 #include "SALOME_Event.hxx"
38 #include "SUIT_ResourceMgr.h"
39 #include "SUIT_Application.h"
40 #include "SUIT_Session.h"
41 #include "SUIT_Study.h"
43 #include "SALOMEDSClient_AttributeComment.hxx"
44 #include "SALOMEDSClient_AttributeName.hxx"
45 #include "CASCatch.hxx"
55 //------------------------------------------------------------------------
56 VISU_TimeAnimation::VISU_TimeAnimation (_PTR(Study) theStudy,
57 VISU::View3D_ptr theView3D)
63 myProportional = false;
66 if (!CORBA::is_nil(theView3D)) {
67 VISU::View3D_i* pView = dynamic_cast<VISU::View3D_i*>(GetServant(theView3D).in());
68 SUIT_ViewWindow* aVW = pView->GetViewWindow();
69 myView = dynamic_cast<SVTK_ViewWindow*>(aVW);
70 connect( myView, SIGNAL( destroyed() ), this, SLOT( onViewDeleted() ) );
83 myAVIMaker = "jpeg2yuv";
87 //------------------------------------------------------------------------
88 VISU_TimeAnimation::~VISU_TimeAnimation()
91 MESSAGE("Viewer is not defined for animation");
95 for (int i = 0; i < getNbFields(); i++) {
96 clearData(myFieldsLst[i]);
99 /* Terminates the execution of the thread.
100 * The thread may or may not be terminated immediately,
101 * depending on the operating system's scheduling policies.
103 * Use QThread::wait() after terminate() for synchronous termination.
105 * When the thread is terminated, all threads waiting for the the thread to finish will be woken up.
107 * Warning: This function is dangerous, and its use is discouraged.
108 * The thread can be terminated at any point in its code path.
109 * Threads can be terminated while modifying data.
110 * There is no chance for the thread to cleanup after itself,
111 * unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
115 QThread::terminate();
120 //------------------------------------------------------------------------
121 void VISU_TimeAnimation::addField (_PTR(SObject) theField)
124 aNewData.myField = theField;
125 aNewData.myNbFrames = 0;
126 aNewData.myPrsType = VISU::TSCALARMAP;
127 aNewData.myOffset[0] = aNewData.myOffset[1] = aNewData.myOffset[2] = 0;
128 VISU::Storable::TRestoringMap aMap = getMapOfValue(aNewData.myField);
129 aNewData.myNbTimes = VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
130 myFieldsLst.append(aNewData);
132 //find Min/Max timestamps
133 if ((myTimeMin == 0) && (myTimeMax == 0)) {
134 _PTR(ChildIterator) anIter = myStudy->NewChildIterator(theField);
135 anIter->Next(); // First is reference on support
136 myTimeMin = getTimeValue(anIter->Value());
137 for(; anIter->More(); anIter->Next()) {
138 myTimeMax = getTimeValue(anIter->Value());
143 //------------------------------------------------------------------------
144 void VISU_TimeAnimation::addField (SALOMEDS::SObject_ptr theField)
146 SALOMEDS::SObject_var theFieldDup = SALOMEDS::SObject::_duplicate(theField);
147 _PTR(SObject) aField = VISU::GetClientSObject(theFieldDup, myStudy);
152 //------------------------------------------------------------------------
153 void VISU_TimeAnimation::clearData(FieldData& theData) {
155 MESSAGE("Viewer is not defined for animation");
158 theData.myTiming.clear();
159 vtkRenderer* aRen = myView->getRenderer();
160 if (!theData.myActors.empty()) {
161 for (int i = 0, iEnd = theData.myActors.size(); i < iEnd; i++) {
162 if (theData.myActors[i] != 0) {
163 theData.myActors[i]->RemoveFromRender(aRen);
166 theData.myActors.clear();
168 if (!theData.myPrs.empty()) {
169 for (int i = 0, iEnd = theData.myPrs.size(); i < iEnd; i++)
170 if (theData.myPrs[i] != 0) {
171 theData.myPrs[i]->_remove_ref();
173 theData.myPrs.clear();
175 theData.myNbFrames = 0;
182 //------------------------------------------------------------------------
183 template<class TPrs3d>
185 GeneratePresentations(_PTR(Study) theStudy,
187 VISU::Result_i* theResult,
188 bool theIsRangeDefined,
189 CORBA::Double theTimeMin,
190 CORBA::Double theTimeMax)
192 double aMin = VTK_LARGE_FLOAT, aMax = -VTK_LARGE_FLOAT;
194 _PTR(ChildIterator) anIter = theStudy->NewChildIterator(theData.myField);
195 anIter->Next(); // First is reference on support
198 for(; anIter->More(); anIter->Next()){
199 if (aFrameId == theData.myNbTimes) {
200 MESSAGE("There are extra timestamps in field");
203 _PTR(SObject) aTimeStamp = anIter->Value();
207 theData.myTiming[aFrameId] = VISU_TimeAnimation::getTimeValue(aTimeStamp);
208 if (theIsRangeDefined) {
209 if (theData.myTiming[aFrameId] < theTimeMin)
211 if (theData.myTiming[aFrameId] > theTimeMax)
215 VISU::Storable::TRestoringMap aTimeMap = VISU_TimeAnimation::getMapOfValue(aTimeStamp);
216 QString aMeshName = VISU::Storable::FindValue(aTimeMap,"myMeshName");
217 VISU::Entity anEntity = (VISU::Entity) VISU::Storable::FindValue(aTimeMap,"myEntityId").toInt();
218 QString aFieldName = VISU::Storable::FindValue(aTimeMap,"myFieldName");
219 int aTimeStampId = VISU::Storable::FindValue(aTimeMap,"myTimeStampId").toInt();
221 bool anIsCreated = false;
222 TPrs3d* aPresent = new TPrs3d(theResult, false);
225 if(aPresent->Create(aMeshName.latin1(),anEntity,aFieldName.latin1(),aTimeStampId)){
227 theData.myPrs[aFrameId++] = aPresent;
228 aMin = std::min(aPresent->GetMin(), aMin);
229 aMax = std::max(aPresent->GetMax(), aMax);
231 }catch(std::exception& exc){
232 INFOS("Follow exception was occured :\n"<<exc.what());
234 INFOS("Unknown exception was occured!");
236 }CASCatch_CATCH(Standard_Failure) {
237 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
238 INFOS("Follow signal was occured :\n"<<aFail->GetMessageString());
241 aPresent->_remove_ref();
243 theData.myNbFrames = aFrameId;
245 if (theData.myPrsType != VISU::TGAUSSPOINTS){
246 int aRangeType = VISU::GetResourceMgr()->integerValue("VISU" , "scalar_range_type", 0);
247 if( aRangeType != 1 ){
248 for(long aFrameId = 0; aFrameId < theData.myNbFrames; aFrameId++) {
249 if (VISU::ScalarMap_i* aPrs = dynamic_cast<VISU::ScalarMap_i*>(theData.myPrs[aFrameId])){
250 aPrs->SetRange(aMin, aMax);
251 aPrs->SetOffset(theData.myOffset);
255 if (theData.myPrsType == VISU::TISOSURFACE)
256 for (long aFrameId = 0; aFrameId < theData.myNbFrames; aFrameId++)
257 if (VISU::IsoSurfaces_i* aPrs = dynamic_cast<VISU::IsoSurfaces_i*>(theData.myPrs[aFrameId]))
258 aPrs->SetSubRange(aMin, aMax);
263 void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
264 FieldData& aData = myFieldsLst[theFieldNum];
266 // Delete previous presentations
269 VISU::Result_i* aResult = createPresent(aData.myField);
270 VISU::Storable::TRestoringMap aMap = getMapOfValue(aData.myField);
271 aData.myNbFrames = aData.myNbTimes;
272 //VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
274 aData.myPrs.resize(aData.myNbTimes,NULL);
275 aData.myTiming.resize(aData.myNbTimes);
277 using namespace VISU;
278 switch (aData.myPrsType) {
279 case VISU::TSCALARMAP: // ScalarMap
280 GeneratePresentations<ScalarMap_i>(myStudy,
287 case VISU::TISOSURFACE: // Iso Surfaces
288 GeneratePresentations<IsoSurfaces_i>(myStudy,
295 case VISU::TCUTPLANES: // Cut Planes
296 GeneratePresentations<CutPlanes_i>(myStudy,
303 case VISU::TCUTLINES: // Cut Lines
304 GeneratePresentations<CutLines_i>(myStudy,
311 case VISU::TPLOT3D: // Plot3d
312 GeneratePresentations<Plot3D_i>(myStudy,
319 case VISU::TDEFORMEDSHAPE: // Deformed Shape
320 GeneratePresentations<DeformedShape_i>(myStudy,
327 case VISU::TVECTORS: // Vectors
328 GeneratePresentations<Vectors_i>(myStudy,
335 case VISU::TSTREAMLINES: // Stream Lines
336 GeneratePresentations<StreamLines_i>(myStudy,
343 case VISU::TGAUSSPOINTS: // Gauss Points
344 GeneratePresentations<GaussPoints_i>(myStudy,
351 case VISU::TSCALARMAPONDEFORMEDSHAPE: // Scalar map on deformed shape
352 GeneratePresentations<ScalarMapOnDeformedShape_i>(myStudy,
360 MESSAGE("Not implemented for this presentation type: " << aData.myPrsType);
366 //------------------------------------------------------------------------
367 CORBA::Boolean VISU_TimeAnimation::generateFrames() {
369 MESSAGE("Viewer is not defined for animation");
373 myLastError = QString("Frame(s) for ");
374 bool aNoError = true;
378 for (int i = 0; i < getNbFields(); i++) {
379 FieldData& aData = myFieldsLst[i];
380 aData.myActors.resize(aData.myNbFrames,NULL);
381 for (long j = 0; j < aData.myNbFrames; j++) {
382 VISU_Actor* aActor = NULL;
384 aData.myPrs[j]->SetOffset(aData.myOffset);
385 aActor = aData.myPrs[j]->CreateActor();
386 myView->AddActor(aActor);
388 aActor->VisibilityOn();
390 aActor->VisibilityOff();
391 }catch(...){ //catch(std::runtime_error& exc){
393 myLastError += QString("%1 ").arg(aData.myTiming[j]);
395 aData.myActors[j] = aActor;
399 myLastError += QString(" timestamp(s) cannot be created.");
400 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
405 //------------------------------------------------------------------------
406 void VISU_TimeAnimation::clearView() {
408 MESSAGE("Viewer is not defined for animation");
411 vtkRenderer* aRen = myView->getRenderer();
412 for (int i = 0; i < getNbFields(); i++) {
413 FieldData& aData = myFieldsLst[i];
414 if (!aData.myActors.empty()) {
415 for (int i = 0, iEnd = aData.myActors.size(); i < iEnd; i++) {
416 if (aData.myActors[i] != 0) {
417 aData.myActors[i]->RemoveFromRender(aRen);
420 aData.myActors.clear();
423 VISU::RepaintView(myView);
426 //------------------------------------------------------------------------
427 void VISU_TimeAnimation::stopAnimation() {
431 //------------------------------------------------------------------------
432 void VISU_TimeAnimation::startAnimation() {
439 //------------------------------------------------------------------------
440 void VISU_TimeAnimation::nextFrame() {
442 MESSAGE("Viewer is not defined for animation");
446 if (myFrame < (myFieldsLst[0].myNbFrames-1)) {
448 for (i = 0; i < getNbFields(); i++)
449 if (myFieldsLst[i].myActors[myFrame] != 0)
450 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
453 for (i = 0; i < getNbFields(); i++)
454 if (myFieldsLst[i].myActors[myFrame] != 0)
455 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
457 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
462 //------------------------------------------------------------------------
463 void VISU_TimeAnimation::prevFrame() {
465 MESSAGE("Viewer is not defined for animation");
471 for (i = 0; i < getNbFields(); i++)
472 if (myFieldsLst[i].myActors[myFrame] != 0)
473 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
476 for (i = 0; i < getNbFields(); i++)
477 if (myFieldsLst[i].myActors[myFrame] != 0)
478 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
480 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
485 //------------------------------------------------------------------------
486 void VISU_TimeAnimation::firstFrame() {
488 MESSAGE("Viewer is not defined for animation");
493 for (i = 0; i < getNbFields(); i++)
494 if(!myFieldsLst[i].myActors.empty())
495 if (myFieldsLst[i].myActors[myFrame] != 0)
496 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
498 for (i = 0; i < getNbFields(); i++)
499 if(!myFieldsLst[i].myActors.empty())
500 if (myFieldsLst[i].myActors[myFrame] != 0)
501 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
502 if(!myFieldsLst[0].myTiming.empty()){
503 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
508 //------------------------------------------------------------------------
509 void VISU_TimeAnimation::lastFrame() {
511 MESSAGE("Viewer is not defined for animation");
516 for (i = 0; i < getNbFields(); i++)
517 if (myFieldsLst[i].myActors[myFrame] != 0)
518 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
520 myFrame = myFieldsLst[0].myNbFrames-1;
521 for (i = 0; i < getNbFields(); i++)
522 if (myFieldsLst[i].myActors[myFrame] != 0)
523 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
525 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
530 //------------------------------------------------------------------------
531 // For Batchmode using
532 void VISU_TimeAnimation::gotoFrame(CORBA::Long theFrame) {
534 MESSAGE("Viewer is not defined for animation");
537 if ((theFrame < 0) || (theFrame > (getNbFrames()-1)))
543 for (i = 0; i < getNbFields(); i++)
544 if (myFieldsLst[i].myActors[myFrame] != 0)
545 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
548 for (i = 0; i < getNbFields(); i++)
549 if (myFieldsLst[i].myActors[myFrame] != 0)
550 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
552 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
555 qApp->processEvents(3);
560 //------------------------------------------------------------------------
561 VISU::ColoredPrs3d_ptr VISU_TimeAnimation::getPresentation(CORBA::Long theField, CORBA::Long theFrame) {
562 if ((theField > getNbFields()) || (theField < 0))
563 return VISU::ColoredPrs3d::_nil();
564 if ((theFrame < 0) || (theFrame > (myFieldsLst[theField].myNbFrames - 1)))
565 return VISU::ColoredPrs3d::_nil();
566 return myFieldsLst[theField].myPrs[theFrame]->_this();
570 //------------------------------------------------------------------------
571 CORBA::Long VISU_TimeAnimation::getNbFrames() {
572 return (getNbFields() > 0)? myFieldsLst[0].myNbFrames : 0;
576 //------------------------------------------------------------------------
577 void VISU_TimeAnimation::run()
580 MESSAGE("Viewer is not defined for animation");
584 bool isDumping = !myDumpPath.isEmpty();
586 if (myFieldsLst[0].myNbFrames > 2)
587 aOneVal = myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0];
590 QValueList<int> anIndexList;
594 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
595 if(!(myFieldsLst[0].myField))
597 for (int i = 0; i < getNbFields(); i++) {
598 FieldData& aData = myFieldsLst[i];
600 if (aData.myActors[myFrame-1] != 0)
601 aData.myActors[myFrame-1]->VisibilityOff();
603 if (aData.myActors[aData.myNbFrames-1] != 0)
604 aData.myActors[aData.myNbFrames-1]->VisibilityOff();
606 if (aData.myActors[myFrame] != 0) {
607 aData.myActors[myFrame]->VisibilityOn();
610 myView->Repaint(false);
613 if (myProportional) {
618 if (myFieldsLst[0].myNbFrames > 2)
619 k = (myFieldsLst[0].myTiming[myFrame+1] -
620 myFieldsLst[0].myTiming[myFrame]) / aOneVal;
623 if (myFrame < (myFieldsLst[0].myNbFrames - 1))
624 k = (myFieldsLst[0].myTiming[myFrame+1] -
625 myFieldsLst[0].myTiming[myFrame]) / aOneVal;
628 int delay = (int)(1000. * k / mySpeed);
629 isDumping = !myDumpPath.isEmpty();
630 if (delay < 1 && isDumping) {
631 // We must unlock mutex for some time before grabbing to allow view updating
639 // We must unlock mutex for some time before grabbing to allow view updating
643 if(!(myFieldsLst[0].myField)) // break, if field was deleted.
645 if (myDumpFormat.compare("AVI") != 0) {
646 QString aFile(myDumpPath);
647 QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
649 while ((aPos = aName.find(".")) > -1 )
650 aName.replace(aPos, 1, "_");
653 aFile += myDumpFormat.lower();
654 myView->dumpViewToFormat(aFile,myDumpFormat);
656 QFileInfo aFileInfo(myDumpPath);
657 QString aDirPath = aFileInfo.dirPath(true);
658 QString aBaseName = aFileInfo.fileName();
667 if (myProportional) {
668 double p = (myFieldsLst[0].myTiming[myFrame] -
669 myFieldsLst[0].myTiming[myFrame-1]) / aOneVal;
670 myFileIndex += (long) (5*p);
676 QString aFile = aDirPath + QDir::separator() + aBaseName;
678 aFile += QString("%1").arg(myFileIndex).rightJustify(8, '0');
681 /* check image size is divisable 16
682 myView->dumpViewToFormat(aFile,"JPEG");
684 SUIT_ViewWindow* aView = myView;
685 QImage img = aView->dumpView();
687 int width = img.width(); width = (width/16)*16;
688 int height = img.height(); height = (height/16)*16;
689 QImage copy = img.copy(0, 0, width, height);
690 if (copy.save(aFile, "JPEG")) {
691 anIndexList.append(myFileIndex);
698 if (!myIsActive) break;
701 if (myFrame == myFieldsLst[0].myNbFrames) {
711 // make AVI file if need
712 if (isDumping && myDumpFormat.compare("AVI") == 0) {
713 double aFPS = 17.3 * mySpeed;
715 QFileInfo aFileInfo(myDumpPath);
716 QString aDirPath = aFileInfo.dirPath(true);
717 QString aBaseName = aFileInfo.fileName();
720 if (anIndexList.count() > 1) {
721 QString aFFile = aDirPath + QDir::separator() + aBaseName;
722 aFFile += QString("_%1.jpeg");
723 int aStartIndex = anIndexList[0], anEndIndex;
724 for (int i = 1; i < anIndexList.count(); i++) {
725 anEndIndex = anIndexList[i];
726 QString aCurFile = aFFile.arg(QString::number(aStartIndex).rightJustify(8, '0'));
727 QStringList aCommands;
728 for (int j = aStartIndex+1; j < anEndIndex; j++) {
729 QString aFile = aFFile.arg(QString::number(j).rightJustify(8, '0'));
730 aCommands.append(QString("ln -s %1 %2").arg(aCurFile).arg(aFile));
732 system(aCommands.join(" ; \\\n").latin1());
733 aStartIndex = anEndIndex;
738 QString aPattern = aDirPath + QDir::separator() + aBaseName;
739 aPattern += "_\%08d.jpeg";
741 QString aCmd = myAVIMaker;
744 aCmd += QString(" -f %1").arg(aFPS);
745 // aCmd += QString(" -n %1").arg(aNbFiles);
746 aCmd += QString(" -n %1").arg(myFileIndex+1);
747 aCmd += QString(" -j %1").arg(aPattern);
748 aCmd += " | yuv2lav";
749 aCmd += QString(" -o %1").arg(myDumpPath);
750 system(aCmd.latin1());
752 // remove temporary jpeg files
754 aCmd += QString("cd %1").arg(aDirPath);
756 aCmd += QString(" | egrep '%1_[0-9]*.jpeg'").arg(aBaseName);
757 aCmd += " | xargs rm";
759 system(aCmd.latin1());
767 //------------------------------------------------------------------------
768 VISU::Result_i* VISU_TimeAnimation::createPresent (_PTR(SObject) theField)
770 _PTR(SObject) aSObj = theField->GetFather();
771 aSObj = aSObj->GetFather();
772 aSObj = aSObj->GetFather();
773 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObj);
774 if (CORBA::is_nil(anObject)) return NULL;
775 return dynamic_cast<VISU::Result_i*>(VISU::GetServant(anObject).in());
778 //------------------------------------------------------------------------
779 VISU::Storable::TRestoringMap VISU_TimeAnimation::getMapOfValue (_PTR(SObject) theSObject)
781 VISU::Storable::TRestoringMap aMap;
783 _PTR(GenericAttribute) anAttr;
784 if (theSObject->FindAttribute(anAttr, "AttributeComment")) {
785 _PTR(AttributeComment) aComment (anAttr);
786 std::string aString = aComment->Value();
787 QString strIn (aString.c_str());
788 VISU::Storable::StrToMap(strIn, aMap);
794 //------------------------------------------------------------------------
795 double VISU_TimeAnimation::getTimeValue (_PTR(SObject) theTimeStamp)
797 _PTR(GenericAttribute) anAttr;
798 if (theTimeStamp->FindAttribute(anAttr, "AttributeName")) {
799 _PTR(AttributeName) aName (anAttr);
800 QString aNameString (aName->Value().c_str());
801 int time_len = aNameString.find(',');
803 return aNameString.left(time_len).toDouble();
805 return aNameString.toDouble();
810 //------------------------------------------------------------------------
811 void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed)
813 mySpeed = (theSpeed<1)? 1 : theSpeed;
816 std::string VISU_TimeAnimation::setDumpFormat(const char* theFormat)
818 myDumpFormat = theFormat;
819 QStrList aDumpFormats = QImageIO::outputFormats();
820 if (myDumpFormat.isEmpty() ||
821 (aDumpFormats.find(theFormat) < 0 && myDumpFormat.compare("AVI") != 0)) {
822 if (aDumpFormats.find("JPEG"))
823 myDumpFormat = "JPEG";
825 myDumpFormat = aDumpFormats.at(0);
827 return myDumpFormat.latin1();
830 //------------------------------------------------------------------------
831 bool VISU_TimeAnimation::checkAVIMaker() const
833 QStrList aDumpFormats = QImageIO::outputFormats();
834 if (aDumpFormats.find("JPEG") < 0) return false;
836 QString aCmd("which ");
838 aCmd += " >& /dev/null";
839 int iErr = system(aCmd.latin1());
843 //************************************************************************
844 int VISU_TimeAnimation::myNBAnimations = 0;
845 QString VISU_TimeAnimation::GenerateName()
847 return VISU::GenerateName("Animation", myNBAnimations++);
850 //------------------------------------------------------------------------
851 std::string GetPresentationComment (VISU::VISUType thePrsType)
854 switch (thePrsType) {
855 case VISU::TSCALARMAP:
856 aPrsCmt = VISU::ScalarMap_i::myComment;
858 case VISU::TISOSURFACE:
859 aPrsCmt = VISU::IsoSurfaces_i::myComment;
861 case VISU::TCUTPLANES:
862 aPrsCmt = VISU::CutPlanes_i::myComment;
864 case VISU::TCUTLINES:
865 aPrsCmt = VISU::CutLines_i::myComment;
868 aPrsCmt = VISU::Plot3D_i::myComment;
870 case VISU::TDEFORMEDSHAPE:
871 aPrsCmt = VISU::DeformedShape_i::myComment;
874 aPrsCmt = VISU::Vectors_i::myComment;
876 case VISU::TSTREAMLINES:
877 aPrsCmt = VISU::StreamLines_i::myComment;
879 case VISU::TGAUSSPOINTS:
880 aPrsCmt = VISU::GaussPoints_i::myComment;
882 case VISU::TSCALARMAPONDEFORMEDSHAPE:
883 aPrsCmt = VISU::ScalarMapOnDeformedShape_i::myComment;
886 aPrsCmt = "Unknown presentation";
892 //------------------------------------------------------------------------
893 SALOMEDS::SObject_ptr VISU_TimeAnimation::publishInStudy()
895 if (myStudy->GetProperties()->IsLocked())
896 return SALOMEDS::SObject::_nil();
898 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
899 aStudyBuilder->NewCommand(); // There is a transaction
900 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent(myStudy);
901 std::string aSComponentEntry = aSComponent->GetID();
904 aComment.sprintf("myComment=ANIMATION;myType=%d;myTimeMinVal=%g;myTimeMaxVal=%g",
905 VISU::TANIMATION,myTimeMinVal,myTimeMaxVal);
907 string anEntry = VISU::CreateAttributes(myStudy,aSComponentEntry.c_str(),"","",
908 GenerateName(),"",aComment,true);
909 myAnimEntry = anEntry.c_str();
910 _PTR(SObject) aAnimSObject = myStudy->FindObjectID(anEntry.c_str());
912 for (int i = 0; i < getNbFields(); i++) {
913 FieldData& aData = myFieldsLst[i];
915 _PTR(SObject) newObj = aStudyBuilder->NewObject(aAnimSObject);
916 aStudyBuilder->Addreference(newObj, aData.myField);
918 if (aData.myPrs.empty()) {
919 generatePresentations(i);
921 ostringstream strOut;
922 aData.myPrs[0]->ToStream(strOut);
923 string aPrsComment = strOut.str();
924 VISU::CreateAttributes(myStudy, newObj->GetID().c_str(),"","",
925 aData.myPrs[0]->GetComment(),"",aPrsComment.c_str(),true);
927 aStudyBuilder->CommitCommand();
929 return VISU::GetSObject(aAnimSObject);
932 //------------------------------------------------------------------------
933 void VISU_TimeAnimation::saveAnimation()
935 if (myStudy->GetProperties()->IsLocked()) return;
936 if (myAnimEntry.isEmpty()) return;
938 _PTR(SObject) aAnimSObject = myStudy->FindObjectID(myAnimEntry.latin1());
939 if (!aAnimSObject) return;
941 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
942 aStudyBuilder->NewCommand(); // There is a transaction
943 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent(myStudy);
944 std::string aSComponentEntry = aSComponent->GetID();
947 aComment.sprintf("myComment=ANIMATION;myType=%d;myTimeMinVal=%g;myTimeMaxVal=%g",
948 VISU::TANIMATION,myTimeMinVal,myTimeMaxVal);
950 _PTR(GenericAttribute) anAttr;
951 anAttr = aStudyBuilder->FindOrCreateAttribute(aAnimSObject, "AttributeComment");
952 _PTR(AttributeComment) aCmnt (anAttr);
953 aCmnt->SetValue(aComment.latin1());
955 _PTR(ChildIterator) anIter = myStudy->NewChildIterator(aAnimSObject);
956 int i = 0, nbf = getNbFields();
957 for (anIter->Init(); anIter->More(); anIter->Next(), i++) {
958 if (i >= nbf) break; // it must not be
959 FieldData& aData = myFieldsLst[i];
961 // Get presentation name and comment
962 if (aData.myPrs.empty()) {
963 generatePresentations(i);
965 ostringstream strOut;
966 aData.myPrs[0]->ToStream(strOut);
967 string aPrsComment = strOut.str();
968 string aPrsNameTxt = aData.myPrs[0]->GetComment();
971 _PTR(SObject) aRefObj = anIter->Value();
972 _PTR(ChildIterator) anPrsIter = myStudy->NewChildIterator(aRefObj);
975 if (anPrsIter->More()) {
976 _PTR(SObject) aPrsObj = anPrsIter->Value();
977 anAttr = aStudyBuilder->FindOrCreateAttribute(aPrsObj, "AttributeComment");
978 aCmnt = _PTR(AttributeComment)(anAttr);
979 aCmnt->SetValue(aPrsComment.c_str());
981 anAttr = aStudyBuilder->FindOrCreateAttribute(aPrsObj, "AttributeName");
982 _PTR(AttributeName) aPrsName (anAttr);
983 aPrsName->SetValue(aPrsNameTxt);
986 VISU::CreateAttributes(myStudy, aRefObj->GetID().c_str(),"","",
987 aPrsNameTxt.c_str(),"",aPrsComment.c_str(),true);
990 aStudyBuilder->CommitCommand();
993 //------------------------------------------------------------------------
994 void VISU_TimeAnimation::restoreFromStudy(SALOMEDS::SObject_ptr theField)
996 _PTR(SObject) aAnimSObject = VISU::GetClientSObject(theField, myStudy);
997 restoreFromStudy(aAnimSObject);
1000 void VISU_TimeAnimation::restoreFromStudy(_PTR(SObject) theField)
1002 _PTR(SObject) aAnimSObject = theField;
1004 VISU::Storable::TRestoringMap aMap;
1005 _PTR(GenericAttribute) anAttr;
1006 if (!aAnimSObject->FindAttribute(anAttr, "AttributeComment")) return;
1008 _PTR(AttributeComment) aComment (anAttr);
1009 string aComm = aComment->Value();
1010 QString strIn (aComm.c_str());
1011 VISU::Storable::StrToMap(strIn,aMap);
1014 myTimeMinVal = VISU::Storable::FindValue(aMap,"myTimeMinVal",&isExist).toDouble();
1015 myTimeMaxVal = VISU::Storable::FindValue(aMap,"myTimeMaxVal",&isExist).toDouble();
1017 _PTR(ChildIterator) anIter = myStudy->NewChildIterator(aAnimSObject);
1018 for (anIter->Init(); anIter->More(); anIter->Next()) {
1019 _PTR(SObject) aRefObj = anIter->Value();
1020 _PTR(SObject) aFieldObj;
1021 if (!aRefObj->ReferencedObject(aFieldObj) ) continue;
1022 addField(aFieldObj);
1023 FieldData& aData = getFieldData(getNbFields()-1);
1025 // Get Presentation object
1026 _PTR(ChildIterator) anPrsIter = myStudy->NewChildIterator(aRefObj);
1028 if (!anPrsIter->More()) continue;
1029 _PTR(SObject) aPrsObj = anPrsIter->Value();
1030 if (!aPrsObj->FindAttribute(anAttr, "AttributeName")) continue;
1031 _PTR(AttributeName) aName (anAttr);
1032 string aStr = aName->Value();
1033 QString strName (aStr.c_str());
1035 if (strName == VISU::ScalarMap_i::myComment.c_str())
1036 aData.myPrsType = VISU::TSCALARMAP;
1037 else if (strName == VISU::IsoSurfaces_i::myComment.c_str())
1038 aData.myPrsType = VISU::TISOSURFACE;
1039 else if (strName == VISU::CutPlanes_i::myComment.c_str())
1040 aData.myPrsType = VISU::TCUTPLANES;
1041 else if (strName == VISU::CutLines_i::myComment.c_str())
1042 aData.myPrsType = VISU::TCUTLINES;
1043 else if (strName == VISU::Plot3D_i::myComment.c_str())
1044 aData.myPrsType = VISU::TPLOT3D;
1045 else if (strName == VISU::DeformedShape_i::myComment.c_str())
1046 aData.myPrsType = VISU::TDEFORMEDSHAPE;
1047 else if (strName == VISU::Vectors_i::myComment.c_str())
1048 aData.myPrsType = VISU::TVECTORS;
1049 else if (strName == VISU::StreamLines_i::myComment.c_str())
1050 aData.myPrsType = VISU::TSTREAMLINES;
1051 else if (strName == VISU::GaussPoints_i::myComment.c_str())
1052 aData.myPrsType = VISU::TGAUSSPOINTS;
1053 else if (strName == VISU::ScalarMapOnDeformedShape_i::myComment.c_str())
1054 aData.myPrsType = VISU::TSCALARMAPONDEFORMEDSHAPE;
1057 generatePresentations(getNbFields()-1);
1059 if (!aPrsObj->FindAttribute(anAttr, "AttributeComment")) continue;
1060 _PTR(AttributeComment) aPrsComment (anAttr);
1061 string aPrsComm = aPrsComment->Value();
1062 if (aPrsComm.length() > 0) {
1063 QString strPrsIn (aPrsComm.c_str());
1064 VISU::Storable::TRestoringMap aPrsMap;
1065 VISU::Storable::StrToMap(strPrsIn,aPrsMap);
1067 aData.myPrs[0]->Restore(aPrsMap);
1069 aData.myPrs[0]->GetOffset(aData.myOffset);
1070 for (int i = 1; i < aData.myNbFrames; i++) {
1071 //jfa 03.08.2005:aData.myPrs[i]->SameAs(aData.myPrs[0]);
1072 aData.myPrs[i]->SameAsParams(aData.myPrs[0]);//jfa 03.08.2005
1075 string aStr = aAnimSObject->GetID();
1076 myAnimEntry = aStr.c_str();
1079 void VISU_TimeAnimation::onViewDeleted()
1085 //========================================================================
1086 //========================================================================
1087 //========================================================================
1088 struct TNewAnimationEvent: public SALOME_Event
1090 std::string myStudyName;
1091 VISU::View3D_ptr myView3D;
1093 typedef VISU_TimeAnimation* TResult;
1096 TNewAnimationEvent (std::string theStudyName, VISU::View3D_ptr theView3D):
1097 myStudyName(theStudyName),
1098 myView3D(VISU::View3D::_duplicate(theView3D)),
1106 SUIT_Session* aSession = SUIT_Session::session();
1107 QPtrList<SUIT_Application> anApplications = aSession->applications();
1108 QPtrListIterator<SUIT_Application> anIter (anApplications);
1109 while (SUIT_Application* anApp = anIter.current()) {
1111 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
1112 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
1113 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
1114 if (myStudyName == aCStudy->Name()) {
1115 myResult = new VISU_TimeAnimation (aCStudy, myView3D);
1125 VISU_TimeAnimation_i::VISU_TimeAnimation_i (SALOMEDS::Study_ptr theStudy,
1126 VISU::View3D_ptr theView3D)
1128 std::string aStudyName = theStudy->Name();
1129 myAnim = ProcessEvent(new TNewAnimationEvent (aStudyName, theView3D));
1132 VISU_TimeAnimation_i::~VISU_TimeAnimation_i()
1137 void VISU_TimeAnimation_i::addField (SALOMEDS::SObject_ptr theField)
1139 myAnim->addField(theField);
1142 CORBA::Boolean VISU_TimeAnimation_i::generateFrames()
1144 return ProcessEvent(new TMemFunEvent<VISU_TimeAnimation,bool>
1145 (myAnim,&VISU_TimeAnimation::generateFrames));
1148 void VISU_TimeAnimation_i::generatePresentations (CORBA::Long theFieldNum)
1150 myAnim->generatePresentations(theFieldNum);
1153 void VISU_TimeAnimation_i::clearView()
1155 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1156 (myAnim,&VISU_TimeAnimation::clearView));
1159 void VISU_TimeAnimation_i::stopAnimation()
1161 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1162 (myAnim,&VISU_TimeAnimation::stopAnimation));
1165 void VISU_TimeAnimation_i::startAnimation()
1167 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1168 (myAnim,&VISU_TimeAnimation::startAnimation));
1171 void VISU_TimeAnimation_i::nextFrame()
1173 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1174 (myAnim,&VISU_TimeAnimation::nextFrame));
1177 void VISU_TimeAnimation_i::prevFrame()
1179 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1180 (myAnim,&VISU_TimeAnimation::prevFrame));
1183 void VISU_TimeAnimation_i::firstFrame()
1185 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1186 (myAnim,&VISU_TimeAnimation::firstFrame));
1189 void VISU_TimeAnimation_i::lastFrame()
1191 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1192 (myAnim,&VISU_TimeAnimation::lastFrame));
1195 void VISU_TimeAnimation_i::gotoFrame(CORBA::Long theFrame)
1197 ProcessVoidEvent(new TVoidMemFun1ArgEvent<VISU_TimeAnimation,CORBA::Long>
1198 (myAnim,&VISU_TimeAnimation::gotoFrame,theFrame));
1201 CORBA::Long VISU_TimeAnimation_i::getNbFields()
1203 return myAnim->getNbFields();
1206 CORBA::Long VISU_TimeAnimation_i::getNbFrames()
1208 return myAnim->getNbFrames();
1211 CORBA::Boolean VISU_TimeAnimation_i::isRunning()
1213 return myAnim->isRunning();
1216 CORBA::Long VISU_TimeAnimation_i::getCurrentFrame()
1218 return myAnim->getCurrentFrame();
1221 VISU::ColoredPrs3d_ptr VISU_TimeAnimation_i::getPresentation
1222 (CORBA::Long theField, CORBA::Long theFrame)
1224 return myAnim->getPresentation(theField,theFrame);
1227 void VISU_TimeAnimation_i::setPresentationType (CORBA::Long theFieldNum,
1228 VISU::VISUType theType)
1230 myAnim->setPresentationType(theFieldNum,theType);
1233 VISU::VISUType VISU_TimeAnimation_i::getPresentationType (CORBA::Long theFieldNum)
1235 return myAnim->getPresentationType(theFieldNum);
1238 void VISU_TimeAnimation_i::setSpeed(CORBA::Long theSpeed)
1240 myAnim->setSpeed(theSpeed);
1243 CORBA::Long VISU_TimeAnimation_i::getSpeed()
1245 return myAnim->getSpeed();
1248 CORBA::Boolean VISU_TimeAnimation_i::isProportional()
1250 return myAnim->isProportional();
1253 void VISU_TimeAnimation_i::setAnimationRange (CORBA::Double theMin,
1254 CORBA::Double theMax)
1256 myAnim->setAnimationRange(theMin,theMax);
1259 CORBA::Double VISU_TimeAnimation_i::getMinRange()
1261 return myAnim->getMinRange();
1264 CORBA::Double VISU_TimeAnimation_i::getMaxRange()
1266 return myAnim->getMaxRange();
1269 CORBA::Boolean VISU_TimeAnimation_i::isRangeDefined()
1271 return myAnim->isRangeDefined();
1274 void VISU_TimeAnimation_i::dumpTo (const char* thePath)
1276 myAnim->dumpTo(thePath);
1279 char* VISU_TimeAnimation_i::setDumpFormat (const char* theFormat)
1281 string aDumpFormat = myAnim->setDumpFormat(theFormat);
1282 return CORBA::string_dup(aDumpFormat.c_str());
1285 CORBA::Boolean VISU_TimeAnimation_i::isCycling()
1287 return myAnim->isCycling();
1290 CORBA::Double VISU_TimeAnimation_i::getMinTime()
1292 return myAnim->getMinTime();
1295 CORBA::Double VISU_TimeAnimation_i::getMaxTime()
1297 return myAnim->getMaxTime();
1300 void VISU_TimeAnimation_i::setProportional (CORBA::Boolean theProp)
1302 myAnim->setProportional(theProp);
1305 void VISU_TimeAnimation_i::setCycling (CORBA::Boolean theCycle)
1307 myAnim->setCycling(theCycle);
1310 SALOMEDS::SObject_ptr VISU_TimeAnimation_i::publishInStudy()
1312 return myAnim->publishInStudy();
1315 void VISU_TimeAnimation_i::restoreFromStudy(SALOMEDS::SObject_ptr theObj)
1317 myAnim->restoreFromStudy(theObj);
1320 CORBA::Boolean VISU_TimeAnimation_i::isSavedInStudy()
1322 return myAnim->isSavedInStudy();
1325 void VISU_TimeAnimation_i::saveAnimation()
1327 myAnim->saveAnimation();