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