Salome HOME
adfef8b8d38b15890f874c972feae412c69a1630
[modules/visu.git] / src / VISU_I / VISU_ColoredPrs3dCache_i.cc
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  VISU OBJECT : interactive object for VISU entities implementation
23 //  File   : VISU_ColoredPrs3dCache_i.cc
24 //  Author : Oleg UVAROV
25 //  Module : VISU
26 //
27 #ifdef WNT
28 #define NOGDI
29 #endif
30
31 #include "VISU_ColoredPrs3dCache_i.hh"
32
33 #include "VISU_ColoredPrs3dHolder_i.hh"
34 #include "VISU_ColoredPrs3dFactory.hh"
35
36 #include "VISU_ViewManager_i.hh"
37 #include "VISU_View_i.hh"
38 #include "VISU_Actor.h"
39
40 #include "VISU_PipeLine.hxx"
41
42 #include "SALOME_Event.h"
43
44 #include "VTKViewer_Algorithm.h"
45 #include "SVTK_Functor.h"
46 #include "SVTK_ViewWindow.h"
47
48 #include "SUIT_ResourceMgr.h"
49
50 #include <vtkRenderWindow.h>
51
52 #include <QtGlobal>
53
54 #include "utilities.h"
55
56 #ifdef _DEBUG_
57 static int MYDEBUG = 0;
58 #else
59 static int MYDEBUG = 0;
60 #endif
61
62 using namespace std;
63
64 namespace
65 {
66   //----------------------------------------------------------------------------
67   inline
68   bool
69   IsSameField(const VISU::ColoredPrs3dHolder::BasicInput& theReferenceInput,
70               const VISU::ColoredPrs3dHolder::BasicInput& thePrs3dInput)
71   {
72     return thePrs3dInput.myResult->_is_equivalent(theReferenceInput.myResult) &&
73       thePrs3dInput.myEntity == theReferenceInput.myEntity &&
74       !strcmp(thePrs3dInput.myFieldName.in(), theReferenceInput.myFieldName.in());
75   }
76
77
78   //----------------------------------------------------------------------------
79   inline
80   bool
81   IsSameTimeStamp(const VISU::ColoredPrs3dHolder::BasicInput& theReferenceInput,
82                   const VISU::ColoredPrs3dHolder::BasicInput& thePrs3dInput)
83   {
84     return IsSameField(theReferenceInput, thePrs3dInput) &&
85       thePrs3dInput.myTimeStampNumber == theReferenceInput.myTimeStampNumber;
86   }
87   
88   
89   //----------------------------------------------------------------------------
90   VISU::ColoredPrs3d_i*
91   FindSameFieldPrs(const VISU::TColoredPrs3dHolderMap& theHolderMap,
92                    const VISU::ColoredPrs3dHolder::BasicInput& theInput,
93                    VISU::VISUType theType)
94   {
95     VISU::TColoredPrs3dHolderMap::const_iterator aHolderIter = theHolderMap.begin();
96     VISU::TColoredPrs3dHolderMap::const_iterator aHolderIterEnd = theHolderMap.end();
97     for(; aHolderIter != aHolderIterEnd; aHolderIter++){
98       const VISU::TLastVisitedPrsList& aPrsList = aHolderIter->second;
99       VISU::TLastVisitedPrsList::const_iterator aPrsIter = aPrsList.begin();
100       VISU::TLastVisitedPrsList::const_iterator aPrsIterEnd = aPrsList.end();
101       for(; aPrsIter != aPrsIterEnd; aPrsIter++){
102         VISU::TPrs3dPtr aPrs3d = *aPrsIter;
103         if(aPrs3d->GetType() != theType)
104           break;
105         VISU::ColoredPrs3dHolder::BasicInput_var anInput = aPrs3d->GetBasicInput();
106         if(IsSameField(theInput, anInput))
107           return aPrs3d;
108       }
109     }
110     return NULL;
111   }
112   
113   
114   //----------------------------------------------------------------------------
115   CORBA::Float
116   EstimateMemorySize(const VISU::TColoredPrs3dHolderMap& theHolderMap,
117                      const VISU::ColoredPrs3dHolder::BasicInput& theInput,
118                      VISU::VISUType theType,
119                      const size_t theRawEstimatedMemorySize)
120   {
121     VISU::ColoredPrs3d_i* aPrs3d = FindSameFieldPrs(theHolderMap, theInput, theType);
122     if(aPrs3d)
123       return aPrs3d->GetMemorySize();
124     return CORBA::Float(theRawEstimatedMemorySize/(1024.0*1024.0)); // convert to Mb
125   }
126
127
128   //----------------------------------------------------------------------------
129   bool
130   SelectPrs3dToBeDeleted(CORBA::Float theRequiredMemory,
131                          const std::string& theActiveHolderEntry,
132                          const VISU::TColoredPrs3dHolderMap& theHolderMap,
133                          VISU::TColoredPrs3dHolderMap& theColoredPrs3dHolderMap)
134   {
135     if( theRequiredMemory < 1.0 / VTK_LARGE_FLOAT )
136       return false;
137     
138     VISU::TColoredPrs3dHolderMap::const_iterator aHolderIter = theHolderMap.begin();
139     VISU::TColoredPrs3dHolderMap::const_iterator aHolderIterEnd = theHolderMap.end();
140     
141     // To calculate the maximum length of the cache history among all holders
142     int anIteration = 0;
143     for( ; aHolderIter != aHolderIterEnd; aHolderIter++ ){
144       if( aHolderIter->first == theActiveHolderEntry )
145         continue;
146       const VISU::TLastVisitedPrsList& aPrsList = aHolderIter->second;
147       anIteration = qMax( (int)aPrsList.size() - 1, anIteration );
148     }
149
150     // To estimate what amount of memory can be obtained
151     // by cleaning of non-active holder's presentation
152     CORBA::Float aGatheredMemory = 0.0;
153     for(; anIteration > 0; anIteration--){ // To take into account only non-devices
154       aHolderIter = theHolderMap.begin();
155       for(; aHolderIter != aHolderIterEnd; aHolderIter++ ){
156         const std::string& aHolderEntry = aHolderIter->first;
157         if( aHolderEntry == theActiveHolderEntry )
158           continue;
159         const VISU::TLastVisitedPrsList& aPrsList = aHolderIter->second;
160         if( anIteration < aPrsList.size() ){
161           VISU::TPrs3dPtr aPrs3d = aPrsList[anIteration];
162           aGatheredMemory += aPrs3d->GetMemorySize();
163           theColoredPrs3dHolderMap[aHolderEntry].push_back(aPrs3d);
164           if( aGatheredMemory > theRequiredMemory )
165             return true;
166         }
167       }
168     }
169     
170     // To estimate what amount of memory can be obtained
171     // by cleaning of active holder's presentation
172     if( theActiveHolderEntry != "" ){
173       aHolderIter = theHolderMap.find( theActiveHolderEntry );
174       if(aHolderIter == theHolderMap.end())
175         return false;
176
177       const VISU::TLastVisitedPrsList& aPrsList = aHolderIter->second;
178
179       // To prefere "move" action instead of destroy / create presentation
180       if(aPrsList.back()->GetMemorySize() >= theRequiredMemory)
181         return false;
182
183       VISU::TLastVisitedPrsList::const_reverse_iterator aPrsIter = aPrsList.rbegin();
184       // Do not porcess first item to avoid of the device destruction
185       VISU::TLastVisitedPrsList::const_reverse_iterator aPrsIterEnd = aPrsList.rend()++;
186       for(; aPrsIter != aPrsIterEnd; aPrsIter++){
187         VISU::TPrs3dPtr aPrs3d = *aPrsIter;
188         aGatheredMemory += aPrs3d->GetMemorySize();
189         theColoredPrs3dHolderMap[theActiveHolderEntry].push_back(aPrs3d);
190         if( aGatheredMemory > theRequiredMemory )
191           return true;
192       }
193     }
194     
195     return false;
196   }
197
198
199   //----------------------------------------------------------------------------
200   void
201   ErasePrs3d(VISU::TLastVisitedPrsList& thePrsList,
202              const VISU::TPrs3dPtr& thePrs3d)
203   {
204     VISU::TLastVisitedPrsList::iterator anIter = thePrsList.begin();
205     VISU::TLastVisitedPrsList::iterator aEndIter = thePrsList.end();
206     for(; anIter != aEndIter; anIter++){
207       VISU::TPrs3dPtr aPrs3d = *anIter;
208       if(aPrs3d == thePrs3d)
209         thePrsList.erase(anIter);
210     }
211   }
212 }
213
214
215 //----------------------------------------------------------------------------
216 VISU::ColoredPrs3dCache_i
217 ::ColoredPrs3dCache_i(SALOMEDS::Study_ptr theStudy,
218                       bool thePublishInStudy):
219   RemovableObject_i()
220 {
221   if(MYDEBUG) MESSAGE("ColoredPrs3dCache_i::ColoredPrs3dCache_i - this = "<<this);
222   SetStudyDocument(theStudy);
223
224   SetName(GetFolderName(), false);
225
226   if( thePublishInStudy )
227   {
228     CORBA::String_var anIOR = GetID();
229     SALOMEDS::SComponent_var aSComponent = VISU::FindOrCreateVisuComponent(theStudy);
230     CORBA::String_var aFatherEntry = aSComponent->GetID();
231     CreateAttributes(GetStudyDocument(), aFatherEntry.in(), "", anIOR.in(), GetName(), "", "", true);
232   }
233
234   SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
235
236   int aMemoryMode = aResourceMgr->integerValue( "VISU", "cache_memory_mode", 0 );
237   SetMemoryMode( aMemoryMode == 0 ? VISU::ColoredPrs3dCache::MINIMAL : VISU::ColoredPrs3dCache::LIMITED );
238
239   float aLimitedMemory = aResourceMgr->doubleValue( "VISU", "cache_memory_limit", 1024.0 );
240   SetLimitedMemory( aLimitedMemory );
241 }
242
243
244 //----------------------------------------------------------------------------
245 VISU::ColoredPrs3dCache_i
246 ::~ColoredPrs3dCache_i() 
247 {
248   if(MYDEBUG) MESSAGE("ColoredPrs3dCache_i::~ColoredPrs3dCache_i - this = "<<this);
249 }
250
251
252 //----------------------------------------------------------------------------
253 const string VISU::ColoredPrs3dCache_i::myComment = "COLOREDPRS3DCACHE";
254
255 const char* 
256 VISU::ColoredPrs3dCache_i
257 ::GetComment() const 
258
259   return myComment.c_str();
260 }
261
262
263 //----------------------------------------------------------------------------
264 CORBA::Float
265 VISU::ColoredPrs3dCache_i
266 ::GetMemorySize()
267
268   CORBA::Float aMemoryUsed = 0.0;
269   TColoredPrs3dHolderMap::const_iterator aHolderIter = myHolderMap.begin();
270   TColoredPrs3dHolderMap::const_iterator aHolderIterEnd = myHolderMap.end();
271   for(; aHolderIter != aHolderIterEnd; aHolderIter++){
272     const TLastVisitedPrsList& aPrsList = aHolderIter->second;
273     TLastVisitedPrsList::const_iterator aPrsIter = aPrsList.begin();
274     TLastVisitedPrsList::const_iterator aPrsIterEnd = aPrsList.end();
275     for(; aPrsIter != aPrsIterEnd; aPrsIter++){
276       if(TPrs3dPtr aPrs3d = *aPrsIter)
277         aMemoryUsed += aPrs3d->GetMemorySize();
278     }
279   }
280   return aMemoryUsed; 
281 }
282
283
284 //----------------------------------------------------------------------------
285 CORBA::Float
286 VISU::ColoredPrs3dCache_i
287 ::GetDeviceMemorySize()
288
289   CORBA::Float aMemoryUsed = 0.0;
290   TColoredPrs3dHolderMap::const_iterator aHolderIter = myHolderMap.begin();
291   TColoredPrs3dHolderMap::const_iterator aHolderIterEnd = myHolderMap.end();
292   for(; aHolderIter != aHolderIterEnd; aHolderIter++){
293     const TLastVisitedPrsList& aPrsList = aHolderIter->second;
294     if(TPrs3dPtr aPrs3d = aPrsList.front())
295       aMemoryUsed += aPrs3d->GetMemorySize();
296   }
297   return aMemoryUsed; 
298 }
299
300
301 //----------------------------------------------------------------------------
302 int
303 VISU::ColoredPrs3dCache_i
304 ::IsPossible(VISU::VISUType theType,
305              const VISU::ColoredPrs3dHolder::BasicInput& theInput,
306              CORBA::Float& theRequiredMemory,
307              const std::string theHolderEntry)
308 {
309   size_t aRawEstimatedMemorySize = VISU::CheckIsPossible(theType, theInput, true);
310   if(aRawEstimatedMemorySize > 0){
311     if(GetMemoryMode() == VISU::ColoredPrs3dCache::LIMITED){
312       CORBA::Float aMemoryUsed = GetMemorySize();
313       CORBA::Float aMemoryLimit = GetLimitedMemory();
314       CORBA::Float aMemoryNeeded = EstimateMemorySize(myHolderMap,
315                                                       theInput,
316                                                       theType,
317                                                       aRawEstimatedMemorySize);
318
319       if( aMemoryUsed + aMemoryNeeded < aMemoryLimit )
320         return true;
321       
322       theRequiredMemory = aMemoryNeeded - ( aMemoryLimit - aMemoryUsed );
323       TColoredPrs3dHolderMap aColoredPrs3dHolderMap;
324       return SelectPrs3dToBeDeleted(theRequiredMemory, 
325                                     theHolderEntry, 
326                                     myHolderMap,
327                                     aColoredPrs3dHolderMap);
328     }
329   }
330   return aRawEstimatedMemorySize > 0;
331 }
332
333
334 //----------------------------------------------------------------------------
335 VISU::ColoredPrs3dCache::EnlargeType
336 VISU::ColoredPrs3dCache_i
337 ::GetRequiredMemory(VISU::VISUType theType,
338                     const VISU::ColoredPrs3dHolder::BasicInput& theInput,
339                     CORBA::Float& theRequiredMemory)
340 {
341   VISU::ColoredPrs3dCache::EnlargeType anEnlargeType = VISU::ColoredPrs3dCache::NO_ENLARGE;
342
343   size_t aRawEstimatedMemorySize = VISU::CheckIsPossible(theType, theInput, true);
344   if(aRawEstimatedMemorySize > 0){
345     if(GetMemoryMode() == VISU::ColoredPrs3dCache::LIMITED){
346       CORBA::Float aMemoryUsed = GetDeviceMemorySize();
347       CORBA::Float aMemoryLimit = GetLimitedMemory();
348       CORBA::Float aMemoryNeeded = EstimateMemorySize(myHolderMap,
349                                                       theInput,
350                                                       theType,
351                                                       aRawEstimatedMemorySize);
352       if( aMemoryUsed + aMemoryNeeded < aMemoryLimit )
353         return anEnlargeType;
354
355       theRequiredMemory = int( aMemoryUsed + aMemoryNeeded ) + 1;
356
357       size_t aMb = 1024 * 1024;
358       double aFreeMemory = double(VISU_PipeLine::GetAvailableMemory(8192*aMb)) / double(aMb);
359       anEnlargeType = aMemoryNeeded < aFreeMemory ?
360         VISU::ColoredPrs3dCache::ENLARGE : VISU::ColoredPrs3dCache::IMPOSSIBLE;
361     }
362   }
363   return anEnlargeType;
364 }
365
366
367 //----------------------------------------------------------------------------
368 VISU::ColoredPrs3dCache_i*
369 VISU::ColoredPrs3dCache_i
370 ::GetInstance_i(SALOMEDS::Study_ptr theStudy)
371 {
372   std::string aFolderName = VISU::ColoredPrs3dCache_i::GetFolderName();
373   SALOMEDS::SObject_var aSObject = theStudy->FindObject(aFolderName.c_str());
374   if (CORBA::is_nil(aSObject)) {
375     aSObject = theStudy->FindObject("3D Cache System");
376     if (!CORBA::is_nil(aSObject)) {
377       SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
378       SALOMEDS::GenericAttribute_var anAttr = aBuilder->FindOrCreateAttribute( aSObject, "AttributeName" );
379       SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr );
380       aNameAttr->SetValue( GetFolderName().c_str() );
381     }
382   }
383   if(!CORBA::is_nil(aSObject)){
384     CORBA::Object_var anObject = aSObject->GetObject();
385     VISU::ColoredPrs3dCache_var aCache = VISU::ColoredPrs3dCache::_narrow(anObject);
386     if(!CORBA::is_nil(aCache))
387       return dynamic_cast<VISU::ColoredPrs3dCache_i*>(GetServant(aCache).in());
388   }
389   
390   return new VISU::ColoredPrs3dCache_i(theStudy);
391 }
392
393
394 VISU::ColoredPrs3dCache_ptr
395 VISU::ColoredPrs3dCache_i
396 ::GetInstance(SALOMEDS::Study_ptr theStudy)
397 {
398   VISU::ColoredPrs3dCache_i* aServant = GetInstance_i(theStudy);
399   VISU::ColoredPrs3dCache_var anObject = aServant->_this();
400   return anObject._retn();
401 }
402
403
404 //----------------------------------------------------------------------------
405 VISU::ColoredPrs3dHolder_ptr
406 VISU::ColoredPrs3dCache_i
407 ::CreateHolder(VISU::VISUType theType,
408                const VISU::ColoredPrs3dHolder::BasicInput& theInput)
409 {
410   if(MYDEBUG) MESSAGE ("CreateHolder "<<theType);
411   CORBA::Float aRequiredMemory = 0.0;
412   if(IsPossible(theType, theInput, aRequiredMemory, "")){
413     if(VISU::ColoredPrs3d_i* aColoredPrs3d = CreateColoredPrs3d(theType, theInput)){
414       VISU::ColoredPrs3dHolder_i* aHolder = new VISU::ColoredPrs3dHolder_i(*this);
415       std::string aComment = std::string("myComment=") + aColoredPrs3d->GetComment();
416       std::string aName = (const char*)aColoredPrs3d->GenerateName().toLatin1();
417       aHolder->PublishInStudy(aName, aColoredPrs3d->GetIconName(), aComment);
418       RegisterInHolder(aColoredPrs3d, aHolder->GetEntry());
419       if( aRequiredMemory > 1.0 / VTK_LARGE_FLOAT )
420         ClearMemory( aRequiredMemory, aHolder->GetEntry() );
421       return aHolder->_this();
422     }
423   }
424   return VISU::ColoredPrs3dHolder::_nil();
425 }
426
427
428 //----------------------------------------------------------------------------
429 void
430 VISU::ColoredPrs3dCache_i
431 ::SetMemoryMode(VISU::ColoredPrs3dCache::MemoryMode theMode)
432 {
433   VISU::ColoredPrs3dCache::MemoryMode aCurrentMode = GetMemoryMode();
434
435   if( aCurrentMode == VISU::ColoredPrs3dCache::LIMITED &&
436       theMode == VISU::ColoredPrs3dCache::MINIMAL )
437   {
438     ClearCache();
439   }
440
441   myMemoryMode = theMode;
442   GetStudyDocument()->Modified();
443 }
444
445 VISU::ColoredPrs3dCache::MemoryMode
446 VISU::ColoredPrs3dCache_i
447 ::GetMemoryMode()
448
449   return myMemoryMode; 
450 }
451
452
453 //----------------------------------------------------------------------------
454 void
455 VISU::ColoredPrs3dCache_i
456 ::SetLimitedMemory(CORBA::Float theMemorySize)
457 {
458   if( fabs( myLimitedMemory - theMemorySize ) < 1 / VTK_LARGE_FLOAT )
459     return;
460
461   size_t aMb = 1024 * 1024;
462   double aFreeMemory = double(VISU_PipeLine::GetAvailableMemory(8192*aMb)) / double(aMb);
463   CORBA::Float aMemoryUsed = GetDeviceMemorySize();
464   CORBA::Float aMemoryNeeded = theMemorySize - aMemoryUsed;
465   if( aMemoryNeeded > aFreeMemory )
466     return;
467
468   ClearCache(theMemorySize);
469   myLimitedMemory = theMemorySize;
470   GetStudyDocument()->Modified();
471 }
472
473 CORBA::Float
474 VISU::ColoredPrs3dCache_i
475 ::GetLimitedMemory()
476
477   return myLimitedMemory; 
478 }
479
480
481 void
482 VISU::ColoredPrs3dCache_i
483 ::RemoveFromStudy() 
484 {
485   CORBA::String_var anIOR = GetID();
486   SALOMEDS::SObject_var aSObject = GetStudyDocument()->FindObjectIOR(anIOR.in());
487   VISU::RemoveFromStudy(aSObject, false, true);
488   Destroy();
489 }
490
491 std::string
492 VISU::ColoredPrs3dCache_i
493 ::GetFolderName() 
494
495   //return "3D Cache System"; 
496   return "Presentations"; 
497 }
498
499 //----------------------------------------------------------------------------
500 VISU::ColoredPrs3d_i*
501 VISU::ColoredPrs3dCache_i
502 ::CreateColoredPrs3d(VISU::VISUType theType,
503                      VISU::ColoredPrs3dHolder::BasicInput theInput)
504 {
505   VISU::ColoredPrs3d_i* aPrs3d = VISU::CreatePrs3d_i(theType, GetStudyDocument(), ColoredPrs3d_i::ERegisterInCache);
506   aPrs3d->SetResultObject( theInput.myResult );  
507   aPrs3d->SetMeshName( theInput.myMeshName );  
508   aPrs3d->SetEntity( theInput.myEntity );  
509   aPrs3d->SetFieldName( theInput.myFieldName );  
510   aPrs3d->SetTimeStampNumber( theInput.myTimeStampNumber );
511   if(aPrs3d->Apply( false ))
512     return aPrs3d;
513   return NULL;
514 }
515
516
517 //----------------------------------------------------------------------------
518 VISU::ColoredPrs3d_i*
519 VISU::ColoredPrs3dCache_i
520 ::RegisterInHolder(VISU::ColoredPrs3d_i* thePrs3d,
521                    const std::string& theHolderEntry)
522 {
523   if(MYDEBUG) MESSAGE("RegisterInHolder "<<theHolderEntry.c_str()<<" "<<thePrs3d);
524   if(thePrs3d){
525     TPrs3dPtr aPrs3d(thePrs3d);
526     myHolderMap[theHolderEntry].push_front(aPrs3d);  
527     thePrs3d->SetHolderEntry( theHolderEntry );
528     thePrs3d->Destroy();
529   }
530   return thePrs3d;
531 }
532
533
534 //----------------------------------------------------------------------------
535 VISU::ColoredPrs3d_i*
536 VISU::ColoredPrs3dCache_i
537 ::CreatePrs(VISU::VISUType theType,
538             VISU::ColoredPrs3dHolder::BasicInput theInput,
539             VISU::ColoredPrs3dHolder_i* theHolder)
540 {
541   return RegisterInHolder(CreateColoredPrs3d(theType, theInput), 
542                           theHolder->GetEntry());
543 }
544
545
546 //----------------------------------------------------------------------------
547 VISU::TLastVisitedPrsList&
548 VISU::ColoredPrs3dCache_i
549 ::GetLastVisitedPrsList(VISU::ColoredPrs3dHolder_i* theHolder)
550 {
551   return myHolderMap[theHolder->GetEntry()];
552 }
553
554
555 //----------------------------------------------------------------------------
556 VISU::TPrs3dPtr
557 VISU::ColoredPrs3dCache_i
558 ::GetLastVisitedPrs(VISU::ColoredPrs3dHolder_i* theHolder)
559 {
560   const TLastVisitedPrsList& aList = GetLastVisitedPrsList(theHolder);
561   if(MYDEBUG) MESSAGE("GetLastVisitedPrs " << theHolder->GetEntry().c_str() << " " << aList.size() );
562   if( !aList.empty() )
563     return aList.front();
564   return VISU::TPrs3dPtr();
565 }
566
567
568 //----------------------------------------------------------------------------
569 VISU::TPrs3dPtr
570 VISU::ColoredPrs3dCache_i
571 ::FindPrsByInput(TLastVisitedPrsList& theLastVisitedPrsList,
572                  const VISU::ColoredPrs3dHolder::BasicInput& theInput)
573 {
574   TLastVisitedPrsList::iterator anIter = theLastVisitedPrsList.begin();
575   TLastVisitedPrsList::iterator aEndIter = theLastVisitedPrsList.end();
576   for(; anIter != aEndIter; anIter++){
577     TPrs3dPtr aPrs3d = *anIter;
578     VISU::ColoredPrs3dHolder::BasicInput_var anInput = aPrs3d->GetBasicInput();
579     if(IsSameTimeStamp(theInput, anInput)){
580       theLastVisitedPrsList.erase(anIter);
581       return aPrs3d;
582     }
583   }
584   return VISU::TPrs3dPtr();
585 }
586
587 struct TFindActorEvent: public SALOME_Event
588 {
589   VISU::TPrs3dPtr myPrs3d;
590   SVTK_ViewWindow* myViewWindow;
591
592   typedef VISU_Actor* TResult;
593   TResult myResult;
594
595   TFindActorEvent(VISU::TPrs3dPtr thePrs3d, SVTK_ViewWindow* theViewWindow):
596     myPrs3d(thePrs3d),
597     myViewWindow(theViewWindow),
598     myResult(NULL)
599   {}
600
601   virtual
602   void
603   Execute()
604   {
605     myResult = VISU::FindActor(myViewWindow, myPrs3d);
606   }
607 };
608
609 struct TAddActorEvent: public SALOME_Event
610 {
611   VISU_Actor* myActor;
612   SVTK_ViewWindow* myViewWindow;
613 public:
614   TAddActorEvent(VISU_Actor* theActor, SVTK_ViewWindow* theViewWindow):
615     myActor(theActor),
616     myViewWindow(theViewWindow)
617   {}
618   virtual void Execute(){
619     myViewWindow->AddActor(myActor);
620   }
621 };
622
623 struct TRenderEvent: public SALOME_Event
624 {
625   SVTK_ViewWindow* myViewWindow;
626 public:
627   TRenderEvent(SVTK_ViewWindow* theViewWindow):
628     myViewWindow(theViewWindow)
629   {}
630   virtual void Execute(){
631     myViewWindow->getRenderWindow()->Render();
632   }
633 };
634
635 //----------------------------------------------------------------------------
636 bool
637 VISU::ColoredPrs3dCache_i
638 ::UpdateLastVisitedPrs(VISU::ColoredPrs3dHolder_i* theHolder,
639                        VISU::ColoredPrs3d_i* thePrs,
640                        const VISU::ColoredPrs3dHolder::BasicInput& theInput,
641                        VISU::View3D_ptr theView3D)
642 {
643   if(MYDEBUG) MESSAGE( "VISU::ColoredPrs3dCache_i::UpdateLastVisitedPrs" );
644   TPrs3dPtr aPrs3d;
645   try{
646     TPrs3dPtr aLastVisitedPrs3d = GetLastVisitedPrs(theHolder);
647     TLastVisitedPrsList& aLastVisitedPrsList = GetLastVisitedPrsList(theHolder);
648     bool anIsCheckPossible = GetMemoryMode() == VISU::ColoredPrs3dCache::LIMITED;
649     std::string aHolderEntry = theHolder->GetEntry();
650     VISU::VISUType aPrsType = theHolder->GetPrsType();
651     CORBA::Float aRequiredMemory = 0.0;
652     if(aPrs3d = FindPrsByInput(aLastVisitedPrsList, theInput)){
653       aLastVisitedPrsList.push_front(aPrs3d);
654       if(MYDEBUG) MESSAGE( "FindPrsByInput " << aPrs3d );
655     }else if(anIsCheckPossible && IsPossible(aPrsType, theInput, aRequiredMemory, aHolderEntry)){
656       if( aRequiredMemory > 1.0 / VTK_LARGE_FLOAT )
657         ClearMemory(aRequiredMemory, aHolderEntry);
658       aPrs3d = CreatePrs(aPrsType, theInput, theHolder);
659       if(MYDEBUG) MESSAGE( "Created " << aPrs3d );
660     }else{
661       aPrs3d = aLastVisitedPrsList.back();
662       aPrs3d->SetResultObject(theInput.myResult);
663       aPrs3d->SetMeshName(theInput.myMeshName);
664       aPrs3d->SetEntity(theInput.myEntity);
665       aPrs3d->SetFieldName(theInput.myFieldName);
666       aPrs3d->SetTimeStampNumber(theInput.myTimeStampNumber);
667       aLastVisitedPrsList.pop_back();
668       aLastVisitedPrsList.push_front(aPrs3d);
669       if(MYDEBUG) MESSAGE( "Move only " << aPrs3d );
670     }
671     //if(MYDEBUG) PrintCache();
672     
673     aPrs3d->SameAs(thePrs);
674     
675     // special case for deformed shape
676     VISU::DeformedShapeAndScalarMap_i* dShape =
677       dynamic_cast<VISU::DeformedShapeAndScalarMap_i*>( aPrs3d.get() );
678     if ( dShape && dShape->GetScalarTimeStampNumber() != theInput.myTimeStampNumber )
679     {
680       dShape->SetScalarField( dShape->GetScalarEntity(),
681         dShape->GetScalarFieldName(), theInput.myTimeStampNumber );            
682     }                    
683
684     if(CORBA::is_nil(theView3D))
685       return false;
686
687     PortableServer::ServantBase_var aServant = GetServant(theView3D);
688     if(VISU::View3D_i* aView3d = dynamic_cast<VISU::View3D_i*>(aServant.in())){
689       if(SUIT_ViewWindow* aView = aView3d->GetViewWindow()){
690         if(SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>(aView)){
691           // Find actor that corresponds to the holder
692           VISU_Actor* anActor = ProcessEvent(new TFindActorEvent(aLastVisitedPrs3d,aViewWindow));
693           //VISU_Actor* anActor = VISU::FindActor(aViewWindow, aLastVisitedPrs3d);
694
695           // If the holder was erased from view then do nothing
696           if(anActor && !anActor->GetVisibility())
697             return true;
698
699           if(!anActor)
700           {
701             anActor = aLastVisitedPrs3d->CreateActor();
702             ProcessVoidEvent(new TAddActorEvent(anActor,aViewWindow));
703             //aViewWindow->AddActor(anActor);
704             anActor->SetVisibility(true);
705           }
706
707           if(aPrs3d != aLastVisitedPrs3d)
708           {
709             // To erase non active presentation
710             aLastVisitedPrs3d->SetActiveState(false);
711             if(anActor)
712               anActor->SetVisibility(false);
713
714             // To find the new one that corresponds to fresh presentation
715             VISU_Actor* aNewActor = ProcessEvent(new TFindActorEvent(aPrs3d,aViewWindow));
716             //VISU_Actor* aNewActor = VISU::FindActor(aViewWindow, aPrs3d);
717             if(!aNewActor){
718               aNewActor = aPrs3d->CreateActor();
719               ProcessVoidEvent(new TAddActorEvent(aNewActor,aViewWindow));
720               //aViewWindow->AddActor(aNewActor);
721             }else
722               aNewActor->SetVisibility(true);
723             aNewActor->DeepCopy(anActor);
724
725             aPrs3d->SetActiveState(true);
726           }
727
728           aPrs3d->UpdateActors();
729           ProcessVoidEvent(new TRenderEvent(aViewWindow));
730           //aViewWindow->getRenderWindow()->Render();
731           return true;
732         }
733       }
734     }
735   }catch(std::exception& exc){
736     INFOS("Follow exception was occured :\n"<<exc.what());
737   }catch(...){
738     INFOS("Unknown exception was occured!");
739   }
740
741   return false;
742 }
743
744
745 //----------------------------------------------------------------------------
746 void
747 VISU::ColoredPrs3dCache_i
748 ::ClearCache(float theMemory)
749 {
750   CORBA::Float aCurrentMemory = GetMemorySize();
751   ClearMemory( aCurrentMemory - theMemory, "" );
752 }
753
754
755 //----------------------------------------------------------------------------
756 bool
757 VISU::ColoredPrs3dCache_i
758 ::ClearMemory(CORBA::Float theRequiredMemory, 
759               const std::string& theHolderEntry)
760 {
761   CORBA::Float aInitialMemorySize = GetMemorySize();
762   TColoredPrs3dHolderMap aHolder2PrsToBeDeletedMap;
763   SelectPrs3dToBeDeleted(theRequiredMemory, theHolderEntry, myHolderMap, aHolder2PrsToBeDeletedMap);
764   TColoredPrs3dHolderMap::const_iterator aHolderIter = aHolder2PrsToBeDeletedMap.begin();
765   TColoredPrs3dHolderMap::const_iterator anEndHolderIter = aHolder2PrsToBeDeletedMap.end();
766   for(; aHolderIter != anEndHolderIter; aHolderIter++){
767     const std::string aHolderEntry = aHolderIter->first;
768     TColoredPrs3dHolderMap::iterator anHolderMapIter = myHolderMap.find(aHolderEntry);
769     if(anHolderMapIter != myHolderMap.end()){
770       TLastVisitedPrsList& aLastVisitedPrsList = anHolderMapIter->second;
771       
772       const TLastVisitedPrsList& aPrsToBeDeletedList = aHolderIter->second;
773       TLastVisitedPrsList::const_iterator anIter = aPrsToBeDeletedList.begin();
774       TLastVisitedPrsList::const_iterator aEndIter = aPrsToBeDeletedList.end();
775       for(; anIter != aEndIter; anIter++){
776         TPrs3dPtr aPrs3d = *anIter;
777         ErasePrs3d(aLastVisitedPrsList, aPrs3d);
778       }
779     }
780   }
781   CORBA::Float aCurrentMemory = GetMemorySize();
782   return (aInitialMemorySize - aCurrentMemory >= theRequiredMemory);
783 }
784
785
786 //----------------------------------------------------------------------------
787 void
788 VISU::ColoredPrs3dCache_i
789 ::PrintCache()
790 {
791   if(MYDEBUG)
792   {
793     MESSAGE_BEGIN(std::endl << "--------------CACHE-----------------" );
794     MESSAGE_ADD(std::endl << "Cache memory - " << GetMemorySize() << " Mb" );
795     TColoredPrs3dHolderMap::const_iterator aHolderIter = myHolderMap.begin();
796     TColoredPrs3dHolderMap::const_iterator aHolderIterEnd = myHolderMap.end();
797     for(; aHolderIter != aHolderIterEnd; aHolderIter++){
798       const TLastVisitedPrsList& aPrsList = aHolderIter->second;
799       TLastVisitedPrsList::const_iterator aPrsIter = aPrsList.begin();
800       TLastVisitedPrsList::const_iterator aPrsIterEnd = aPrsList.end();
801
802       MESSAGE_ADD(std::endl << "--------------------------" );
803       MESSAGE_ADD(std::endl <<  "Holder - " << aHolderIter->first.c_str() );
804       MESSAGE_ADD(std::endl <<  "Size   - " << aPrsList.size() );
805       for(; aPrsIter != aPrsIterEnd; aPrsIter++)
806         if(TPrs3dPtr aPrs3d = *aPrsIter)
807         {
808           MESSAGE_ADD(std::endl <<  aPrs3d << " (" << aPrs3d->GetMemorySize() << " Mb)");
809           if(aPrsIter == aPrsList.begin())
810             MESSAGE_ADD( " (device)" );
811         }
812     }
813     MESSAGE_END(std::endl <<  "------------------------------------" );
814   }
815 }
816
817
818 //----------------------------------------------------------------------------
819 void
820 VISU::ColoredPrs3dCache_i
821 ::RemoveHolder(VISU::ColoredPrs3dHolder_i* theHolder)
822 {
823   TColoredPrs3dHolderMap::iterator anIter = myHolderMap.find(theHolder->GetEntry());
824   if(anIter != myHolderMap.end())
825     myHolderMap.erase(anIter);
826 }
827
828 //----------------------------------------------------------------------------
829 void
830 VISU::ColoredPrs3dCache_i
831 ::ToStream(std::ostringstream& theStr) 
832 {
833   Storable::DataToStream( theStr, "myMemoryMode", GetMemoryMode() );
834   Storable::DataToStream( theStr, "myLimitedMemory", GetLimitedMemory() );
835 }
836
837 //---------------------------------------------------------------
838 VISU::Storable*
839 VISU::ColoredPrs3dCache_i
840 ::Restore(SALOMEDS::SObject_ptr theSObject,
841           const Storable::TRestoringMap& theMap)
842 {
843   SetMemoryMode( (VISU::ColoredPrs3dCache::MemoryMode)VISU::Storable::FindValue( theMap, "myMemoryMode" ).toInt() );
844   SetLimitedMemory( VISU::Storable::FindValue( theMap, "myLimitedMemory" ).toInt() );
845   
846   return this;
847 }
848
849 //---------------------------------------------------------------
850 VISU::Storable*
851 VISU::ColoredPrs3dCache_i
852 ::StorableEngine(SALOMEDS::SObject_ptr theSObject,
853                  const Storable::TRestoringMap& theMap,
854                  const std::string& thePrefix,
855                  CORBA::Boolean theIsMultiFile)
856 {
857   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
858   VISU::ColoredPrs3dCache_i* aCache = new VISU::ColoredPrs3dCache_i(aStudy, false);
859   return aCache->Restore(theSObject, theMap);
860 }