1 // Copyright (C) 2003 CEA/DEN, EDF R&D
5 // File : VISU_TimeAnimation.cxx
6 // Author : Vitaly SMETANNIKOV
9 #include "VISU_TimeAnimation.h"
10 #include "VISU_Result_i.hh"
11 #include "VISU_Prs3d_i.hh"
12 #include "VISU_Mesh_i.hh"
13 #include "VISU_ScalarMap_i.hh"
14 #include "VISU_IsoSurfaces_i.hh"
15 #include "VISU_DeformedShape_i.hh"
16 #include "VISU_CutPlanes_i.hh"
17 #include "VISU_CutLines_i.hh"
18 #include "VISU_Vectors_i.hh"
19 #include "VISU_StreamLines_i.hh"
20 #include "VISU_ViewManager_i.hh"
21 #include "VISU_ScalarBarActor.hxx"
22 #include "VISU_Actor.h"
24 #include "SALOME_Event.hxx"
26 #include "VTKViewer_ViewFrame.h"
28 #include "QAD_Config.h"
32 //QWaitCondition myCondition;
33 static int MYDELAY = 1;
35 //************************************************************************
36 VISU_TimeAnimation::VISU_TimeAnimation(SALOMEDS::Study_ptr theStudy, VISU::View3D_ptr theView3D) {
41 myProportional = false;
44 if(!CORBA::is_nil(theView3D)){
45 VISU::View3D_i* pView = dynamic_cast<VISU::View3D_i*>(GetServant(theView3D).in());
46 QAD_StudyFrame* aStudyFrame = pView->GetStudyFrame();
47 myView = VISU::GetViewFrame(aStudyFrame);
59 //************************************************************************
60 VISU_TimeAnimation::~VISU_TimeAnimation() {
61 for (int i = 0; i < getNbFields(); i++) {
62 clearData(myFieldsLst[i]);
67 //************************************************************************
68 void VISU_TimeAnimation::addField(SALOMEDS::SObject_ptr theField) {
70 aNewData.myField = SALOMEDS::SObject::_duplicate(theField);
71 aNewData.myNbFrames = 0;
72 aNewData.myPrsType = VISU::TSCALARMAP;
73 VISU::Storable::TRestoringMap aMap = getMapOfValue(aNewData.myField);
74 aNewData.myNbTimes = VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
75 myFieldsLst.append(aNewData);
77 //find Min/Max timestamps
78 if ((myTimeMin == 0) && (myTimeMax == 0)) {
79 SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(theField);
80 SALOMEDS::SObject_var aTimeStamp;
81 anIter->Next(); // First is reference on support
82 myTimeMin = getTimeValue(anIter->Value());
83 for(; anIter->More(); anIter->Next()) {
84 myTimeMax = getTimeValue(anIter->Value());
90 //************************************************************************
91 void VISU_TimeAnimation::clearData(FieldData& theData) {
92 theData.myTiming.clear();
93 vtkRenderer* aRen = myView->getRenderer();
94 if (!theData.myActors.empty()) {
95 for (int i = 0, iEnd = theData.myActors.size(); i < iEnd; i++) {
96 if (theData.myActors[i] != 0) {
97 theData.myActors[i]->RemoveFromRender(aRen);
98 theData.myActors[i]->Delete();
101 theData.myActors.clear();
103 if (!theData.myPrs.empty()) {
104 for (int i = 0, iEnd = theData.myPrs.size(); i < iEnd; i++)
105 if (theData.myPrs[i] != 0) {
106 theData.myPrs[i]->_remove_ref();
108 theData.myPrs.clear();
110 theData.myNbFrames = 0;
115 //************************************************************************
116 void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
117 FieldData& aData = myFieldsLst[theFieldNum];
119 // Delete previous presentations
122 VISU::Result_i* pResult = createPresent(aData.myField);
123 VISU::Storable::TRestoringMap aMap = getMapOfValue(aData.myField);
124 aData.myNbFrames = aData.myNbTimes;
125 //VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
127 aData.myPrs.resize(aData.myNbTimes,NULL);
128 aData.myTiming.resize(aData.myNbTimes);
130 SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(aData.myField);
131 SALOMEDS::SObject_var aTimeStamp;
132 anIter->Next(); // First is reference on support
134 double aMin = VTK_LARGE_FLOAT, aMax = -VTK_LARGE_FLOAT;
135 for(;anIter->More();anIter->Next()) {
136 if (i == aData.myNbTimes) {
137 MESSAGE("There are extra timestamps in field");
140 aTimeStamp = anIter->Value();
141 if (aTimeStamp->_is_nil()) continue;
143 aData.myTiming[i] = getTimeValue(aTimeStamp);
144 if (isRangeDefined()) {
145 if (aData.myTiming[i] < myMinVal) continue;
146 if (aData.myTiming[i] > myMaxVal) break;
149 VISU::Storable::TRestoringMap aTimeMap = getMapOfValue(aTimeStamp);
150 QString aMeshName = VISU::Storable::FindValue(aTimeMap,"myMeshName");
151 VISU::Entity anEntity = (VISU::Entity) VISU::Storable::FindValue(aTimeMap,"myEntityId").toInt();
152 QString aFieldName = VISU::Storable::FindValue(aTimeMap,"myFieldName");
153 int aTimeStampId = VISU::Storable::FindValue(aTimeMap,"myTimeStampId").toInt();
155 switch (aData.myPrsType) {
156 case VISU::TSCALARMAP: // ScalarMap
158 VISU::ScalarMap_i* aPresent = new VISU::ScalarMap_i(pResult, false);
159 aPresent->Create(aMeshName.latin1(), anEntity,
160 aFieldName.latin1(), aTimeStampId);
161 //VISU::ScalarMap_var aTmp = aPresent->_this();
162 //aPresent->_remove_ref();
163 aData.myPrs[i] = aPresent;
167 case VISU::TISOSURFACE: // Iso Surfaces
169 VISU::IsoSurfaces_i* aPresent = new VISU::IsoSurfaces_i(pResult, false);
170 aPresent->Create(aMeshName.latin1(), anEntity,
171 aFieldName.latin1(), aTimeStampId);
172 //VISU::IsoSurfaces_var aTmp = aPresent->_this();
173 //aPresent->_remove_ref();
174 aData.myPrs[i] = aPresent;
178 case VISU::TCUTPLANES: // Cut Planes
180 VISU::CutPlanes_i* aPresent = new VISU::CutPlanes_i(pResult, false);
181 aPresent->Create(aMeshName.latin1(), anEntity,
182 aFieldName.latin1(), aTimeStampId);
183 //VISU::CutPlanes_var aTmp = aPresent->_this();
184 //aPresent->_remove_ref();
185 aData.myPrs[i] = aPresent;
189 case VISU::TDEFORMEDSHAPE: // Deformed Shape
191 VISU::DeformedShape_i* aPresent = new VISU::DeformedShape_i(pResult, false);
192 aPresent->Create(aMeshName.latin1(), anEntity,
193 aFieldName.latin1(), aTimeStampId);
194 //VISU::DeformedShape_var aTmp = aPresent->_this();
195 //aPresent->_remove_ref();
196 aData.myPrs[i] = aPresent;
200 case VISU::TVECTORS: // Vectors
202 VISU::Vectors_i* aPresent = new VISU::Vectors_i(pResult, false);
203 aPresent->Create(aMeshName.latin1(), anEntity,
204 aFieldName.latin1(), aTimeStampId);
205 //VISU::Vectors_var aTmp = aPresent->_this();
206 //aPresent->_remove_ref();
207 aData.myPrs[i] = aPresent;
211 case VISU::TSTREAMLINES: // Stream Lines
213 VISU::StreamLines_i* aPresent = new VISU::StreamLines_i(pResult, false);
214 aPresent->Create(aMeshName.latin1(), anEntity,
215 aFieldName.latin1(), aTimeStampId);
216 //VISU::StreamLines_var aTmp = aPresent->_this();
217 //aPresent->_remove_ref();
218 aData.myPrs[i] = aPresent;
222 if (aData.myPrs[i]->GetMin() < aMin) aMin = aData.myPrs[i]->GetMin();
223 if (aData.myPrs[i]->GetMax() > aMax) aMax = aData.myPrs[i]->GetMax();
226 aData.myNbFrames = i;
227 QString aFixRange = QAD_CONFIG->getSetting("Visu:SBImposeRange");
228 if (aFixRange.compare("true") != 0) {
229 for (i = 0; i < aData.myNbFrames; i++)
230 aData.myPrs[i]->SetRange(aMin, aMax);
231 if(aData.myPrsType == VISU::TISOSURFACE)
232 for (i = 0; i < aData.myNbFrames; i++)
233 if(VISU::IsoSurfaces_i* aPrs = dynamic_cast<VISU::IsoSurfaces_i*>(aData.myPrs[i]))
234 aPrs->SetSubRange(aMin, aMax);
239 //************************************************************************
240 CORBA::Boolean VISU_TimeAnimation::generateFrames() {
242 MESSAGE("Viewer is nod defined for animation");
246 myLastError = QString("Frame(s) for ");
247 bool aNoError = true;
250 vtkRenderer* aRen = myView->getRenderer();
252 for (int i = 0; i < getNbFields(); i++) {
253 FieldData& aData = myFieldsLst[i];
254 aData.myActors.resize(aData.myNbFrames,NULL);
255 for (long j = 0; j < aData.myNbFrames; j++) {
256 VISU_Actor* aActor = NULL;
258 aActor = aData.myPrs[j]->CreateActor();
259 myView->AddActor(aActor);
261 aActor->VisibilityOn();
263 aActor->VisibilityOff();
264 }catch(...){ //catch(std::runtime_error& exc){
266 myLastError += QString("%1 ").arg(aData.myTiming[j]);
268 aData.myActors[j] = aActor;
272 myLastError += QString(" timestamp(s) cannot be created.");
273 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
278 //************************************************************************
279 void VISU_TimeAnimation::clearView() {
281 MESSAGE("Viewer is nod defined for animation");
284 vtkRenderer* aRen = myView->getRenderer();
285 for (int i = 0; i < getNbFields(); i++) {
286 FieldData& aData = myFieldsLst[i];
287 if (!aData.myActors.empty()) {
288 for (int i = 0, iEnd = aData.myActors.size(); i < iEnd; i++) {
289 if (aData.myActors[i] != 0) {
290 aData.myActors[i]->RemoveFromRender(aRen);
291 aData.myActors[i]->Delete();
294 aData.myActors.clear();
297 VISU::RepaintView(myView);
301 //************************************************************************
302 void VISU_TimeAnimation::stopAnimation() {
306 //************************************************************************
307 void VISU_TimeAnimation::startAnimation() {
314 //************************************************************************
315 void VISU_TimeAnimation::nextFrame() {
317 if (myFrame < (myFieldsLst[0].myNbFrames-1)) {
319 for (i = 0; i < getNbFields(); i++)
320 if (myFieldsLst[i].myActors[myFrame] != 0)
321 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
324 for (i = 0; i < getNbFields(); i++)
325 if (myFieldsLst[i].myActors[myFrame] != 0)
326 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
328 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
333 //************************************************************************
334 void VISU_TimeAnimation::prevFrame() {
338 for (i = 0; i < getNbFields(); i++)
339 if (myFieldsLst[i].myActors[myFrame] != 0)
340 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
343 for (i = 0; i < getNbFields(); i++)
344 if (myFieldsLst[i].myActors[myFrame] != 0)
345 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
347 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
352 //************************************************************************
353 void VISU_TimeAnimation::firstFrame() {
356 for (i = 0; i < getNbFields(); i++)
357 if(!myFieldsLst[i].myActors.empty())
358 if (myFieldsLst[i].myActors[myFrame] != 0)
359 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
361 for (i = 0; i < getNbFields(); i++)
362 if(!myFieldsLst[i].myActors.empty())
363 if (myFieldsLst[i].myActors[myFrame] != 0)
364 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
365 if(!myFieldsLst[0].myTiming.empty()){
366 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
371 //************************************************************************
372 void VISU_TimeAnimation::lastFrame() {
375 for (i = 0; i < getNbFields(); i++)
376 if (myFieldsLst[i].myActors[myFrame] != 0)
377 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
379 myFrame = myFieldsLst[0].myNbFrames-1;
380 for (i = 0; i < getNbFields(); i++)
381 if (myFieldsLst[i].myActors[myFrame] != 0)
382 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
384 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
389 //************************************************************************
390 // For Batchmode using
391 void VISU_TimeAnimation::gotoFrame(CORBA::Long theFrame) {
392 if ((theFrame < 0) || (theFrame > (getNbFrames()-1)))
398 for (i = 0; i < getNbFields(); i++)
399 if (myFieldsLst[i].myActors[myFrame] != 0)
400 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
403 for (i = 0; i < getNbFields(); i++)
404 if (myFieldsLst[i].myActors[myFrame] != 0)
405 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
407 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
410 qApp->processEvents(3);
415 //************************************************************************
416 VISU::ScalarMap_ptr VISU_TimeAnimation::getPresentation(CORBA::Long theField, CORBA::Long theFrame) {
417 if ((theField > getNbFields()) || (theField < 0))
418 return VISU::ScalarMap::_nil();
419 if ((theFrame < 0) || (theFrame > (myFieldsLst[theField].myNbFrames - 1)))
420 return VISU::ScalarMap::_nil();
421 return myFieldsLst[theField].myPrs[theFrame]->_this();
425 //************************************************************************
426 CORBA::Long VISU_TimeAnimation::getNbFrames() {
427 return (getNbFields() > 0)? myFieldsLst[0].myNbFrames : 0;
431 //************************************************************************
432 void VISU_TimeAnimation::run() {
434 MESSAGE("Viewer is nod defined for animation");
439 bool isDumping = !myDumpPath.isEmpty();
440 aOneVal = (myFieldsLst[0].myNbFrames > 2) ?
441 myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0] : 1;
444 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
445 for (int i = 0; i < getNbFields(); i++) {
446 FieldData& aData = myFieldsLst[i];
448 if (aData.myActors[myFrame-1] != 0)
449 aData.myActors[myFrame-1]->VisibilityOff();
451 if (aData.myActors[aData.myNbFrames-1] != 0)
452 aData.myActors[aData.myNbFrames-1]->VisibilityOff();
454 if (aData.myActors[myFrame] != 0) {
455 aData.myActors[myFrame]->VisibilityOn();
458 myView->Repaint(false);
460 QPixmap px = QPixmap::grabWindow(myView->getViewWidget()->winId());
461 QString aFile(myDumpPath);
462 QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
464 while ((aPos = aName.find(".")) > -1 )
465 aName.replace(aPos, 1, "_");
468 px.save(aFile, "JPEG");
471 if (myProportional) {
477 if (myFieldsLst[0].myNbFrames > 2)
478 k = (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal;
483 k = (myFrame < (myFieldsLst[0].myNbFrames-1))?
484 (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal : 1;
489 msleep((int)(1000.*k/mySpeed));
496 if (!myIsActive) break;
499 if (myFrame == myFieldsLst[0].myNbFrames) {
513 //************************************************************************
514 VISU::Result_i* VISU_TimeAnimation::createPresent(SALOMEDS::SObject_var theField) {
515 SALOMEDS::SObject_var aSObj = theField->GetFather();
516 aSObj = aSObj->GetFather();
517 aSObj = aSObj->GetFather();
518 CORBA::Object_var anObject = VISU::SObjectToObject(aSObj);
519 if(CORBA::is_nil(anObject)) return NULL;
520 return dynamic_cast<VISU::Result_i*>(VISU::GetServant(anObject).in());
524 //************************************************************************
525 VISU::Storable::TRestoringMap VISU_TimeAnimation::getMapOfValue(SALOMEDS::SObject_var theSObject) {
526 VISU::Storable::TRestoringMap aMap;
527 if(!theSObject->_is_nil()){
528 SALOMEDS::GenericAttribute_var anAttr;
529 if (theSObject->FindAttribute(anAttr, "AttributeComment")) {
530 SALOMEDS::AttributeComment_var aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
531 CORBA::String_var aString = aComment->Value();
532 QString strIn(aString.in());
533 VISU::Storable::StrToMap(strIn,aMap);
539 //************************************************************************
540 double VISU_TimeAnimation::getTimeValue(SALOMEDS::SObject_var theTimeStamp) {
541 SALOMEDS::GenericAttribute_var anAttr;
542 if(theTimeStamp->FindAttribute(anAttr, "AttributeName")) {
543 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
544 QString aNameString(aName->Value());
545 return aNameString.toDouble();
550 //************************************************************************
551 void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed) {
552 mySpeed = (theSpeed<1)? 1 : theSpeed;
556 //========================================================================
557 VISU_TimeAnimation_i::VISU_TimeAnimation_i(SALOMEDS::Study_ptr theStudy, VISU::View3D_ptr theView3D){
558 myAnim = new VISU_TimeAnimation(theStudy,theView3D);
562 VISU_TimeAnimation_i::~VISU_TimeAnimation_i(){
567 void VISU_TimeAnimation_i::addField(SALOMEDS::SObject_ptr theField){
568 myAnim->addField(theField);
572 CORBA::Boolean VISU_TimeAnimation_i::generateFrames(){
573 return ProcessEvent(new TMemFunEvent<VISU_TimeAnimation,bool>(myAnim,&VISU_TimeAnimation::generateFrames));
577 void VISU_TimeAnimation_i::generatePresentations(CORBA::Long theFieldNum){
578 myAnim->generatePresentations(theFieldNum);
582 void VISU_TimeAnimation_i::clearView(){
583 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::clearView));
587 void VISU_TimeAnimation_i::stopAnimation(){
588 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::stopAnimation));
592 void VISU_TimeAnimation_i::startAnimation(){
593 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::startAnimation));
597 void VISU_TimeAnimation_i::nextFrame(){
598 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::nextFrame));
602 void VISU_TimeAnimation_i::prevFrame(){
603 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::prevFrame));
607 void VISU_TimeAnimation_i::firstFrame(){
608 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::firstFrame));
612 void VISU_TimeAnimation_i::lastFrame(){
613 ProcessVoidEvent(new TVoidMemFunEvent<VISU_TimeAnimation>(myAnim,&VISU_TimeAnimation::lastFrame));
617 void VISU_TimeAnimation_i::gotoFrame(CORBA::Long theFrame){
618 ProcessVoidEvent(new TVoidMemFun1ArgEvent<VISU_TimeAnimation,CORBA::Long>(myAnim,&VISU_TimeAnimation::gotoFrame,theFrame));
622 CORBA::Long VISU_TimeAnimation_i::getNbFields(){
623 return myAnim->getNbFields();
627 CORBA::Long VISU_TimeAnimation_i::getNbFrames(){
628 return myAnim->getNbFrames();
632 CORBA::Boolean VISU_TimeAnimation_i::isRunning(){
633 return myAnim->isRunning();
637 CORBA::Long VISU_TimeAnimation_i::getCurrentFrame(){
638 return myAnim->getCurrentFrame();
642 VISU::ScalarMap_ptr VISU_TimeAnimation_i::getPresentation(CORBA::Long theField, CORBA::Long theFrame){
643 return myAnim->getPresentation(theField,theFrame);
647 void VISU_TimeAnimation_i::setPresentationType(CORBA::Long theFieldNum, VISU::VISUType theType){
648 myAnim->setPresentationType(theFieldNum,theType);
652 VISU::VISUType VISU_TimeAnimation_i::getPresentationType(CORBA::Long theFieldNum){
653 return myAnim->getPresentationType(theFieldNum);
657 void VISU_TimeAnimation_i::setSpeed(CORBA::Long theSpeed){
658 myAnim->setSpeed(theSpeed);
662 CORBA::Long VISU_TimeAnimation_i::getSpeed(){
663 return myAnim->getSpeed();
667 CORBA::Boolean VISU_TimeAnimation_i::isProportional(){
668 return myAnim->isProportional();
672 void VISU_TimeAnimation_i::setAnimationRange(CORBA::Double theMin, CORBA::Double theMax){
673 myAnim->setAnimationRange(theMin,theMax);
677 CORBA::Double VISU_TimeAnimation_i::getMinRange(){
678 return myAnim->getMinRange();
682 CORBA::Double VISU_TimeAnimation_i::getMaxRange(){
683 return myAnim->getMaxRange();
687 CORBA::Boolean VISU_TimeAnimation_i::isRangeDefined(){
688 return myAnim->isRangeDefined();
692 void VISU_TimeAnimation_i::dumpTo(const char* thePath){
693 myAnim->dumpTo(thePath);
697 CORBA::Boolean VISU_TimeAnimation_i::isCycling(){
698 return myAnim->isCycling();
702 CORBA::Double VISU_TimeAnimation_i::getMinTime(){
703 return myAnim->getMinTime();
707 CORBA::Double VISU_TimeAnimation_i::getMaxTime(){
708 return myAnim->getMaxTime();
712 void VISU_TimeAnimation_i::setProportional(CORBA::Boolean theProp){
713 myAnim->setProportional(theProp);
717 void VISU_TimeAnimation_i::setCycling(CORBA::Boolean theCycle){
718 myAnim->setCycling(theCycle);