Salome HOME
Fix of issue 0020593: EDF 885 VISU: Unchecking Filter by Scalar does not remove white...
[modules/visu.git] / src / VISU_I / VISU_Prs3d_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_Prs3d_i.cc
24 //  Author : Alexey PETROV
25 //  Module : VISU
26 //
27 #include "VISU_Prs3d_i.hh"
28 #include "VISU_Prs3dUtils.hh"
29 #include "VISU_PipeLine.hxx"
30
31 #include "VISU_Result_i.hh"
32 #include "VISU_Actor.h"
33
34 #include "SALOME_Event.h"
35 #include "SUIT_ResourceMgr.h"
36 #include "SUIT_MessageBox.h"
37
38 #include <vtkActorCollection.h>
39 #include <vtkUnstructuredGrid.h>
40 #include <vtkDataSet.h>
41 #include <vtkMapper.h>
42
43 #include <boost/bind.hpp>
44
45 #ifdef _DEBUG_
46 static int MYDEBUG = 1;
47 #else
48 static int MYDEBUG = 0;
49 #endif
50
51
52 //----------------------------------------------------------------------------
53 VISU::Prs3d_i::Prs3d_i() :
54   PrsObject_i(SALOMEDS::Study::_nil()),
55   myActorCollection(vtkActorCollection::New()),
56   myIsActiveSatate(true)
57 {
58   if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
59   myOffset[0] = myOffset[1] = myOffset[2] = 0;
60   myActorCollection->Delete();
61 }
62
63
64 //----------------------------------------------------------------------------
65 void
66 VISU::Prs3d_i
67 ::SameAs(const Prs3d_i* theOrigin)
68 {
69   if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
70     VISU::TSetModified aModified(this);
71
72     GetPipeLine()->SameAs(anOrigin->GetPipeLine());
73     anOrigin->GetOffset(myOffset);
74   }
75 }
76
77
78 //----------------------------------------------------------------------------
79 namespace VISU
80 {
81   struct TInvokeSignalEvent: public SALOME_Event
82   {
83     typedef boost::signal0<void> TSignal;
84     const TSignal& mySignal;
85     
86     TInvokeSignalEvent(const TSignal& theSignal):
87       mySignal(theSignal)
88     {}
89     
90     virtual
91     void
92     Execute()
93     {
94       mySignal();
95     }
96   };
97 }
98
99 //----------------------------------------------------------------------------
100 VISU::Prs3d_i::~Prs3d_i()
101 {
102   if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
103   ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
104 }
105
106
107 //----------------------------------------------------------------------------
108 bool 
109 VISU::Prs3d_i
110 ::SetInput(bool theReInit)
111 {
112   if(GetCResult()){
113     if(myMeshName != ""){
114       myPreviousResult = myResult;
115       myPreviousMeshName = myMeshName;
116       return true;
117     }
118   }
119   return false;
120 }
121
122
123 //----------------------------------------------------------------------------
124 void 
125 VISU::Prs3d_i
126 ::OnRestoreInput()
127 {
128   SetCResult(myPreviousResult);
129   myMeshName = myPreviousMeshName;
130 }
131
132
133 //----------------------------------------------------------------------------
134 CORBA::Boolean 
135 VISU::Prs3d_i
136 ::Apply(bool theReInit)
137 {
138   try{
139     if(SetInput(theReInit)){
140       if(myActorCollection->GetNumberOfItems())
141         UpdateActors();
142       return true;
143     }
144   }catch(std::exception& exc){
145     INFOS("Follow exception was occured :\n"<<exc.what());
146   }catch(...){
147     INFOS("Unknown exception was occured!");
148   }
149   OnRestoreInput();
150   return false;
151 }
152
153
154 //----------------------------------------------------------------------------
155 void
156 VISU::Prs3d_i
157 ::SetCResult(VISU::Result_i* theResult)
158 {
159   if(GetCResult() == theResult)
160     return;
161
162   if(theResult) {
163     SetStudyDocument(theResult->GetStudyDocument());
164   }
165   
166   VISU::TSetModified aModified(this);
167   
168   myResult = theResult;
169   myParamsTime.Modified();
170 }
171
172 //----------------------------------------------------------------------------
173 void
174 VISU::Prs3d_i
175 ::SetResultEntry(const std::string& theResultEntry)
176 {
177   SetCResult(VISU::GetResult(GetStudyDocument(), theResultEntry));
178 }
179
180 //----------------------------------------------------------------------------
181 std::string
182 VISU::Prs3d_i
183 ::GetResultEntry()
184 {
185   if(VISU::Result_i* aResult = GetCResult())
186     return aResult->GetEntry();
187   return "";
188 }
189
190 //----------------------------------------------------------------------------
191 VISU::Result_i* 
192 VISU::Prs3d_i
193 ::GetCResult() const 
194
195   return myResult;
196 }
197
198
199 //----------------------------------------------------------------------------
200 void
201 VISU::Prs3d_i
202 ::SetResultObject(VISU::Result_ptr theResult)
203 {
204   SetCResult(dynamic_cast<VISU::Result_i*>(GetServant(theResult).in()));
205 }
206
207
208 //----------------------------------------------------------------------------
209 VISU::Result_ptr
210 VISU::Prs3d_i
211 ::GetResultObject()
212 {
213   return GetCResult()->_this();
214 }
215
216
217 //----------------------------------------------------------------------------
218 void 
219 VISU::Prs3d_i
220 ::SetMeshName(const char* theMeshName)
221 {
222   if(myMeshName == theMeshName)
223     return;
224
225   VISU::TSetModified aModified(this);
226
227   myMeshName = theMeshName;
228   myParamsTime.Modified();
229 }
230
231
232 //----------------------------------------------------------------------------
233 char*
234 VISU::Prs3d_i
235 ::GetMeshName()
236 {
237   return CORBA::string_dup(myMeshName.c_str());
238 }
239
240
241 //----------------------------------------------------------------------------
242 std::string
243 VISU::Prs3d_i
244 ::GetCMeshName() const
245 {
246   return myMeshName;
247 }
248
249
250 //----------------------------------------------------------------------------
251 unsigned long int 
252 VISU::Prs3d_i
253 ::GetMTime()
254 {
255   unsigned long int aTime = myParamsTime.GetMTime();
256   if(IsPipeLineExists())
257     aTime = std::max(aTime, GetPipeLine()->GetMTime());
258   return aTime;
259 }
260
261 //----------------------------------------------------------------------------
262 bool 
263 VISU::Prs3d_i
264 ::GetActiveState()
265 {
266   return myIsActiveSatate;
267 }
268
269 //----------------------------------------------------------------------------
270 void 
271 VISU::Prs3d_i
272 ::SetActiveState(bool theState)
273 {
274   myIsActiveSatate = theState;
275 }
276
277 //----------------------------------------------------------------------------
278 VISU::Storable* 
279 VISU::Prs3d_i
280 ::Restore(SALOMEDS::SObject_ptr theSObject,
281           const Storable::TRestoringMap& theMap)
282 {
283   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
284   SetStudyDocument(aStudy);
285
286   bool anIsExists = false;
287   QString aResultEntry = VISU::Storable::FindValue(theMap,"myResultEntry", &anIsExists);
288   if(!anIsExists){
289     SALOMEDS::SObject_var aSObject = SALOMEDS::SObject::_duplicate(theSObject);
290     for(; aSObject->Depth() > 2 && !aResultEntry.isEmpty(); aSObject = aSObject->GetFather()){
291       CORBA::Object_var anObject = VISU::SObjectToObject(aSObject);
292       if(CORBA::is_nil(anObject))
293         continue;
294
295       VISU::Result_var aResult = VISU::Result::_narrow(anObject);
296       if(CORBA::is_nil(aResult))
297         continue;
298
299       CORBA::String_var anEntry = aSObject->GetID();
300       aResultEntry = anEntry.in();
301     }
302   }
303   SetResultEntry(aResultEntry.toLatin1().data());
304   if(!GetCResult())
305     return NULL;
306
307   SetMeshName((const char*)VISU::Storable::FindValue(theMap,"myMeshName").toLatin1());
308   SetName((const char*)VISU::Storable::FindValue(theMap,"myName").toLatin1(), false);
309   myOffset[0] = VISU::Storable::FindValue(theMap,"myOffset[0]").toFloat();
310   myOffset[1] = VISU::Storable::FindValue(theMap,"myOffset[1]").toFloat();
311   myOffset[2] = VISU::Storable::FindValue(theMap,"myOffset[2]").toFloat();
312   myParamsTime.Modified();
313   return this;
314 }
315
316 //----------------------------------------------------------------------------
317 void
318 VISU::Prs3d_i
319 ::ToStream(std::ostringstream& theStr)
320 {
321   Storable::DataToStream( theStr, "myResultEntry", GetResultEntry().c_str() );
322   Storable::DataToStream( theStr, "myMeshName", GetCMeshName().c_str() );
323   Storable::DataToStream( theStr, "myName", GetName().c_str() );
324   Storable::DataToStream( theStr, "myOffset[0]", myOffset[0] );
325   Storable::DataToStream( theStr, "myOffset[1]", myOffset[1] );
326   Storable::DataToStream( theStr, "myOffset[2]", myOffset[2] );
327 }
328
329
330 //----------------------------------------------------------------------------
331 SALOMEDS::SObject_var
332 VISU::Prs3d_i
333 ::GetSObject()
334 {
335   const SALOMEDS::Study_var& aStudy = GetStudyDocument();
336   if(!CORBA::is_nil(aStudy.in())){
337     CORBA::String_var anIOR = GetID();
338     return aStudy->FindObjectIOR(anIOR);
339   }
340   return SALOMEDS::SObject::_nil();
341 }
342
343
344 //----------------------------------------------------------------------------
345 void
346 VISU::Prs3d_i
347 ::Update()
348 {
349   if(GetMTime() < myUpdateTime.GetMTime())
350     return;
351
352   if(MYDEBUG) MESSAGE("Prs3d_i::Update - this = "<<this);
353
354   try{
355     ProcessVoidEvent(new TVoidMemFunEvent<VISU_PipeLine>
356                      (GetPipeLine(), &VISU_PipeLine::Update));
357     myUpdateTime.Modified();
358   }catch(std::exception&){
359     throw;
360   }catch(...){
361     throw std::runtime_error("Prs3d_i::Update >> unexpected exception was caught!!!");
362   }
363 }
364
365
366 //----------------------------------------------------------------------------
367 void
368 VISU::Prs3d_i
369 ::CheckDataSet()
370 {
371   vtkMapper *aMapper = GetPipeLine()->GetMapper();
372   vtkDataSet *aDataSet = aMapper->GetInput();
373   if (!aDataSet)
374     throw std::runtime_error("There is no input data !!!");
375
376   aDataSet->Update();
377   static float eps = VTK_LARGE_FLOAT * 0.1 ;
378   if (!aDataSet->GetNumberOfCells())
379     throw std::runtime_error("There are no visible elements");
380
381   if (aDataSet->GetLength() > eps)
382     throw std::runtime_error("Diagonal of the actor is too large !!!");
383 }
384
385
386 //----------------------------------------------------------------------------
387 void
388 VISU::Prs3d_i
389 ::RemoveFromStudy()
390 {
391   struct TEvent: public TInvokeSignalEvent
392   {
393     VISU::Prs3d_i* myRemovable;
394   
395     TEvent(const TSignal& theSignal,
396            VISU::Prs3d_i* theRemovable):
397       TInvokeSignalEvent(theSignal),
398       myRemovable(theRemovable)
399     {}
400   
401     virtual
402     void
403     Execute()
404     {
405       //TInvokeSignalEvent::Execute();
406       myRemovable->Destroy();
407     }
408   };
409
410   ProcessVoidEvent(new TEvent(myRemoveActorsFromRendererSignal, this));
411 }
412
413
414 //----------------------------------------------------------------------------
415 VISU_PipeLine*
416 VISU::Prs3d_i
417 ::GetPipeLine() const
418 {
419   if(!myPipeLine.GetPointer())
420     throw std::runtime_error("VISU::Prs3d_i::myPipeLine == NULL !!!");
421
422   return myPipeLine.GetPointer();
423 }
424
425 //----------------------------------------------------------------------------
426 void
427 VISU::Prs3d_i
428 ::SetPipeLine(VISU_PipeLine* thePipeLine)
429 {
430   myPipeLine = thePipeLine;
431   if(thePipeLine)
432     thePipeLine->Delete();
433 }
434
435 //----------------------------------------------------------------------------
436 bool 
437 VISU::Prs3d_i
438 ::IsPipeLineExists()
439 {
440   return myPipeLine.GetPointer() != NULL;
441 }
442
443 //----------------------------------------------------------------------------
444 VISU_PipeLine* 
445 VISU::Prs3d_i
446 ::GetActorPipeLine()
447 {
448   return GetPipeLine();
449 }
450
451 //----------------------------------------------------------------------------
452 vtkDataSet* 
453 VISU::Prs3d_i
454 ::GetInput()
455 {
456   return GetPipeLine()->GetInput();
457 }
458
459 //----------------------------------------------------------------------------
460 Handle(SALOME_InteractiveObject)
461 VISU::Prs3d_i
462 ::GetIO()
463 {
464   if( myIO.IsNull() )
465     myIO = new SALOME_InteractiveObject(GetActorEntry().c_str(), "VISU", GetName().c_str());
466
467   return myIO;
468 }
469
470 //----------------------------------------------------------------------------
471 std::string
472 VISU::Prs3d_i
473 ::GetActorEntry()
474 {
475   return GetEntry();
476 }
477
478
479 //----------------------------------------------------------------------------
480 void
481 VISU::Prs3d_i
482 ::CreateActor(VISU_Actor* theActor)
483 {
484   try{
485     SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
486
487     Handle(SALOME_InteractiveObject) anIO = GetIO();
488     if(!anIO.IsNull() && anIO->hasEntry()){
489       theActor->setIO(anIO);
490     }
491
492     Update();
493     CheckDataSet();
494
495     theActor->SetPrs3d(this);
496     theActor->SetShrinkFactor(aResourceMgr->integerValue("VISU", "shrink_factor", 80)/100.);
497     theActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
498     theActor->SetPipeLine(GetActorPipeLine());
499     if(theActor->GetPipeLine() != GetPipeLine()){
500        // To decrease actor'ss pipeline reference counter
501       theActor->GetPipeLine()->Delete();
502     }
503
504     theActor->SetFactory(this);
505     theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
506
507     myActorCollection->AddItem(theActor);
508     theActor->Delete();
509   }catch(std::bad_alloc& ex){
510     throw std::runtime_error("CreateActor >> No enough memory");
511     throw ex;
512   } catch(std::exception&){
513     throw;
514   }catch(...) {
515     throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
516   }
517 }
518
519 //----------------------------------------------------------------------------
520 void
521 VISU::Prs3d_i
522 ::RemoveActor(VISU_ActorBase* theActor)
523 {
524   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
525   myActorCollection->RemoveItem(theActor);
526 }
527
528 //----------------------------------------------------------------------------
529 void
530 VISU::Prs3d_i
531 ::RemoveActors()
532 {
533   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
534   ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
535   myActorCollection->RemoveAllItems();
536 }
537
538 //----------------------------------------------------------------------------
539 void
540 VISU::Prs3d_i
541 ::UpdateActor(VISU_ActorBase* theActor)
542 {
543   if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(theActor)){
544     if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<anActor);
545     anActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
546     anActor->ShallowCopyPL(GetPipeLine());
547     anActor->highlight(anActor->isHighlighted());
548   }
549 }
550
551 void
552 VISU::Prs3d_i
553 ::UpdateActors()
554 {
555   if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
556   Update();
557   try {
558     CheckDataSet();
559   } catch( std::exception& ex ) {
560     SUIT_MessageBox::warning( 0,
561                               QObject::tr("WRN_VISU"),
562                               QString( ex.what() ),
563                               QObject::tr("BUT_OK") );
564     RemoveActors();
565     return;
566   }
567   ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
568 }
569
570
571 //----------------------------------------------------------------------------
572 // Clipping planes
573 void
574 VISU::Prs3d_i
575 ::RemoveAllClippingPlanes()
576 {
577   GetPipeLine()->RemoveAllClippingPlanes();
578 }
579
580 //----------------------------------------------------------------------------
581 bool
582 VISU::Prs3d_i
583 ::AddClippingPlane(vtkPlane* thePlane)
584 {
585   return GetPipeLine()->AddClippingPlane(thePlane);
586 }
587
588 //----------------------------------------------------------------------------
589 vtkIdType
590 VISU::Prs3d_i
591 ::GetNumberOfClippingPlanes() const
592 {
593   return GetPipeLine()->GetNumberOfClippingPlanes();
594 }
595
596 //----------------------------------------------------------------------------
597 vtkPlane* 
598 VISU::Prs3d_i::
599 GetClippingPlane(vtkIdType theID) const
600 {
601   return GetPipeLine()->GetClippingPlane(theID);
602 }
603
604 //----------------------------------------------------------------------------
605 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
606 {
607   GetPipeLine()->RemoveClippingPlane(theID);
608 }
609
610 //----------------------------------------------------------------------------
611 void
612 VISU::Prs3d_i
613 ::SetPlaneParam(vtkFloatingPointType theDir[3], 
614                 vtkFloatingPointType theDist, 
615                 vtkPlane* thePlane) 
616 {
617   GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
618 }
619
620
621 //----------------------------------------------------------------------------
622 void
623 VISU::Prs3d_i
624 ::GetBounds(vtkFloatingPointType aBounds[6])
625 {
626   GetPipeLine()->GetMapper()->GetBounds(aBounds);
627 }
628
629 //----------------------------------------------------------------------------
630 void 
631 VISU::Prs3d_i
632 ::SetOffset(const CORBA::Float* theOffsets)
633 {
634   myOffset[0] = theOffsets[0];
635   myOffset[1] = theOffsets[1];
636   myOffset[2] = theOffsets[2];
637   myParamsTime.Modified();
638 }
639
640 //----------------------------------------------------------------------------
641 void
642 VISU::Prs3d_i
643 ::SetOffset(CORBA::Float theDx,
644             CORBA::Float theDy,
645             CORBA::Float theDz)
646 {
647   myOffset[0] = theDx;
648   myOffset[1] = theDy;
649   myOffset[2] = theDz;
650   myParamsTime.Modified();
651 }
652
653 //----------------------------------------------------------------------------
654 void
655 VISU::Prs3d_i
656 ::GetOffset(CORBA::Float* theOffsets)
657 {
658   theOffsets[0] = myOffset[0];
659   theOffsets[1] = myOffset[1];
660   theOffsets[2] = myOffset[2];
661 }
662
663 //----------------------------------------------------------------------------
664 void 
665 VISU::Prs3d_i
666 ::GetOffset(CORBA::Float& theDx,
667             CORBA::Float& theDy,
668             CORBA::Float& theDz)
669 {
670   theDx = myOffset[0];
671   theDy = myOffset[1];
672   theDz = myOffset[2];
673 }
674
675
676 //----------------------------------------------------------------------------
677 CORBA::Float
678 VISU::Prs3d_i
679 ::GetMemorySize()
680 {
681   // To calculate memory used by VISU PipeLine
682   CORBA::Float aSize = GetPipeLine()->GetMemorySize();
683   //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; GetPipeLine = "<<aSize / (1024.0 * 1024.0)<<endl;
684
685   // To calculate memory used by VISU Actos
686   int anEnd = myActorCollection->GetNumberOfItems();
687   for(int anId = 0; anId < anEnd; anId++)
688     if(vtkObject* anObject = myActorCollection->GetItemAsObject(anId))
689       if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(anObject)){
690         aSize += anActor->GetMemorySize();
691         //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; anActor = "<<aSize / (1024.0 * 1024.0)<<endl;
692       }
693
694   // Convert to mega bytes
695   return aSize / (1024.0 * 1024.0);
696 }
697
698 int
699 VISU::Prs3d_i
700 ::GetNumberOfActors()
701 {
702   return myActorCollection->GetNumberOfItems();
703 }