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_ScalarBarActor.hxx"
12 //QWaitCondition myCondition;
13 static int MYDELAY = 1;
15 //************************************************************************
16 VISU_TimeAnimation::VISU_TimeAnimation(SALOMEDS::Study_var theStudy, VISU::View3D_ptr theView3D) {
21 myProportional = false;
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);
39 //************************************************************************
40 VISU_TimeAnimation::~VISU_TimeAnimation() {
41 for (int i = 0; i < getNbFields(); i++) {
42 clearData(myFieldsLst[i]);
47 //************************************************************************
48 void VISU_TimeAnimation::addField(SALOMEDS::SObject_ptr theField) {
50 aNewData.myField = SALOMEDS::SObject::_duplicate(theField);
51 aNewData.myNbFrames = 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);
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());
73 //************************************************************************
74 void VISU_TimeAnimation::clearData(FieldData& theData) {
75 if (theData.myTiming) {
76 free(theData.myTiming);
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();
87 free(theData.myActors);
91 for (int i = 0; i < theData.myNbFrames; i++)
92 theData.myPrs[i]->_remove_ref();
96 theData.myNbFrames = 0;
101 //************************************************************************
102 void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
103 FieldData& aData = myFieldsLst[theFieldNum];
105 // Delete previous presentations
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();
113 aData.myPrs = (VISU::ScalarMap_i**) malloc(aData.myNbTimes * sizeof(VISU::ScalarMap_i*));
114 aData.myTiming = (double*) malloc(aData.myNbTimes * sizeof(double));
116 SALOMEDS::ChildIterator_var anIter = myStudy->NewChildIterator(aData.myField);
117 SALOMEDS::SObject_var aTimeStamp;
118 anIter->Next(); // First is reference on support
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");
126 aTimeStamp = anIter->Value();
127 if (aTimeStamp->_is_nil()) continue;
129 aData.myTiming[i] = getTimeValue(aTimeStamp);
130 if (isRangeDefined()) {
131 if (aData.myTiming[i] < myMinVal) continue;
132 if (aData.myTiming[i] > myMaxVal) break;
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();
141 switch (aData.myPrsType) {
142 case VISU::TSCALARMAP: // ScalarMap
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;
153 case VISU::TISOSURFACE: // Iso Surfaces
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;
164 case VISU::TCUTPLANES: // Cut Planes
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;
175 case VISU::TDEFORMEDSHAPE: // Deformed Shape
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;
186 case VISU::TVECTORS: // Vectors
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;
197 case VISU::TSTREAMLINES: // Stream Lines
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;
208 if (aData.myPrs[i]->GetMin() < aMin) aMin = aData.myPrs[i]->GetMin();
209 if (aData.myPrs[i]->GetMax() > aMax) aMax = aData.myPrs[i]->GetMax();
212 aData.myNbFrames = i;
213 for (i = 0; i < aData.myNbFrames; i++)
214 aData.myPrs[i]->SetRange(aMin, aMax);
218 //************************************************************************
219 CORBA::Boolean VISU_TimeAnimation::generateFrames() {
221 MESSAGE("Viewer is nod defined for animation");
224 myLastError = QString("Frame(s) for ");
225 bool aNoError = true;
226 VISU::Mutex mt(myMutex,qApp,MYDELAY);
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) {
237 myLastError += QString("%1 ").arg(aData.myTiming[j]);
239 myView->AddActor(aActor);
241 aActor->VisibilityOn();
243 aActor->VisibilityOff();
245 aData.myActors[j] = aActor;
249 myLastError += QString(" timestamp(s) cannot be created.");
250 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
255 //************************************************************************
256 void VISU_TimeAnimation::clearView() {
258 MESSAGE("Viewer is nod defined for animation");
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();
272 free(aData.myActors);
279 //************************************************************************
280 void VISU_TimeAnimation::stopAnimation() {
284 //************************************************************************
285 void VISU_TimeAnimation::startAnimation() {
292 //************************************************************************
293 void VISU_TimeAnimation::nextFrame() {
295 if (myFrame < (myFieldsLst[0].myNbFrames-1)) {
297 for (i = 0; i < getNbFields(); i++)
298 if (myFieldsLst[i].myActors[myFrame] != 0)
299 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
301 for (i = 0; i < getNbFields(); i++)
302 if (myFieldsLst[i].myActors[myFrame] != 0)
303 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
305 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
310 //************************************************************************
311 void VISU_TimeAnimation::prevFrame() {
315 for (i = 0; i < getNbFields(); i++)
316 if (myFieldsLst[i].myActors[myFrame] != 0)
317 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
319 for (i = 0; i < getNbFields(); i++)
320 if (myFieldsLst[i].myActors[myFrame] != 0)
321 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
323 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
328 //************************************************************************
329 void VISU_TimeAnimation::firstFrame() {
332 for (i = 0; i < getNbFields(); i++)
333 if (myFieldsLst[i].myActors[myFrame] != 0)
334 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
336 for (i = 0; i < getNbFields(); i++)
337 if (myFieldsLst[i].myActors[myFrame] != 0)
338 myFieldsLst[i].myActors[myFrame]->VisibilityOn();
340 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
344 //************************************************************************
345 void VISU_TimeAnimation::lastFrame() {
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();
356 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
361 //************************************************************************
362 // For Batchmode using
363 void VISU_TimeAnimation::gotoFrame(CORBA::Long theFrame) {
364 if ((theFrame < 0) || (theFrame > (getNbFrames()-1)))
370 for (i = 0; i < getNbFields(); i++)
371 if (myFieldsLst[i].myActors[myFrame] != 0)
372 myFieldsLst[i].myActors[myFrame]->VisibilityOff();
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]);
380 qApp->processEvents(3);
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();
395 //************************************************************************
396 CORBA::Long VISU_TimeAnimation::getNbFrames() {
397 return (getNbFields() > 0)? myFieldsLst[0].myNbFrames : 0;
401 //************************************************************************
402 void VISU_TimeAnimation::run() {
404 MESSAGE("Viewer is nod defined for animation");
410 bool isDumping = !myDumpPath.isEmpty();
411 aOneVal = (myFieldsLst[0].myNbFrames > 2) ?
412 myFieldsLst[0].myTiming[1] - myFieldsLst[0].myTiming[0] : 1;
416 emit frameChanged(myFrame, myFieldsLst[0].myTiming[myFrame]);
417 for (int i = 0; i < getNbFields(); i++) {
418 FieldData& aData = myFieldsLst[i];
420 if (aData.myActors[myFrame-1] != 0)
421 aData.myActors[myFrame-1]->VisibilityOff();
423 if (aData.myActors[aData.myNbFrames-1] != 0)
424 aData.myActors[aData.myNbFrames-1]->VisibilityOff();
426 if (aData.myActors[myFrame] != 0) {
427 aData.myActors[myFrame]->VisibilityOn();
432 QPixmap px = QPixmap::grabWindow(myView->getViewWidget()->winId());
433 QString aFile(myDumpPath);
434 QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]);
436 while ((aPos = aName.find(".")) > -1 )
437 aName.replace(aPos, 1, "_");
440 px.save(aFile, "JPEG");
443 if (myProportional) {
449 if (myFieldsLst[0].myNbFrames > 2)
450 k = (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal;
455 k = (myFrame < (myFieldsLst[0].myNbFrames-1))?
456 (myFieldsLst[0].myTiming[myFrame+1] - myFieldsLst[0].myTiming[myFrame])/aOneVal : 1;
462 msleep((int)(1000.*k/mySpeed));
469 if (!myIsActive) break;
472 if (myFrame == myFieldsLst[0].myNbFrames) {
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));
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);
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();
522 //************************************************************************
523 void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed) {
524 mySpeed = (theSpeed<1)? 1 : theSpeed;