]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_TimeAnimation.cxx
Salome HOME
NRI : Merge from V1_2.
[modules/visu.git] / src / VISU_I / VISU_TimeAnimation.cxx
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : VISU_TimeAnimation.cxx
6 //  Author : Vitaly SMETANNIKOV
7 //  Module : VISU
8
9 #include "VISU_TimeAnimation.h"
10 #include "VISU_ScalarBarActor.hxx"
11
12 //QWaitCondition myCondition;
13 static int MYDELAY = 1;
14
15 //************************************************************************
16 VISU_TimeAnimation::VISU_TimeAnimation(SALOMEDS::Study_var theStudy, VISU::View3D_ptr theView3D) {
17   myStudy = theStudy;
18   myIsActive = false;
19   myFrame = 0;
20   mySpeed = 1;
21   myProportional = false;
22   myView = 0;
23
24   if(!CORBA::is_nil(theView3D)){
25     VISU::View3D_i* pView = dynamic_cast<VISU::View3D_i*>(GetServant(theView3D));
26     QAD_StudyFrame* aStudyFrame = pView->GetStudyFrame();
27     myView = VISU::GetViewFrame(aStudyFrame);
28   }
29
30   myMaxVal = 0;
31   myMinVal = 0;
32   myTimeMin = 0;
33   myTimeMax = 0;
34   myLastError = "";
35   myCycling = false;
36 }
37
38
39 //************************************************************************
40 VISU_TimeAnimation::~VISU_TimeAnimation() {
41   for (int i = 0; i < getNbFields(); i++) {
42     clearData(myFieldsLst[i]);
43   }
44 }
45
46
47 //************************************************************************
48 void VISU_TimeAnimation::addField(SALOMEDS::SObject_ptr theField) {
49   FieldData aNewData;
50   aNewData.myField = SALOMEDS::SObject::_duplicate(theField);
51   aNewData.myNbFrames = 0;
52   aNewData.myPrs = 0;
53   aNewData.myActors = 0;
54   aNewData.myTiming = 0;
55   aNewData.myPrsType = VISU::TSCALARMAP;
56   VISU::Storable::TRestoringMap aMap = getMapOfValue(aNewData.myField);
57   aNewData.myNbTimes = VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
58   myFieldsLst.append(aNewData);
59
60   //find Min/Max timestamps
61   if ((myTimeMin == 0) && (myTimeMax == 0)) {
62     SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(theField);
63     SALOMEDS::SObject_var aTimeStamp;
64     anIter->Next(); // First is reference on support
65     myTimeMin = getTimeValue(anIter->Value());
66     for(; anIter->More(); anIter->Next()) {
67       myTimeMax = getTimeValue(anIter->Value());
68     }
69   }
70 }
71
72
73 //************************************************************************
74 void VISU_TimeAnimation::clearData(FieldData& theData) {
75   if (theData.myTiming) {
76     free(theData.myTiming);
77     theData.myTiming = 0;
78   }
79   vtkRenderer* aRen = myView->getRenderer();
80   if (theData.myActors) {
81     for (int i = 0; i < theData.myNbFrames; i++) {
82       if (theData.myActors[i] != 0) {
83         theData.myActors[i]->RemoveFromRender(aRen);
84         theData.myActors[i]->Delete();
85       }
86     }
87     free(theData.myActors);
88     theData.myActors = 0;
89   }
90   if (theData.myPrs) {
91     for (int i = 0; i < theData.myNbFrames; i++) 
92       theData.myPrs[i]->_remove_ref();
93     free(theData.myPrs);
94     theData.myPrs = 0;
95   }  
96   theData.myNbFrames = 0;
97   myView->update();
98 }
99
100
101 //************************************************************************
102 void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
103   FieldData& aData = myFieldsLst[theFieldNum];
104
105   // Delete previous presentations
106   clearData(aData);
107
108   VISU::Result_i* pResult = createPresent(aData.myField); 
109   VISU::Storable::TRestoringMap aMap = getMapOfValue(aData.myField);
110   aData.myNbFrames = aData.myNbTimes;
111     //VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
112
113   aData.myPrs = (VISU::ScalarMap_i**) malloc(aData.myNbTimes * sizeof(VISU::ScalarMap_i*));
114   aData.myTiming = (double*) malloc(aData.myNbTimes * sizeof(double));
115
116   SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(aData.myField);
117   SALOMEDS::SObject_var aTimeStamp;
118   anIter->Next(); // First is reference on support
119   long i = 0;
120   double aMin = 0, aMax = 0;
121   for(;anIter->More();anIter->Next()) {
122     if (i == aData.myNbTimes) {
123       MESSAGE("There are extra timestamps in field");
124       return;
125     }
126     aTimeStamp = anIter->Value();
127     if (aTimeStamp->_is_nil()) continue;
128
129     aData.myTiming[i] = getTimeValue(aTimeStamp);
130     if (isRangeDefined()) {
131       if (aData.myTiming[i] < myMinVal) continue;
132       if (aData.myTiming[i] > myMaxVal) break;
133     }
134
135     VISU::Storable::TRestoringMap aTimeMap = getMapOfValue(aTimeStamp);
136     QString aMeshName = VISU::Storable::FindValue(aTimeMap,"myMeshName"); 
137     VISU::Entity anEntity = (VISU::Entity) VISU::Storable::FindValue(aTimeMap,"myEntityId").toInt(); 
138     QString aFieldName = VISU::Storable::FindValue(aTimeMap,"myFieldName"); 
139     double aTimeStampId = VISU::Storable::FindValue(aTimeMap,"myTimeStampId").toDouble(); 
140     
141     switch (aData.myPrsType) {
142     case VISU::TSCALARMAP: // ScalarMap
143       {
144         VISU::ScalarMap_i* aPresent = new VISU::ScalarMap_i(pResult, false);
145         aPresent->Create(aMeshName.latin1(), anEntity, 
146                          aFieldName.latin1(), aTimeStampId);
147         //VISU::ScalarMap_var aTmp = aPresent->_this();
148         //aPresent->_remove_ref();
149         aData.myPrs[i] = aPresent;
150       }
151       break;
152       
153     case VISU::TISOSURFACE: // Iso Surfaces
154       {
155         VISU::IsoSurfaces_i* aPresent = new VISU::IsoSurfaces_i(pResult, false);
156         aPresent->Create(aMeshName.latin1(), anEntity, 
157                          aFieldName.latin1(), aTimeStampId);
158         //VISU::IsoSurfaces_var aTmp = aPresent->_this();
159         //aPresent->_remove_ref();
160         aData.myPrs[i] = aPresent;
161       }
162       break;
163     
164     case VISU::TCUTPLANES: // Cut Planes
165       {
166         VISU::CutPlanes_i* aPresent = new VISU::CutPlanes_i(pResult, false);
167         aPresent->Create(aMeshName.latin1(), anEntity, 
168                          aFieldName.latin1(), aTimeStampId);
169         //VISU::CutPlanes_var aTmp = aPresent->_this();
170         //aPresent->_remove_ref();
171         aData.myPrs[i] = aPresent;
172       }
173       break;
174       
175     case VISU::TDEFORMEDSHAPE: // Deformed Shape
176       {
177         VISU::DeformedShape_i* aPresent = new VISU::DeformedShape_i(pResult, false);
178         aPresent->Create(aMeshName.latin1(), anEntity, 
179                          aFieldName.latin1(), aTimeStampId);
180         //VISU::DeformedShape_var aTmp = aPresent->_this();
181         //aPresent->_remove_ref();
182         aData.myPrs[i] = aPresent;
183       }
184       break;
185       
186     case VISU::TVECTORS: // Vectors
187       {
188         VISU::Vectors_i* aPresent = new VISU::Vectors_i(pResult, false);
189         aPresent->Create(aMeshName.latin1(), anEntity, 
190                          aFieldName.latin1(), aTimeStampId);
191         //VISU::Vectors_var aTmp = aPresent->_this();
192         //aPresent->_remove_ref();
193         aData.myPrs[i] = aPresent;
194       }
195       break;
196       
197     case VISU::TSTREAMLINES: // Stream Lines
198       {
199         VISU::StreamLines_i* aPresent = new VISU::StreamLines_i(pResult, false);
200         aPresent->Create(aMeshName.latin1(), anEntity, 
201                          aFieldName.latin1(), aTimeStampId);
202         //VISU::StreamLines_var aTmp = aPresent->_this();
203         //aPresent->_remove_ref();
204         aData.myPrs[i] = aPresent;
205       }
206       break;
207     }
208     if (aData.myPrs[i]->GetMin() < aMin) aMin = aData.myPrs[i]->GetMin();
209     if (aData.myPrs[i]->GetMax() > aMax) aMax = aData.myPrs[i]->GetMax();
210     i++;
211   }
212   aData.myNbFrames = i;
213   for (i = 0; i < aData.myNbFrames; i++) 
214     aData.myPrs[i]->SetRange(aMin, aMax);
215 }
216
217
218 //************************************************************************
219 CORBA::Boolean VISU_TimeAnimation::generateFrames() {
220   if (!myView) {
221     MESSAGE("Viewer is nod defined for animation");
222     return false;
223   }
224   myLastError = QString("Frame(s) for ");
225   bool aNoError = true;
226   VISU::Mutex mt(myMutex,qApp,MYDELAY);
227   clearView();
228   vtkRenderer* aRen = myView->getRenderer();
229   for (int i = 0; i < getNbFields(); i++) {
230     FieldData& aData = myFieldsLst[i];
231     aData.myActors = (VISU_Actor**) malloc(aData.myNbFrames * sizeof(VISU_Actor*));
232     for (long j = 0; j < aData.myNbFrames; j++) {
233       VISU_Actor* aActor = aData.myPrs[j]->CreateActor();
234       if (aActor == NULL) {
235         aNoError = false;
236         aActor = 0;
237         myLastError += QString("%1 ").arg(aData.myTiming[j]);
238       } else {
239         myView->AddActor(aActor);
240         if (j == 0) {
241           aActor->VisibilityOn();
242         } else
243           aActor->VisibilityOff();
244       }
245       aData.myActors[j] = aActor;
246     }
247   }
248   myFrame = 0;
249   myLastError += QString(" timestamp(s) cannot be created.");
250   emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
251   myView->Repaint();
252   return aNoError;
253 }
254
255 //************************************************************************
256 void VISU_TimeAnimation::clearView() {
257   if (!myView) {
258     MESSAGE("Viewer is nod defined for animation");
259     return;
260   }
261   VISU::Mutex mt(myMutex,qApp,MYDELAY);
262   vtkRenderer* aRen = myView->getRenderer();
263   for (int i = 0; i < getNbFields(); i++) {
264     FieldData& aData = myFieldsLst[i];
265     if (aData.myActors) {
266       for (int i = 0; i < aData.myNbFrames; i++) {
267         if (aData.myActors[i] != 0) {
268           aData.myActors[i]->RemoveFromRender(aRen);
269           aData.myActors[i]->Delete();
270         }
271       } 
272       free(aData.myActors);
273       aData.myActors = 0;
274     }
275   }
276   myView->update();
277 }
278
279 //************************************************************************
280 void VISU_TimeAnimation::stopAnimation() {
281   myIsActive = false;
282 }
283
284 //************************************************************************
285 void VISU_TimeAnimation::startAnimation() {
286   if (!myIsActive) {
287     myIsActive = true;
288     QThread::start();
289   }
290 }
291
292 //************************************************************************
293 void VISU_TimeAnimation::nextFrame() {
294   stopAnimation();
295   if (myFrame < (myFieldsLst[0].myNbFrames-1)) {
296     int i;
297     for (i = 0; i < getNbFields(); i++) 
298       if (myFieldsLst[i].myActors[myFrame] != 0)
299         myFieldsLst[i].myActors[myFrame]->VisibilityOff();
300     myFrame++;
301     for (i = 0; i < getNbFields(); i++) 
302       if (myFieldsLst[i].myActors[myFrame] != 0)
303         myFieldsLst[i].myActors[myFrame]->VisibilityOn(); 
304
305     emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
306     myView->Repaint();
307   }
308 }
309
310 //************************************************************************
311 void VISU_TimeAnimation::prevFrame() {
312   stopAnimation();
313   if (myFrame > 0) {
314     int i;
315     for (i = 0; i < getNbFields(); i++) 
316       if (myFieldsLst[i].myActors[myFrame] != 0)
317         myFieldsLst[i].myActors[myFrame]->VisibilityOff();
318     myFrame--;
319     for (i = 0; i < getNbFields(); i++) 
320       if (myFieldsLst[i].myActors[myFrame] != 0)
321         myFieldsLst[i].myActors[myFrame]->VisibilityOn();    
322
323     emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
324     myView->Repaint();
325   }
326 }
327
328 //************************************************************************
329 void VISU_TimeAnimation::firstFrame() {
330   stopAnimation();
331   int i;
332   for (i = 0; i < getNbFields(); i++) 
333     if (myFieldsLst[i].myActors[myFrame] != 0)
334       myFieldsLst[i].myActors[myFrame]->VisibilityOff();
335   myFrame = 0;
336   for (i = 0; i < getNbFields(); i++) 
337     if (myFieldsLst[i].myActors[myFrame] != 0)
338       myFieldsLst[i].myActors[myFrame]->VisibilityOn();    
339
340   emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
341   myView->Repaint();
342 }
343
344 //************************************************************************
345 void VISU_TimeAnimation::lastFrame() {
346   stopAnimation();
347   int i;
348   for (i = 0; i < getNbFields(); i++) 
349     if (myFieldsLst[i].myActors[myFrame] != 0)
350       myFieldsLst[i].myActors[myFrame]->VisibilityOff();
351   myFrame = myFieldsLst[0].myNbFrames-1;
352   for (i = 0; i < getNbFields(); i++) 
353     if (myFieldsLst[i].myActors[myFrame] != 0)
354       myFieldsLst[i].myActors[myFrame]->VisibilityOn();
355     
356   emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
357   myView->Repaint();
358 }
359
360
361 //************************************************************************
362 // For Batchmode using
363 void VISU_TimeAnimation::gotoFrame(CORBA::Long theFrame) {
364   if ((theFrame < 0) || (theFrame > (getNbFrames()-1))) 
365     return;
366   stopAnimation();
367   qApp->lock();
368   qApp->syncX();
369   int i;
370   for (i = 0; i < getNbFields(); i++) 
371     if (myFieldsLst[i].myActors[myFrame] != 0)
372       myFieldsLst[i].myActors[myFrame]->VisibilityOff();
373   myFrame = theFrame;
374   for (i = 0; i < getNbFields(); i++) 
375     if (myFieldsLst[i].myActors[myFrame] != 0)
376       myFieldsLst[i].myActors[myFrame]->VisibilityOn();
377   emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
378   myView->Repaint();
379   qApp->flushX(); 
380   qApp->processEvents(3);
381   qApp->unlock();
382 }
383
384
385 //************************************************************************
386 VISU::ScalarMap_ptr VISU_TimeAnimation::getPresentation(CORBA::Long theField, CORBA::Long theFrame) {
387   if ((theField > getNbFields()) || (theField < 0))
388     return VISU::ScalarMap::_nil();
389   if ((theFrame < 0) || (theFrame > (myFieldsLst[theField].myNbFrames - 1)))
390     return VISU::ScalarMap::_nil();
391   return myFieldsLst[theField].myPrs[theFrame]->_this();
392 }
393
394
395 //************************************************************************
396 CORBA::Long VISU_TimeAnimation::getNbFrames() { 
397   return (getNbFields() > 0)? myFieldsLst[0].myNbFrames : 0;
398 }
399
400
401 //************************************************************************
402 void VISU_TimeAnimation::run() {
403   if (!myView) {
404     MESSAGE("Viewer is nod defined for animation");
405     return;
406   }
407
408   double k=1;
409   double aOneVal;
410   bool isDumping = !myDumpPath.isEmpty();
411   aOneVal = (myFieldsLst[0].myNbFrames > 2) ?
412     myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0] : 1;
413
414   qApp->lock();      
415   while (myIsActive) {
416     emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
417     for (int i = 0; i < getNbFields(); i++) {
418       FieldData& aData = myFieldsLst[i];
419       if (myFrame > 0) {
420         if (aData.myActors[myFrame-1] != 0) 
421           aData.myActors[myFrame-1]->VisibilityOff();
422       } else { 
423         if (aData.myActors[aData.myNbFrames-1] != 0)
424           aData.myActors[aData.myNbFrames-1]->VisibilityOff();
425       }
426       if (aData.myActors[myFrame] != 0) {
427         aData.myActors[myFrame]->VisibilityOn();
428       }
429     }
430     myView->Repaint();
431     if (isDumping) {
432       QPixmap px = QPixmap::grabWindow(myView->getViewWidget()->winId());
433       QString aFile(myDumpPath);
434       QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
435       int aPos = -1;
436       while ((aPos = aName.find(".")) > -1 )
437         aName.replace(aPos, 1, "_");
438       aFile += aName;
439       aFile += ".jpeg";
440       px.save(aFile, "JPEG");
441     }
442     if (!isDumping) {
443       if (myProportional) {
444         switch (myFrame) {
445         case 0:
446           k=1;
447           break;        
448         case 1:
449           if (myFieldsLst[0].myNbFrames > 2)
450             k = (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal;
451           else
452             k = 1;
453           break;        
454         default:
455           k = (myFrame < (myFieldsLst[0].myNbFrames-1))? 
456             (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal : 1;
457         }
458       } else
459         k = 1;
460       
461       qApp->unlock();
462       msleep((int)(1000.*k/mySpeed));
463       qApp->lock();
464     } else {
465       qApp->unlock();
466       msleep(100);
467       qApp->lock();
468     }
469     if (!myIsActive) break;
470
471     myFrame++;
472     if (myFrame == myFieldsLst[0].myNbFrames) {
473       if (!myCycling) {
474         myIsActive = false;
475         myFrame--;
476         break;
477       } else
478         myFrame = 0;
479     }
480   }
481   emit stopped();
482   qApp->unlock();
483   QThread::exit();
484 }
485
486 //************************************************************************
487 VISU::Result_i* VISU_TimeAnimation::createPresent(SALOMEDS::SObject_var theField) {
488   SALOMEDS::SObject_var aSObj = theField->GetFather();
489   aSObj = aSObj->GetFather();
490   aSObj = aSObj->GetFather();
491   CORBA::Object_var anObject = VISU::SObjectToObject(aSObj);
492   if(CORBA::is_nil(anObject)) return NULL;
493   return dynamic_cast<VISU::Result_i*>(VISU::GetServant(anObject));
494 }
495
496
497 //************************************************************************
498 VISU::Storable::TRestoringMap VISU_TimeAnimation::getMapOfValue(SALOMEDS::SObject_var theSObject) {
499   VISU::Storable::TRestoringMap aMap;
500   if(!theSObject->_is_nil()){
501     SALOMEDS::GenericAttribute_var anAttr;
502     if (theSObject->FindAttribute(anAttr, "AttributeComment")) {
503       SALOMEDS::AttributeComment_var aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
504       CORBA::String_var aString = aComment->Value();
505       QString strIn(aString.in());
506       VISU::Storable::StrToMap(strIn,aMap);
507     }
508   }
509   return aMap;
510 }
511
512 //************************************************************************
513 double VISU_TimeAnimation::getTimeValue(SALOMEDS::SObject_var theTimeStamp) {
514   SALOMEDS::GenericAttribute_var anAttr;
515   if(theTimeStamp->FindAttribute(anAttr, "AttributeName")) {
516     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
517     QString aNameString(aName->Value());
518     return aNameString.toDouble();
519   }
520 }
521   
522 //************************************************************************
523 void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed) { 
524   mySpeed = (theSpeed<1)? 1 : theSpeed; 
525 }