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 "VTKViewer_ViewFrame.h"
26 #include "QAD_Config.h"
30 //QWaitCondition myCondition;
31 static int MYDELAY = 1;
33 //************************************************************************
34 VISU_TimeAnimation::VISU_TimeAnimation(SALOMEDS::Study_var theStudy, VISU::View3D_ptr theView3D) {
39 myProportional = false;
42 if(!CORBA::is_nil(theView3D)){
43 VISU::View3D_i* pView = dynamic_cast<VISU::View3D_i*>(GetServant(theView3D));
44 QAD_StudyFrame* aStudyFrame = pView->GetStudyFrame();
45 myView = VISU::GetViewFrame(aStudyFrame);
57 //************************************************************************
58 VISU_TimeAnimation::~VISU_TimeAnimation() {
59 for (int i = 0; i < getNbFields(); i++) {
60 clearData(myFieldsLst[i]);
65 //************************************************************************
66 void VISU_TimeAnimation::addField(SALOMEDS::SObject_ptr theField) {
68 aNewData.myField = SALOMEDS::SObject::_duplicate(theField);
69 aNewData.myNbFrames = 0;
71 aNewData.myActors = 0;
72 aNewData.myTiming = 0;
73 aNewData.myPrsType = VISU::TSCALARMAP;
74 VISU::Storable::TRestoringMap aMap = getMapOfValue(aNewData.myField);
75 aNewData.myNbTimes = VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
76 myFieldsLst.append(aNewData);
78 //find Min/Max timestamps
79 if ((myTimeMin == 0) && (myTimeMax == 0)) {
80 SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(theField);
81 SALOMEDS::SObject_var aTimeStamp;
82 anIter->Next(); // First is reference on support
83 myTimeMin = getTimeValue(anIter->Value());
84 for(; anIter->More(); anIter->Next()) {
85 myTimeMax = getTimeValue(anIter->Value());
91 //************************************************************************
92 void VISU_TimeAnimation::clearData(FieldData& theData) {
93 if (theData.myTiming) {
94 free(theData.myTiming);
97 vtkRenderer* aRen = myView->getRenderer();
98 if (theData.myActors) {
99 for (int i = 0; i < theData.myNbFrames; i++) {
100 if (theData.myActors[i] != 0) {
101 theData.myActors[i]->RemoveFromRender(aRen);
102 theData.myActors[i]->Delete();
105 free(theData.myActors);
106 theData.myActors = 0;
109 for (int i = 0; i < theData.myNbFrames; i++)
110 theData.myPrs[i]->_remove_ref();
114 theData.myNbFrames = 0;
119 //************************************************************************
120 void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
121 FieldData& aData = myFieldsLst[theFieldNum];
123 // Delete previous presentations
126 VISU::Result_i* pResult = createPresent(aData.myField);
127 VISU::Storable::TRestoringMap aMap = getMapOfValue(aData.myField);
128 aData.myNbFrames = aData.myNbTimes;
129 //VISU::Storable::FindValue(aMap,"myNbTimeStamps").toLong();
131 aData.myPrs = (VISU::ScalarMap_i**) malloc(aData.myNbTimes * sizeof(VISU::ScalarMap_i*));
132 aData.myTiming = (double*) malloc(aData.myNbTimes * sizeof(double));
134 SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(aData.myField);
135 SALOMEDS::SObject_var aTimeStamp;
136 anIter->Next(); // First is reference on support
138 double aMin = 0, aMax = 0;
139 for(;anIter->More();anIter->Next()) {
140 if (i == aData.myNbTimes) {
141 MESSAGE("There are extra timestamps in field");
144 aTimeStamp = anIter->Value();
145 if (aTimeStamp->_is_nil()) continue;
147 aData.myTiming[i] = getTimeValue(aTimeStamp);
148 if (isRangeDefined()) {
149 if (aData.myTiming[i] < myMinVal) continue;
150 if (aData.myTiming[i] > myMaxVal) break;
153 VISU::Storable::TRestoringMap aTimeMap = getMapOfValue(aTimeStamp);
154 QString aMeshName = VISU::Storable::FindValue(aTimeMap,"myMeshName");
155 VISU::Entity anEntity = (VISU::Entity) VISU::Storable::FindValue(aTimeMap,"myEntityId").toInt();
156 QString aFieldName = VISU::Storable::FindValue(aTimeMap,"myFieldName");
157 int aTimeStampId = VISU::Storable::FindValue(aTimeMap,"myTimeStampId").toInt();
159 switch (aData.myPrsType) {
160 case VISU::TSCALARMAP: // ScalarMap
162 VISU::ScalarMap_i* aPresent = new VISU::ScalarMap_i(pResult, false);
163 aPresent->Create(aMeshName.latin1(), anEntity,
164 aFieldName.latin1(), aTimeStampId);
165 //VISU::ScalarMap_var aTmp = aPresent->_this();
166 //aPresent->_remove_ref();
167 aData.myPrs[i] = aPresent;
171 case VISU::TISOSURFACE: // Iso Surfaces
173 VISU::IsoSurfaces_i* aPresent = new VISU::IsoSurfaces_i(pResult, false);
174 aPresent->Create(aMeshName.latin1(), anEntity,
175 aFieldName.latin1(), aTimeStampId);
176 //VISU::IsoSurfaces_var aTmp = aPresent->_this();
177 //aPresent->_remove_ref();
178 aData.myPrs[i] = aPresent;
182 case VISU::TCUTPLANES: // Cut Planes
184 VISU::CutPlanes_i* aPresent = new VISU::CutPlanes_i(pResult, false);
185 aPresent->Create(aMeshName.latin1(), anEntity,
186 aFieldName.latin1(), aTimeStampId);
187 //VISU::CutPlanes_var aTmp = aPresent->_this();
188 //aPresent->_remove_ref();
189 aData.myPrs[i] = aPresent;
193 case VISU::TDEFORMEDSHAPE: // Deformed Shape
195 VISU::DeformedShape_i* aPresent = new VISU::DeformedShape_i(pResult, false);
196 aPresent->Create(aMeshName.latin1(), anEntity,
197 aFieldName.latin1(), aTimeStampId);
198 //VISU::DeformedShape_var aTmp = aPresent->_this();
199 //aPresent->_remove_ref();
200 aData.myPrs[i] = aPresent;
204 case VISU::TVECTORS: // Vectors
206 VISU::Vectors_i* aPresent = new VISU::Vectors_i(pResult, false);
207 aPresent->Create(aMeshName.latin1(), anEntity,
208 aFieldName.latin1(), aTimeStampId);
209 //VISU::Vectors_var aTmp = aPresent->_this();
210 //aPresent->_remove_ref();
211 aData.myPrs[i] = aPresent;
215 case VISU::TSTREAMLINES: // Stream Lines
217 VISU::StreamLines_i* aPresent = new VISU::StreamLines_i(pResult, false);
218 aPresent->Create(aMeshName.latin1(), anEntity,
219 aFieldName.latin1(), aTimeStampId);
220 //VISU::StreamLines_var aTmp = aPresent->_this();
221 //aPresent->_remove_ref();
222 aData.myPrs[i] = aPresent;
226 if (aData.myPrs[i]->GetMin() < aMin) aMin = aData.myPrs[i]->GetMin();
227 if (aData.myPrs[i]->GetMax() > aMax) aMax = aData.myPrs[i]->GetMax();
230 aData.myNbFrames = i;
231 QString aFixRange = QAD_CONFIG->getSetting("Visu:SBImposeRange");
232 if (aFixRange.compare("true") != 0) {
233 for (i = 0; i < aData.myNbFrames; i++)
234 aData.myPrs[i]->SetRange(aMin, aMax);
239 //************************************************************************
240 CORBA::Boolean VISU_TimeAnimation::generateFrames() {
242 MESSAGE("Viewer is nod defined for animation");
245 myLastError = QString("Frame(s) for ");
246 bool aNoError = true;
247 VISU::Mutex mt(myMutex,qApp,MYDELAY);
249 vtkRenderer* aRen = myView->getRenderer();
250 for (int i = 0; i < getNbFields(); i++) {
251 FieldData& aData = myFieldsLst[i];
252 aData.myActors = (VISU_Actor**) malloc(aData.myNbFrames * sizeof(VISU_Actor*));
253 for (long j = 0; j < aData.myNbFrames; j++) {
254 VISU_Actor* aActor = NULL;
256 aActor = aData.myPrs[j]->CreateActor();
257 myView->AddActor(aActor);
259 aActor->VisibilityOn();
261 aActor->VisibilityOff();
262 }catch(std::runtime_error& exc){
264 myLastError += QString("%1 ").arg(aData.myTiming[j]);
266 aData.myActors[j] = aActor;
270 myLastError += QString(" timestamp(s) cannot be created.");
271 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
276 //************************************************************************
277 void VISU_TimeAnimation::clearView() {
279 MESSAGE("Viewer is nod defined for animation");
282 VISU::Mutex mt(myMutex,qApp,MYDELAY);
283 vtkRenderer* aRen = myView->getRenderer();
284 for (int i = 0; i < getNbFields(); i++) {
285 FieldData& aData = myFieldsLst[i];
286 if (aData.myActors) {
287 for (int i = 0; i < aData.myNbFrames; i++) {
288 if (aData.myActors[i] != 0) {
289 aData.myActors[i]->RemoveFromRender(aRen);
290 aData.myActors[i]->Delete();
293 free(aData.myActors);
300 //************************************************************************
301 void VISU_TimeAnimation::stopAnimation() {
305 //************************************************************************
306 void VISU_TimeAnimation::startAnimation() {
313 //************************************************************************
314 void VISU_TimeAnimation::nextFrame() {
316 if (myFrame < (myFieldsLst[0].myNbFrames-1)) {
318 for (i = 0; i < getNbFields(); i++)
319 if (myFieldsLst[i].myActors[myFrame] != 0)
320 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
322 for (i = 0; i < getNbFields(); i++)
323 if (myFieldsLst[i].myActors[myFrame] != 0)
324 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
326 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
331 //************************************************************************
332 void VISU_TimeAnimation::prevFrame() {
336 for (i = 0; i < getNbFields(); i++)
337 if (myFieldsLst[i].myActors[myFrame] != 0)
338 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
340 for (i = 0; i < getNbFields(); i++)
341 if (myFieldsLst[i].myActors[myFrame] != 0)
342 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
344 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
349 //************************************************************************
350 void VISU_TimeAnimation::firstFrame() {
353 for (i = 0; i < getNbFields(); i++)
354 if (myFieldsLst[i].myActors[myFrame] != 0)
355 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
357 for (i = 0; i < getNbFields(); i++)
358 if (myFieldsLst[i].myActors[myFrame] != 0)
359 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
361 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
365 //************************************************************************
366 void VISU_TimeAnimation::lastFrame() {
369 for (i = 0; i < getNbFields(); i++)
370 if (myFieldsLst[i].myActors[myFrame] != 0)
371 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
372 myFrame = myFieldsLst[0].myNbFrames-1;
373 for (i = 0; i < getNbFields(); i++)
374 if (myFieldsLst[i].myActors[myFrame] != 0)
375 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
377 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
382 //************************************************************************
383 // For Batchmode using
384 void VISU_TimeAnimation::gotoFrame(CORBA::Long theFrame) {
385 if ((theFrame < 0) || (theFrame > (getNbFrames()-1)))
391 for (i = 0; i < getNbFields(); i++)
392 if (myFieldsLst[i].myActors[myFrame] != 0)
393 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
395 for (i = 0; i < getNbFields(); i++)
396 if (myFieldsLst[i].myActors[myFrame] != 0)
397 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
398 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
401 qApp->processEvents(3);
406 //************************************************************************
407 VISU::ScalarMap_ptr VISU_TimeAnimation::getPresentation(CORBA::Long theField, CORBA::Long theFrame) {
408 if ((theField > getNbFields()) || (theField < 0))
409 return VISU::ScalarMap::_nil();
410 if ((theFrame < 0) || (theFrame > (myFieldsLst[theField].myNbFrames - 1)))
411 return VISU::ScalarMap::_nil();
412 return myFieldsLst[theField].myPrs[theFrame]->_this();
416 //************************************************************************
417 CORBA::Long VISU_TimeAnimation::getNbFrames() {
418 return (getNbFields() > 0)? myFieldsLst[0].myNbFrames : 0;
422 //************************************************************************
423 void VISU_TimeAnimation::run() {
425 MESSAGE("Viewer is nod defined for animation");
431 bool isDumping = !myDumpPath.isEmpty();
432 aOneVal = (myFieldsLst[0].myNbFrames > 2) ?
433 myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0] : 1;
437 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
438 for (int i = 0; i < getNbFields(); i++) {
439 FieldData& aData = myFieldsLst[i];
441 if (aData.myActors[myFrame-1] != 0)
442 aData.myActors[myFrame-1]->VisibilityOff();
444 if (aData.myActors[aData.myNbFrames-1] != 0)
445 aData.myActors[aData.myNbFrames-1]->VisibilityOff();
447 if (aData.myActors[myFrame] != 0) {
448 aData.myActors[myFrame]->VisibilityOn();
453 QPixmap px = QPixmap::grabWindow(myView->getViewWidget()->winId());
454 QString aFile(myDumpPath);
455 QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
457 while ((aPos = aName.find(".")) > -1 )
458 aName.replace(aPos, 1, "_");
461 px.save(aFile, "JPEG");
464 if (myProportional) {
470 if (myFieldsLst[0].myNbFrames > 2)
471 k = (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal;
476 k = (myFrame < (myFieldsLst[0].myNbFrames-1))?
477 (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal : 1;
483 msleep((int)(1000.*k/mySpeed));
490 if (!myIsActive) break;
493 if (myFrame == myFieldsLst[0].myNbFrames) {
507 //************************************************************************
508 VISU::Result_i* VISU_TimeAnimation::createPresent(SALOMEDS::SObject_var theField) {
509 SALOMEDS::SObject_var aSObj = theField->GetFather();
510 aSObj = aSObj->GetFather();
511 aSObj = aSObj->GetFather();
512 CORBA::Object_var anObject = VISU::SObjectToObject(aSObj);
513 if(CORBA::is_nil(anObject)) return NULL;
514 return dynamic_cast<VISU::Result_i*>(VISU::GetServant(anObject));
518 //************************************************************************
519 VISU::Storable::TRestoringMap VISU_TimeAnimation::getMapOfValue(SALOMEDS::SObject_var theSObject) {
520 VISU::Storable::TRestoringMap aMap;
521 if(!theSObject->_is_nil()){
522 SALOMEDS::GenericAttribute_var anAttr;
523 if (theSObject->FindAttribute(anAttr, "AttributeComment")) {
524 SALOMEDS::AttributeComment_var aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
525 CORBA::String_var aString = aComment->Value();
526 QString strIn(aString.in());
527 VISU::Storable::StrToMap(strIn,aMap);
533 //************************************************************************
534 double VISU_TimeAnimation::getTimeValue(SALOMEDS::SObject_var theTimeStamp) {
535 SALOMEDS::GenericAttribute_var anAttr;
536 if(theTimeStamp->FindAttribute(anAttr, "AttributeName")) {
537 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
538 QString aNameString(aName->Value());
539 return aNameString.toDouble();
543 //************************************************************************
544 void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed) {
545 mySpeed = (theSpeed<1)? 1 : theSpeed;