1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : VISU_TimeAnimation.cxx
21 // Author : Vitaly SMETANNIKOV
24 #include "VISU_TimeAnimation.h"
26 #include "VISUConfig.hh"
28 #include "VISU_Result_i.hh"
29 #include "VISU_Prs3d_i.hh"
30 #include "VISU_Mesh_i.hh"
31 #include "VISU_ScalarMap_i.hh"
32 #include "VISU_IsoSurfaces_i.hh"
33 #include "VISU_DeformedShape_i.hh"
34 #include "VISU_ScalarMapOnDeformedShape_i.hh"
35 #include "VISU_CutPlanes_i.hh"
36 #include "VISU_Plot3D_i.hh"
37 #include "VISU_CutLines_i.hh"
38 #include "VISU_Vectors_i.hh"
39 #include "VISU_StreamLines_i.hh"
40 #include "VISU_GaussPoints_i.hh"
41 #include "VISU_ViewManager_i.hh"
42 #include "VISU_View_i.hh"
44 #include "VISU_ScalarBarActor.hxx"
45 #include "VISU_Actor.h"
47 #include "SalomeApp_Study.h"
49 #include "SVTK_ViewWindow.h"
51 #include "SALOME_Event.hxx"
53 #include "SUIT_ResourceMgr.h"
54 #include "SUIT_Application.h"
55 #include "SUIT_Session.h"
56 #include "SUIT_Study.h"
58 #include "SALOMEDSClient_AttributeComment.hxx"
59 #include "SALOMEDSClient_AttributeName.hxx"
60 #include "CASCatch.hxx"
70 //------------------------------------------------------------------------
71 VISU_TimeAnimation::VISU_TimeAnimation (_PTR(Study) theStudy,
72 VISU::View3D_ptr theView3D)
78 myProportional = false;
81 if (!CORBA::is_nil(theView3D)) {
82 VISU::View3D_i* pView = dynamic_cast<VISU::View3D_i*>(GetServant(theView3D).in());
83 SUIT_ViewWindow* aVW = pView->GetViewWindow();
84 myView = dynamic_cast<SVTK_ViewWindow*>(aVW);
85 connect( myView, SIGNAL( destroyed() ), this, SLOT( onViewDeleted() ) );
98 myAVIMaker = "jpeg2yuv";
102 //------------------------------------------------------------------------
103 VISU_TimeAnimation::~VISU_TimeAnimation()
106 MESSAGE("Viewer is not defined for animation");
110 for (int i = 0; i < getNbFields(); i++) {
111 clearData(myFieldsLst[i]);
114 /* Terminates the execution of the thread.
115 * The thread may or may not be terminated immediately,
116 * depending on the operating system's scheduling policies.
118 * Use QThread::wait() after terminate() for synchronous termination.
120 * When the thread is terminated, all threads waiting for the the thread to finish will be woken up.
122 * Warning: This function is dangerous, and its use is discouraged.
123 * The thread can be terminated at any point in its code path.
124 * Threads can be terminated while modifying data.
125 * There is no chance for the thread to cleanup after itself,
126 * unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
130 QThread::terminate();
135 //------------------------------------------------------------------------
136 void VISU_TimeAnimation::addField (_PTR(SObject) theField)
139 aNewData.myField = theField;
140 aNewData.myNbFrames = 0;
141 aNewData.myPrsType = VISU::TSCALARMAP;
142 aNewData.myOffset[0] = aNewData.myOffset[1] = aNewData.myOffset[2] = 0;
143 VISU::Storable::TRestoringMap aMap = getMapOfValue(aNewData.myField);
144 aNewData.myNbTimes = VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
145 myFieldsLst.append(aNewData);
147 //find Min/Max timestamps
148 if ((myTimeMin == 0) && (myTimeMax == 0)) {
149 _PTR(ChildIterator) anIter = myStudy->NewChildIterator(theField);
150 anIter->Next(); // First is reference on support
151 myTimeMin = getTimeValue(anIter->Value());
152 for(; anIter->More(); anIter->Next()) {
153 myTimeMax = getTimeValue(anIter->Value());
158 //------------------------------------------------------------------------
159 void VISU_TimeAnimation::addField (SALOMEDS::SObject_ptr theField)
161 SALOMEDS::SObject_var theFieldDup = SALOMEDS::SObject::_duplicate(theField);
162 _PTR(SObject) aField = VISU::GetClientSObject(theFieldDup, myStudy);
167 //------------------------------------------------------------------------
168 void VISU_TimeAnimation::clearData(FieldData& theData) {
170 MESSAGE("Viewer is not defined for animation");
173 theData.myTiming.clear();
174 vtkRenderer* aRen = myView->getRenderer();
175 if (!theData.myActors.empty()) {
176 for (int i = 0, iEnd = theData.myActors.size(); i < iEnd; i++) {
177 if (theData.myActors[i] != 0) {
178 theData.myActors[i]->RemoveFromRender(aRen);
181 theData.myActors.clear();
183 if (!theData.myPrs.empty()) {
184 for (int i = 0, iEnd = theData.myPrs.size(); i < iEnd; i++)
185 if (theData.myPrs[i] != 0) {
186 theData.myPrs[i]->_remove_ref();
188 theData.myPrs.clear();
190 theData.myNbFrames = 0;
197 //------------------------------------------------------------------------
198 template<class TPrs3d>
200 GeneratePresentations(_PTR(Study) theStudy,
202 VISU::Result_i* theResult,
203 bool theIsRangeDefined,
204 CORBA::Double theTimeMin,
205 CORBA::Double theTimeMax)
207 double aMin = VTK_LARGE_FLOAT, aMax = -VTK_LARGE_FLOAT;
209 _PTR(ChildIterator) anIter = theStudy->NewChildIterator(theData.myField);
210 anIter->Next(); // First is reference on support
213 for(; anIter->More(); anIter->Next()){
214 if (aFrameId == theData.myNbTimes) {
215 MESSAGE("There are extra timestamps in field");
218 _PTR(SObject) aTimeStamp = anIter->Value();
222 theData.myTiming[aFrameId] = VISU_TimeAnimation::getTimeValue(aTimeStamp);
223 if (theIsRangeDefined) {
224 if (theData.myTiming[aFrameId] < theTimeMin)
226 if (theData.myTiming[aFrameId] > theTimeMax)
230 VISU::Storable::TRestoringMap aTimeMap = VISU_TimeAnimation::getMapOfValue(aTimeStamp);
231 QString aMeshName = VISU::Storable::FindValue(aTimeMap,"myMeshName");
232 VISU::Entity anEntity = (VISU::Entity) VISU::Storable::FindValue(aTimeMap,"myEntityId").toInt();
233 QString aFieldName = VISU::Storable::FindValue(aTimeMap,"myFieldName");
234 int aTimeStampId = VISU::Storable::FindValue(aTimeMap,"myTimeStampId").toInt();
236 bool anIsCreated = false;
237 TPrs3d* aPresent = new TPrs3d(theResult, false);
240 if(aPresent->Create(aMeshName.latin1(),anEntity,aFieldName.latin1(),aTimeStampId)){
242 theData.myPrs[aFrameId++] = aPresent;
243 aMin = std::min(aPresent->GetMin(), aMin);
244 aMax = std::max(aPresent->GetMax(), aMax);
246 }catch(std::exception& exc){
247 INFOS("Follow exception was occured :\n"<<exc.what());
249 INFOS("Unknown exception was occured!");
251 }CASCatch_CATCH(Standard_Failure) {
252 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
253 INFOS("Follow signal was occured :\n"<<aFail->GetMessageString());
256 aPresent->_remove_ref();
258 theData.myNbFrames = aFrameId;
260 if (theData.myPrsType != VISU::TGAUSSPOINTS){
261 int aRangeType = VISU::GetResourceMgr()->integerValue("VISU" , "scalar_range_type", 0);
262 if( aRangeType != 1 ){
263 for(long aFrameId = 0; aFrameId < theData.myNbFrames; aFrameId++) {
264 if (VISU::ScalarMap_i* aPrs = dynamic_cast<VISU::ScalarMap_i*>(theData.myPrs[aFrameId])){
265 aPrs->SetRange(aMin, aMax);
266 aPrs->SetOffset(theData.myOffset);
270 if (theData.myPrsType == VISU::TISOSURFACE)
271 for (long aFrameId = 0; aFrameId < theData.myNbFrames; aFrameId++)
272 if (VISU::IsoSurfaces_i* aPrs = dynamic_cast<VISU::IsoSurfaces_i*>(theData.myPrs[aFrameId]))
273 aPrs->SetSubRange(aMin, aMax);
278 void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
279 FieldData& aData = myFieldsLst[theFieldNum];
281 // Delete previous presentations
284 VISU::Result_i* aResult = createPresent(aData.myField);
285 VISU::Storable::TRestoringMap aMap = getMapOfValue(aData.myField);
286 aData.myNbFrames = aData.myNbTimes;
287 //VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
289 aData.myPrs.resize(aData.myNbTimes,NULL);
290 aData.myTiming.resize(aData.myNbTimes);
292 using namespace VISU;
293 switch (aData.myPrsType) {
294 case VISU::TSCALARMAP: // ScalarMap
295 GeneratePresentations<ScalarMap_i>(myStudy,
302 case VISU::TISOSURFACE: // Iso Surfaces
303 GeneratePresentations<IsoSurfaces_i>(myStudy,
310 case VISU::TCUTPLANES: // Cut Planes
311 GeneratePresentations<CutPlanes_i>(myStudy,
318 case VISU::TCUTLINES: // Cut Lines
319 GeneratePresentations<CutLines_i>(myStudy,
326 case VISU::TPLOT3D: // Plot3d
327 GeneratePresentations<Plot3D_i>(myStudy,
334 case VISU::TDEFORMEDSHAPE: // Deformed Shape
335 GeneratePresentations<DeformedShape_i>(myStudy,
342 case VISU::TVECTORS: // Vectors
343 GeneratePresentations<Vectors_i>(myStudy,
350 case VISU::TSTREAMLINES: // Stream Lines
351 GeneratePresentations<StreamLines_i>(myStudy,
358 case VISU::TGAUSSPOINTS: // Gauss Points
359 GeneratePresentations<GaussPoints_i>(myStudy,
366 case VISU::TSCALARMAPONDEFORMEDSHAPE: // Scalar map on deformed shape
367 GeneratePresentations<ScalarMapOnDeformedShape_i>(myStudy,
375 MESSAGE("Not implemented for this presentation type: " << aData.myPrsType);
381 //------------------------------------------------------------------------
382 CORBA::Boolean VISU_TimeAnimation::generateFrames() {
384 MESSAGE("Viewer is not defined for animation");
388 myLastError = QString("Frame(s) for ");
389 bool aNoError = true;
393 for (int i = 0; i < getNbFields(); i++) {
394 FieldData& aData = myFieldsLst[i];
395 aData.myActors.resize(aData.myNbFrames,NULL);
396 for (long j = 0; j < aData.myNbFrames; j++) {
397 VISU_Actor* aActor = NULL;
399 aData.myPrs[j]->SetOffset(aData.myOffset);
400 aActor = aData.myPrs[j]->CreateActor();
401 myView->AddActor(aActor);
403 aActor->VisibilityOn();
405 aActor->VisibilityOff();
406 }catch(...){ //catch(std::runtime_error& exc){
408 myLastError += QString("%1 ").arg(aData.myTiming[j]);
410 aData.myActors[j] = aActor;
414 myLastError += QString(" timestamp(s) cannot be created.");
415 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
420 //------------------------------------------------------------------------
421 void VISU_TimeAnimation::clearView() {
423 MESSAGE("Viewer is not defined for animation");
426 vtkRenderer* aRen = myView->getRenderer();
427 for (int i = 0; i < getNbFields(); i++) {
428 FieldData& aData = myFieldsLst[i];
429 if (!aData.myActors.empty()) {
430 for (int i = 0, iEnd = aData.myActors.size(); i < iEnd; i++) {
431 if (aData.myActors[i] != 0) {
432 aData.myActors[i]->RemoveFromRender(aRen);
435 aData.myActors.clear();
438 VISU::RepaintView(myView);
441 //------------------------------------------------------------------------
442 void VISU_TimeAnimation::stopAnimation() {
446 //------------------------------------------------------------------------
447 void VISU_TimeAnimation::startAnimation() {
454 //------------------------------------------------------------------------
455 void VISU_TimeAnimation::nextFrame() {
457 MESSAGE("Viewer is not defined for animation");
461 if (myFrame < (myFieldsLst[0].myNbFrames-1)) {
463 for (i = 0; i < getNbFields(); i++)
464 if (myFieldsLst[i].myActors[myFrame] != 0)
465 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
468 for (i = 0; i < getNbFields(); i++)
469 if (myFieldsLst[i].myActors[myFrame] != 0)
470 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
472 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
477 //------------------------------------------------------------------------
478 void VISU_TimeAnimation::prevFrame() {
480 MESSAGE("Viewer is not defined for animation");
486 for (i = 0; i < getNbFields(); i++)
487 if (myFieldsLst[i].myActors[myFrame] != 0)
488 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
491 for (i = 0; i < getNbFields(); i++)
492 if (myFieldsLst[i].myActors[myFrame] != 0)
493 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
495 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
500 //------------------------------------------------------------------------
501 void VISU_TimeAnimation::firstFrame() {
503 MESSAGE("Viewer is not defined for animation");
508 for (i = 0; i < getNbFields(); i++)
509 if(!myFieldsLst[i].myActors.empty())
510 if (myFieldsLst[i].myActors[myFrame] != 0)
511 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
513 for (i = 0; i < getNbFields(); i++)
514 if(!myFieldsLst[i].myActors.empty())
515 if (myFieldsLst[i].myActors[myFrame] != 0)
516 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
517 if(!myFieldsLst[0].myTiming.empty()){
518 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
523 //------------------------------------------------------------------------
524 void VISU_TimeAnimation::lastFrame() {
526 MESSAGE("Viewer is not defined for animation");
531 for (i = 0; i < getNbFields(); i++)
532 if (myFieldsLst[i].myActors[myFrame] != 0)
533 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
535 myFrame = myFieldsLst[0].myNbFrames-1;
536 for (i = 0; i < getNbFields(); i++)
537 if (myFieldsLst[i].myActors[myFrame] != 0)
538 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
540 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
545 //------------------------------------------------------------------------
546 // For Batchmode using
547 void VISU_TimeAnimation::gotoFrame(CORBA::Long theFrame) {
549 MESSAGE("Viewer is not defined for animation");
552 if ((theFrame < 0) || (theFrame > (getNbFrames()-1)))
558 for (i = 0; i < getNbFields(); i++)
559 if (myFieldsLst[i].myActors[myFrame] != 0)
560 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
563 for (i = 0; i < getNbFields(); i++)
564 if (myFieldsLst[i].myActors[myFrame] != 0)
565 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
567 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
570 qApp->processEvents(3);
575 //------------------------------------------------------------------------
576 VISU::ColoredPrs3d_ptr VISU_TimeAnimation::getPresentation(CORBA::Long theField, CORBA::Long theFrame) {
577 if ((theField > getNbFields()) || (theField < 0))
578 return VISU::ColoredPrs3d::_nil();
579 if ((theFrame < 0) || (theFrame > (myFieldsLst[theField].myNbFrames - 1)))
580 return VISU::ColoredPrs3d::_nil();
581 return myFieldsLst[theField].myPrs[theFrame]->_this();
585 //------------------------------------------------------------------------
586 CORBA::Long VISU_TimeAnimation::getNbFrames() {
587 return (getNbFields() > 0)? myFieldsLst[0].myNbFrames : 0;
591 //------------------------------------------------------------------------
592 void VISU_TimeAnimation::run()
595 MESSAGE("Viewer is not defined for animation");
599 bool isDumping = !myDumpPath.isEmpty();
601 if (myFieldsLst[0].myNbFrames > 2)
602 aOneVal = myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0];
605 QValueList<int> anIndexList;
609 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
610 if(!(myFieldsLst[0].myField))
612 for (int i = 0; i < getNbFields(); i++) {
613 FieldData& aData = myFieldsLst[i];
615 if (aData.myActors[myFrame-1] != 0)
616 aData.myActors[myFrame-1]->VisibilityOff();
618 if (aData.myActors[aData.myNbFrames-1] != 0)
619 aData.myActors[aData.myNbFrames-1]->VisibilityOff();
621 if (aData.myActors[myFrame] != 0) {
622 aData.myActors[myFrame]->VisibilityOn();
625 myView->Repaint(false);
628 if (myProportional) {
633 if (myFieldsLst[0].myNbFrames > 2)
634 k = (myFieldsLst[0].myTiming[myFrame+1] -
635 myFieldsLst[0].myTiming[myFrame]) / aOneVal;
638 if (myFrame < (myFieldsLst[0].myNbFrames - 1))
639 k = (myFieldsLst[0].myTiming[myFrame+1] -
640 myFieldsLst[0].myTiming[myFrame]) / aOneVal;
643 int delay = (int)(1000. * k / mySpeed);
644 isDumping = !myDumpPath.isEmpty();
645 if (delay < 1 && isDumping) {
646 // We must unlock mutex for some time before grabbing to allow view updating
654 // We must unlock mutex for some time before grabbing to allow view updating
658 if(!(myFieldsLst[0].myField)) // break, if field was deleted.
660 if (myDumpFormat.compare("AVI") != 0) {
661 QString aFile(myDumpPath);
662 QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
664 while ((aPos = aName.find(".")) > -1 )
665 aName.replace(aPos, 1, "_");
668 aFile += myDumpFormat.lower();
669 myView->dumpViewToFormat(aFile,myDumpFormat);
671 QFileInfo aFileInfo(myDumpPath);
672 QString aDirPath = aFileInfo.dirPath(true);
673 QString aBaseName = aFileInfo.fileName();
682 if (myProportional) {
683 double p = (myFieldsLst[0].myTiming[myFrame] -
684 myFieldsLst[0].myTiming[myFrame-1]) / aOneVal;
685 myFileIndex += (long) (5*p);
691 QString aFile = aDirPath + QDir::separator() + aBaseName;
693 aFile += QString("%1").arg(myFileIndex).rightJustify(8, '0');
696 /* check image size is divisable 16
697 myView->dumpViewToFormat(aFile,"JPEG");
699 SUIT_ViewWindow* aView = myView;
700 QImage img = aView->dumpView();
702 int width = img.width(); width = (width/16)*16;
703 int height = img.height(); height = (height/16)*16;
704 QImage copy = img.copy(0, 0, width, height);
705 if (copy.save(aFile, "JPEG")) {
706 anIndexList.append(myFileIndex);
713 if (!myIsActive) break;
716 if (myFrame == myFieldsLst[0].myNbFrames) {
726 // make AVI file if need
727 if (isDumping && myDumpFormat.compare("AVI") == 0) {
728 double aFPS = 17.3 * mySpeed;
730 QFileInfo aFileInfo(myDumpPath);
731 QString aDirPath = aFileInfo.dirPath(true);
732 QString aBaseName = aFileInfo.fileName();
735 if (anIndexList.count() > 1) {
736 QString aFFile = aDirPath + QDir::separator() + aBaseName;
737 aFFile += QString("_%1.jpeg");
738 int aStartIndex = anIndexList[0], anEndIndex;
739 for (int i = 1; i < anIndexList.count(); i++) {
740 anEndIndex = anIndexList[i];
741 QString aCurFile = aFFile.arg(QString::number(aStartIndex).rightJustify(8, '0'));
742 QStringList aCommands;
743 for (int j = aStartIndex+1; j < anEndIndex; j++) {
744 QString aFile = aFFile.arg(QString::number(j).rightJustify(8, '0'));
745 aCommands.append(QString("ln -s %1 %2").arg(aCurFile).arg(aFile));
747 system(aCommands.join(" ; \\\n").latin1());
748 aStartIndex = anEndIndex;
753 QString aPattern = aDirPath + QDir::separator() + aBaseName;
754 aPattern += "_\%08d.jpeg";
756 QString aCmd = myAVIMaker;
759 aCmd += QString(" -f %1").arg(aFPS);
760 // aCmd += QString(" -n %1").arg(aNbFiles);
761 aCmd += QString(" -n %1").arg(myFileIndex+1);
762 aCmd += QString(" -j %1").arg(aPattern);
763 aCmd += " | yuv2lav";
764 aCmd += QString(" -o %1").arg(myDumpPath);
765 system(aCmd.latin1());
767 // remove temporary jpeg files
769 aCmd += QString("cd %1").arg(aDirPath);
771 aCmd += QString(" | egrep '%1_[0-9]*.jpeg'").arg(aBaseName);
772 aCmd += " | xargs rm";
774 system(aCmd.latin1());
782 //------------------------------------------------------------------------
783 VISU::Result_i* VISU_TimeAnimation::createPresent (_PTR(SObject) theField)
785 _PTR(SObject) aSObj = theField->GetFather();
786 aSObj = aSObj->GetFather();
787 aSObj = aSObj->GetFather();
788 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObj);
789 if (CORBA::is_nil(anObject)) return NULL;
790 return dynamic_cast<VISU::Result_i*>(VISU::GetServant(anObject).in());
793 //------------------------------------------------------------------------
794 VISU::Storable::TRestoringMap VISU_TimeAnimation::getMapOfValue (_PTR(SObject) theSObject)
796 VISU::Storable::TRestoringMap aMap;
798 _PTR(GenericAttribute) anAttr;
799 if (theSObject->FindAttribute(anAttr, "AttributeComment")) {
800 _PTR(AttributeComment) aComment (anAttr);
801 std::string aString = aComment->Value();
802 QString strIn (aString.c_str());
803 VISU::Storable::StrToMap(strIn, aMap);
809 //------------------------------------------------------------------------
810 double VISU_TimeAnimation::getTimeValue (_PTR(SObject) theTimeStamp)
812 _PTR(GenericAttribute) anAttr;
813 if (theTimeStamp->FindAttribute(anAttr, "AttributeName")) {
814 _PTR(AttributeName) aName (anAttr);
815 QString aNameString (aName->Value().c_str());
816 int time_len = aNameString.find(',');
818 return aNameString.left(time_len).toDouble();
820 return aNameString.toDouble();
825 //------------------------------------------------------------------------
826 void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed)
828 mySpeed = (theSpeed<1)? 1 : theSpeed;
831 std::string VISU_TimeAnimation::setDumpFormat(const char* theFormat)
833 myDumpFormat = theFormat;
834 QStrList aDumpFormats = QImageIO::outputFormats();
835 if (myDumpFormat.isEmpty() ||
836 (aDumpFormats.find(theFormat) < 0 && myDumpFormat.compare("AVI") != 0)) {
837 if (aDumpFormats.find("JPEG"))
838 myDumpFormat = "JPEG";
840 myDumpFormat = aDumpFormats.at(0);
842 return myDumpFormat.latin1();
845 //------------------------------------------------------------------------
846 bool VISU_TimeAnimation::checkAVIMaker() const
848 QStrList aDumpFormats = QImageIO::outputFormats();
849 if (aDumpFormats.find("JPEG") < 0) return false;
851 QString aCmd("which ");
853 aCmd += " >& /dev/null";
854 int iErr = system(aCmd.latin1());
858 //************************************************************************
859 int VISU_TimeAnimation::myNBAnimations = 0;
860 QString VISU_TimeAnimation::GenerateName()
862 return VISU::GenerateName("Animation", myNBAnimations++);
865 //------------------------------------------------------------------------
866 std::string GetPresentationComment (VISU::VISUType thePrsType)
869 switch (thePrsType) {
870 case VISU::TSCALARMAP:
871 aPrsCmt = VISU::ScalarMap_i::myComment;
873 case VISU::TISOSURFACE:
874 aPrsCmt = VISU::IsoSurfaces_i::myComment;
876 case VISU::TCUTPLANES:
877 aPrsCmt = VISU::CutPlanes_i::myComment;
879 case VISU::TCUTLINES:
880 aPrsCmt = VISU::CutLines_i::myComment;
883 aPrsCmt = VISU::Plot3D_i::myComment;
885 case VISU::TDEFORMEDSHAPE:
886 aPrsCmt = VISU::DeformedShape_i::myComment;
889 aPrsCmt = VISU::Vectors_i::myComment;
891 case VISU::TSTREAMLINES:
892 aPrsCmt = VISU::StreamLines_i::myComment;
894 case VISU::TGAUSSPOINTS:
895 aPrsCmt = VISU::GaussPoints_i::myComment;
897 case VISU::TSCALARMAPONDEFORMEDSHAPE:
898 aPrsCmt = VISU::ScalarMapOnDeformedShape_i::myComment;
901 aPrsCmt = "Unknown presentation";
907 //------------------------------------------------------------------------
908 SALOMEDS::SObject_ptr VISU_TimeAnimation::publishInStudy()
910 if (myStudy->GetProperties()->IsLocked())
911 return SALOMEDS::SObject::_nil();
913 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
914 aStudyBuilder->NewCommand(); // There is a transaction
915 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent(myStudy);
916 std::string aSComponentEntry = aSComponent->GetID();
919 aComment.sprintf("myComment=ANIMATION;myType=%d;myTimeMinVal=%g;myTimeMaxVal=%g",
920 VISU::TANIMATION,myTimeMinVal,myTimeMaxVal);
922 string anEntry = VISU::CreateAttributes(myStudy,aSComponentEntry.c_str(),"","",
923 GenerateName(),"",aComment,true);
924 myAnimEntry = anEntry.c_str();
925 _PTR(SObject) aAnimSObject = myStudy->FindObjectID(anEntry.c_str());
927 for (int i = 0; i < getNbFields(); i++) {
928 FieldData& aData = myFieldsLst[i];
930 _PTR(SObject) newObj = aStudyBuilder->NewObject(aAnimSObject);
931 aStudyBuilder->Addreference(newObj, aData.myField);
933 if (aData.myPrs.empty()) {
934 generatePresentations(i);
936 ostringstream strOut;
937 aData.myPrs[0]->ToStream(strOut);
938 string aPrsComment = strOut.str();
939 VISU::CreateAttributes(myStudy, newObj->GetID().c_str(),"","",
940 aData.myPrs[0]->GetComment(),"",aPrsComment.c_str(),true);
942 aStudyBuilder->CommitCommand();
944 return VISU::GetSObject(aAnimSObject);
947 //------------------------------------------------------------------------
948 void VISU_TimeAnimation::saveAnimation()
950 if (myStudy->GetProperties()->IsLocked()) return;
951 if (myAnimEntry.isEmpty()) return;
953 _PTR(SObject) aAnimSObject = myStudy->FindObjectID(myAnimEntry.latin1());
954 if (!aAnimSObject) return;
956 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
957 aStudyBuilder->NewCommand(); // There is a transaction
958 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent(myStudy);
959 std::string aSComponentEntry = aSComponent->GetID();
962 aComment.sprintf("myComment=ANIMATION;myType=%d;myTimeMinVal=%g;myTimeMaxVal=%g",
963 VISU::TANIMATION,myTimeMinVal,myTimeMaxVal);
965 _PTR(GenericAttribute) anAttr;
966 anAttr = aStudyBuilder->FindOrCreateAttribute(aAnimSObject, "AttributeComment");
967 _PTR(AttributeComment) aCmnt (anAttr);
968 aCmnt->SetValue(aComment.latin1());
970 _PTR(ChildIterator) anIter = myStudy->NewChildIterator(aAnimSObject);
971 int i = 0, nbf = getNbFields();
972 for (anIter->Init(); anIter->More(); anIter->Next(), i++) {
973 if (i >= nbf) break; // it must not be
974 FieldData& aData = myFieldsLst[i];
976 // Get presentation name and comment
977 if (aData.myPrs.empty()) {
978 generatePresentations(i);
980 ostringstream strOut;
981 aData.myPrs[0]->ToStream(strOut);
982 string aPrsComment = strOut.str();
983 string aPrsNameTxt = aData.myPrs[0]->GetComment();
986 _PTR(SObject) aRefObj = anIter->Value();
987 _PTR(ChildIterator) anPrsIter = myStudy->NewChildIterator(aRefObj);
990 if (anPrsIter->More()) {
991 _PTR(SObject) aPrsObj = anPrsIter->Value();
992 anAttr = aStudyBuilder->FindOrCreateAttribute(aPrsObj, "AttributeComment");
993 aCmnt = _PTR(AttributeComment)(anAttr);
994 aCmnt->SetValue(aPrsComment.c_str());
996 anAttr = aStudyBuilder->FindOrCreateAttribute(aPrsObj, "AttributeName");
997 _PTR(AttributeName) aPrsName (anAttr);
998 aPrsName->SetValue(aPrsNameTxt);
1001 VISU::CreateAttributes(myStudy, aRefObj->GetID().c_str(),"","",
1002 aPrsNameTxt.c_str(),"",aPrsComment.c_str(),true);
1005 aStudyBuilder->CommitCommand();
1008 //------------------------------------------------------------------------
1009 void VISU_TimeAnimation::restoreFromStudy(SALOMEDS::SObject_ptr theField)
1011 _PTR(SObject) aAnimSObject = VISU::GetClientSObject(theField, myStudy);
1012 restoreFromStudy(aAnimSObject);
1015 void VISU_TimeAnimation::restoreFromStudy(_PTR(SObject) theField)
1017 _PTR(SObject) aAnimSObject = theField;
1019 VISU::Storable::TRestoringMap aMap;
1020 _PTR(GenericAttribute) anAttr;
1021 if (!aAnimSObject->FindAttribute(anAttr, "AttributeComment")) return;
1023 _PTR(AttributeComment) aComment (anAttr);
1024 string aComm = aComment->Value();
1025 QString strIn (aComm.c_str());
1026 VISU::Storable::StrToMap(strIn,aMap);
1029 myTimeMinVal = VISU::Storable::FindValue(aMap,"myTimeMinVal",&isExist).toDouble();
1030 myTimeMaxVal = VISU::Storable::FindValue(aMap,"myTimeMaxVal",&isExist).toDouble();
1032 _PTR(ChildIterator) anIter = myStudy->NewChildIterator(aAnimSObject);
1033 for (anIter->Init(); anIter->More(); anIter->Next()) {
1034 _PTR(SObject) aRefObj = anIter->Value();
1035 _PTR(SObject) aFieldObj;
1036 if (!aRefObj->ReferencedObject(aFieldObj) ) continue;
1037 addField(aFieldObj);
1038 FieldData& aData = getFieldData(getNbFields()-1);
1040 // Get Presentation object
1041 _PTR(ChildIterator) anPrsIter = myStudy->NewChildIterator(aRefObj);
1043 if (!anPrsIter->More()) continue;
1044 _PTR(SObject) aPrsObj = anPrsIter->Value();
1045 if (!aPrsObj->FindAttribute(anAttr, "AttributeName")) continue;
1046 _PTR(AttributeName) aName (anAttr);
1047 string aStr = aName->Value();
1048 QString strName (aStr.c_str());
1050 if (strName == VISU::ScalarMap_i::myComment.c_str())
1051 aData.myPrsType = VISU::TSCALARMAP;
1052 else if (strName == VISU::IsoSurfaces_i::myComment.c_str())
1053 aData.myPrsType = VISU::TISOSURFACE;
1054 else if (strName == VISU::CutPlanes_i::myComment.c_str())
1055 aData.myPrsType = VISU::TCUTPLANES;
1056 else if (strName == VISU::CutLines_i::myComment.c_str())
1057 aData.myPrsType = VISU::TCUTLINES;
1058 else if (strName == VISU::Plot3D_i::myComment.c_str())
1059 aData.myPrsType = VISU::TPLOT3D;
1060 else if (strName == VISU::DeformedShape_i::myComment.c_str())
1061 aData.myPrsType = VISU::TDEFORMEDSHAPE;
1062 else if (strName == VISU::Vectors_i::myComment.c_str())
1063 aData.myPrsType = VISU::TVECTORS;
1064 else if (strName == VISU::StreamLines_i::myComment.c_str())
1065 aData.myPrsType = VISU::TSTREAMLINES;
1066 else if (strName == VISU::GaussPoints_i::myComment.c_str())
1067 aData.myPrsType = VISU::TGAUSSPOINTS;
1068 else if (strName == VISU::ScalarMapOnDeformedShape_i::myComment.c_str())
1069 aData.myPrsType = VISU::TSCALARMAPONDEFORMEDSHAPE;
1072 generatePresentations(getNbFields()-1);
1074 if (!aPrsObj->FindAttribute(anAttr, "AttributeComment")) continue;
1075 _PTR(AttributeComment) aPrsComment (anAttr);
1076 string aPrsComm = aPrsComment->Value();
1077 if (aPrsComm.length() > 0) {
1078 QString strPrsIn (aPrsComm.c_str());
1079 VISU::Storable::TRestoringMap aPrsMap;
1080 VISU::Storable::StrToMap(strPrsIn,aPrsMap);
1082 aData.myPrs[0]->Restore(aPrsMap);
1084 aData.myPrs[0]->GetOffset(aData.myOffset);
1085 for (int i = 1; i < aData.myNbFrames; i++) {
1086 //jfa 03.08.2005:aData.myPrs[i]->SameAs(aData.myPrs[0]);
1087 aData.myPrs[i]->SameAsParams(aData.myPrs[0]);//jfa 03.08.2005
1090 string aStr = aAnimSObject->GetID();
1091 myAnimEntry = aStr.c_str();
1094 void VISU_TimeAnimation::onViewDeleted()
1100 //========================================================================
1101 //========================================================================
1102 //========================================================================
1103 struct TNewAnimationEvent: public SALOME_Event
1105 std::string myStudyName;
1106 VISU::View3D_ptr myView3D;
1108 typedef VISU_TimeAnimation* TResult;
1111 TNewAnimationEvent (std::string theStudyName, VISU::View3D_ptr theView3D):
1112 myStudyName(theStudyName),
1113 myView3D(VISU::View3D::_duplicate(theView3D)),
1121 SUIT_Session* aSession = SUIT_Session::session();
1122 QPtrList<SUIT_Application> anApplications = aSession->applications();
1123 QPtrListIterator<SUIT_Application> anIter (anApplications);
1124 while (SUIT_Application* anApp = anIter.current()) {
1126 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
1127 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
1128 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
1129 if (myStudyName == aCStudy->Name()) {
1130 myResult = new VISU_TimeAnimation (aCStudy, myView3D);
1140 VISU_TimeAnimation_i::VISU_TimeAnimation_i (SALOMEDS::Study_ptr theStudy,
1141 VISU::View3D_ptr theView3D)
1143 std::string aStudyName = theStudy->Name();
1144 myAnim = ProcessEvent(new TNewAnimationEvent (aStudyName, theView3D));
1147 VISU_TimeAnimation_i::~VISU_TimeAnimation_i()
1152 void VISU_TimeAnimation_i::addField (SALOMEDS::SObject_ptr theField)
1154 myAnim->addField(theField);
1157 CORBA::Boolean VISU_TimeAnimation_i::generateFrames()
1159 return ProcessEvent(new TMemFunEvent<VISU_TimeAnimation,bool>
1160 (myAnim,&VISU_TimeAnimation::generateFrames));
1163 void VISU_TimeAnimation_i::generatePresentations (CORBA::Long theFieldNum)
1165 myAnim->generatePresentations(theFieldNum);
1168 void VISU_TimeAnimation_i::clearView()
1170 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1171 (myAnim,&VISU_TimeAnimation::clearView));
1174 void VISU_TimeAnimation_i::stopAnimation()
1176 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1177 (myAnim,&VISU_TimeAnimation::stopAnimation));
1180 void VISU_TimeAnimation_i::startAnimation()
1182 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1183 (myAnim,&VISU_TimeAnimation::startAnimation));
1186 void VISU_TimeAnimation_i::nextFrame()
1188 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1189 (myAnim,&VISU_TimeAnimation::nextFrame));
1192 void VISU_TimeAnimation_i::prevFrame()
1194 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1195 (myAnim,&VISU_TimeAnimation::prevFrame));
1198 void VISU_TimeAnimation_i::firstFrame()
1200 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1201 (myAnim,&VISU_TimeAnimation::firstFrame));
1204 void VISU_TimeAnimation_i::lastFrame()
1206 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>
1207 (myAnim,&VISU_TimeAnimation::lastFrame));
1210 void VISU_TimeAnimation_i::gotoFrame(CORBA::Long theFrame)
1212 ProcessVoidEvent(new TVoidMemFun1ArgEvent<VISU_TimeAnimation,CORBA::Long>
1213 (myAnim,&VISU_TimeAnimation::gotoFrame,theFrame));
1216 CORBA::Long VISU_TimeAnimation_i::getNbFields()
1218 return myAnim->getNbFields();
1221 CORBA::Long VISU_TimeAnimation_i::getNbFrames()
1223 return myAnim->getNbFrames();
1226 CORBA::Boolean VISU_TimeAnimation_i::isRunning()
1228 return myAnim->isRunning();
1231 CORBA::Long VISU_TimeAnimation_i::getCurrentFrame()
1233 return myAnim->getCurrentFrame();
1236 VISU::ColoredPrs3d_ptr VISU_TimeAnimation_i::getPresentation
1237 (CORBA::Long theField, CORBA::Long theFrame)
1239 return myAnim->getPresentation(theField,theFrame);
1242 void VISU_TimeAnimation_i::setPresentationType (CORBA::Long theFieldNum,
1243 VISU::VISUType theType)
1245 myAnim->setPresentationType(theFieldNum,theType);
1248 VISU::VISUType VISU_TimeAnimation_i::getPresentationType (CORBA::Long theFieldNum)
1250 return myAnim->getPresentationType(theFieldNum);
1253 void VISU_TimeAnimation_i::setSpeed(CORBA::Long theSpeed)
1255 myAnim->setSpeed(theSpeed);
1258 CORBA::Long VISU_TimeAnimation_i::getSpeed()
1260 return myAnim->getSpeed();
1263 CORBA::Boolean VISU_TimeAnimation_i::isProportional()
1265 return myAnim->isProportional();
1268 void VISU_TimeAnimation_i::setAnimationRange (CORBA::Double theMin,
1269 CORBA::Double theMax)
1271 myAnim->setAnimationRange(theMin,theMax);
1274 CORBA::Double VISU_TimeAnimation_i::getMinRange()
1276 return myAnim->getMinRange();
1279 CORBA::Double VISU_TimeAnimation_i::getMaxRange()
1281 return myAnim->getMaxRange();
1284 CORBA::Boolean VISU_TimeAnimation_i::isRangeDefined()
1286 return myAnim->isRangeDefined();
1289 void VISU_TimeAnimation_i::dumpTo (const char* thePath)
1291 myAnim->dumpTo(thePath);
1294 char* VISU_TimeAnimation_i::setDumpFormat (const char* theFormat)
1296 string aDumpFormat = myAnim->setDumpFormat(theFormat);
1297 return CORBA::string_dup(aDumpFormat.c_str());
1300 CORBA::Boolean VISU_TimeAnimation_i::isCycling()
1302 return myAnim->isCycling();
1305 CORBA::Double VISU_TimeAnimation_i::getMinTime()
1307 return myAnim->getMinTime();
1310 CORBA::Double VISU_TimeAnimation_i::getMaxTime()
1312 return myAnim->getMaxTime();
1315 void VISU_TimeAnimation_i::setProportional (CORBA::Boolean theProp)
1317 myAnim->setProportional(theProp);
1320 void VISU_TimeAnimation_i::setCycling (CORBA::Boolean theCycle)
1322 myAnim->setCycling(theCycle);
1325 SALOMEDS::SObject_ptr VISU_TimeAnimation_i::publishInStudy()
1327 return myAnim->publishInStudy();
1330 void VISU_TimeAnimation_i::restoreFromStudy(SALOMEDS::SObject_ptr theObj)
1332 myAnim->restoreFromStudy(theObj);
1335 CORBA::Boolean VISU_TimeAnimation_i::isSavedInStudy()
1337 return myAnim->isSavedInStudy();
1340 void VISU_TimeAnimation_i::saveAnimation()
1342 myAnim->saveAnimation();