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