]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_Prs3d_i.cc
Salome HOME
Merge from BR_V5_DEV 16Feb09
[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
36 #include <vtkActorCollection.h>
37 #include <vtkUnstructuredGrid.h>
38 #include <vtkDataSet.h>
39 #include <vtkMapper.h>
40
41 #include <boost/bind.hpp>
42
43 #ifdef _DEBUG_
44 static int MYDEBUG = 1;
45 #else
46 static int MYDEBUG = 0;
47 #endif
48
49
50 //----------------------------------------------------------------------------
51 VISU::Prs3d_i::Prs3d_i() :
52   PrsObject_i(SALOMEDS::Study::_nil()),
53   myActorCollection(vtkActorCollection::New()),
54   myIsActiveSatate(true)
55 {
56   if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
57   myOffset[0] = myOffset[1] = myOffset[2] = 0;
58   myActorCollection->Delete();
59 }
60
61
62 //----------------------------------------------------------------------------
63 void
64 VISU::Prs3d_i
65 ::SameAs(const Prs3d_i* theOrigin)
66 {
67   if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
68     VISU::TSetModified aModified(this);
69
70     GetPipeLine()->SameAs(anOrigin->GetPipeLine());
71     anOrigin->GetOffset(myOffset);
72   }
73 }
74
75
76 //----------------------------------------------------------------------------
77 namespace VISU
78 {
79   struct TInvokeSignalEvent: public SALOME_Event
80   {
81     typedef boost::signal0<void> TSignal;
82     const TSignal& mySignal;
83     
84     TInvokeSignalEvent(const TSignal& theSignal):
85       mySignal(theSignal)
86     {}
87     
88     virtual
89     void
90     Execute()
91     {
92       mySignal();
93     }
94   };
95 }
96
97 //----------------------------------------------------------------------------
98 VISU::Prs3d_i::~Prs3d_i()
99 {
100   if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
101   ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
102   if(myResult) myResult->Destroy();
103 }
104
105
106 //----------------------------------------------------------------------------
107 bool 
108 VISU::Prs3d_i
109 ::SetInput(bool theReInit)
110 {
111   if(GetCResult()){
112     if(myMeshName != ""){
113       myPreviousResult = myResult;
114       myPreviousMeshName = myMeshName;
115       return true;
116     }
117   }
118   return false;
119 }
120
121
122 //----------------------------------------------------------------------------
123 void 
124 VISU::Prs3d_i
125 ::OnRestoreInput()
126 {
127   SetCResult(myPreviousResult);
128   myMeshName = myPreviousMeshName;
129 }
130
131
132 //----------------------------------------------------------------------------
133 CORBA::Boolean 
134 VISU::Prs3d_i
135 ::Apply(bool theReInit)
136 {
137   try{
138     if(SetInput(theReInit)){
139       if(myActorCollection->GetNumberOfItems())
140         UpdateActors();
141       return true;
142     }
143   }catch(std::exception& exc){
144     INFOS("Follow exception was occured :\n"<<exc.what());
145   }catch(...){
146     INFOS("Unknown exception was occured!");
147   }
148   OnRestoreInput();
149   return false;
150 }
151
152
153 //----------------------------------------------------------------------------
154 void
155 VISU::Prs3d_i
156 ::SetCResult(VISU::Result_i* theResult)
157 {
158   if(GetCResult() == theResult)
159     return;
160
161   if(theResult) {
162     SetStudyDocument(theResult->GetStudyDocument());
163     theResult->Register();
164   }
165   if(myResult) {
166     myResult->Destroy();
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     Handle(SALOME_InteractiveObject) anIO = GetIO();
489     if(!anIO.IsNull() && anIO->hasEntry()){
490       theActor->setIO(anIO);
491     }
492
493     Update();
494     CheckDataSet();
495
496     theActor->SetPrs3d(this);
497     theActor->SetShrinkFactor();
498     theActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
499     theActor->SetPipeLine(GetActorPipeLine());
500     if(theActor->GetPipeLine() != GetPipeLine()){
501        // To decrease actor'ss pipeline reference counter
502       theActor->GetPipeLine()->Delete();
503     }
504
505     theActor->SetFactory(this);
506     theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
507
508     myActorCollection->AddItem(theActor);
509     theActor->Delete();
510   }catch(std::bad_alloc& ex){
511     throw std::runtime_error("CreateActor >> No enough memory");
512     throw ex;
513   } catch(std::exception&){
514     throw;
515   }catch(...) {
516     throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
517   }
518 }
519
520 //----------------------------------------------------------------------------
521 void
522 VISU::Prs3d_i
523 ::RemoveActor(VISU_ActorBase* theActor)
524 {
525   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
526   myActorCollection->RemoveItem(theActor);
527 }
528
529 //----------------------------------------------------------------------------
530 void
531 VISU::Prs3d_i
532 ::RemoveActors()
533 {
534   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
535   ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
536   myActorCollection->RemoveAllItems();
537 }
538
539 //----------------------------------------------------------------------------
540 void
541 VISU::Prs3d_i
542 ::UpdateActor(VISU_ActorBase* theActor)
543 {
544   if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(theActor)){
545     if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<anActor);
546     anActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
547     anActor->ShallowCopyPL(GetPipeLine());
548   }
549 }
550
551 void
552 VISU::Prs3d_i
553 ::UpdateActors()
554 {
555   if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
556   Update();
557   CheckDataSet();
558   ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
559 }
560
561
562 //----------------------------------------------------------------------------
563 // Clipping planes
564 void
565 VISU::Prs3d_i
566 ::RemoveAllClippingPlanes()
567 {
568   GetPipeLine()->RemoveAllClippingPlanes();
569 }
570
571 //----------------------------------------------------------------------------
572 bool
573 VISU::Prs3d_i
574 ::AddClippingPlane(vtkPlane* thePlane)
575 {
576   return GetPipeLine()->AddClippingPlane(thePlane);
577 }
578
579 //----------------------------------------------------------------------------
580 vtkIdType
581 VISU::Prs3d_i
582 ::GetNumberOfClippingPlanes() const
583 {
584   return GetPipeLine()->GetNumberOfClippingPlanes();
585 }
586
587 //----------------------------------------------------------------------------
588 vtkPlane* 
589 VISU::Prs3d_i::
590 GetClippingPlane(vtkIdType theID) const
591 {
592   return GetPipeLine()->GetClippingPlane(theID);
593 }
594
595 //----------------------------------------------------------------------------
596 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
597 {
598   GetPipeLine()->RemoveClippingPlane(theID);
599 }
600
601 //----------------------------------------------------------------------------
602 void
603 VISU::Prs3d_i
604 ::SetPlaneParam(vtkFloatingPointType theDir[3], 
605                 vtkFloatingPointType theDist, 
606                 vtkPlane* thePlane) 
607 {
608   GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
609 }
610
611
612 //----------------------------------------------------------------------------
613 void
614 VISU::Prs3d_i
615 ::GetBounds(vtkFloatingPointType aBounds[6])
616 {
617   GetPipeLine()->GetMapper()->GetBounds(aBounds);
618 }
619
620 //----------------------------------------------------------------------------
621 void 
622 VISU::Prs3d_i
623 ::SetOffset(const CORBA::Float* theOffsets)
624 {
625   myOffset[0] = theOffsets[0];
626   myOffset[1] = theOffsets[1];
627   myOffset[2] = theOffsets[2];
628   myParamsTime.Modified();
629 }
630
631 //----------------------------------------------------------------------------
632 void
633 VISU::Prs3d_i
634 ::SetOffset(CORBA::Float theDx,
635             CORBA::Float theDy,
636             CORBA::Float theDz)
637 {
638   myOffset[0] = theDx;
639   myOffset[1] = theDy;
640   myOffset[2] = theDz;
641   myParamsTime.Modified();
642 }
643
644 //----------------------------------------------------------------------------
645 void
646 VISU::Prs3d_i
647 ::GetOffset(CORBA::Float* theOffsets)
648 {
649   theOffsets[0] = myOffset[0];
650   theOffsets[1] = myOffset[1];
651   theOffsets[2] = myOffset[2];
652 }
653
654 //----------------------------------------------------------------------------
655 void 
656 VISU::Prs3d_i
657 ::GetOffset(CORBA::Float& theDx,
658             CORBA::Float& theDy,
659             CORBA::Float& theDz)
660 {
661   theDx = myOffset[0];
662   theDy = myOffset[1];
663   theDz = myOffset[2];
664 }
665
666
667 //----------------------------------------------------------------------------
668 CORBA::Float
669 VISU::Prs3d_i
670 ::GetMemorySize()
671 {
672   // To calculate memory used by VISU PipeLine
673   CORBA::Float aSize = GetPipeLine()->GetMemorySize();
674   //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; GetPipeLine = "<<aSize / (1024.0 * 1024.0)<<endl;
675
676   // To calculate memory used by VISU Actos
677   int anEnd = myActorCollection->GetNumberOfItems();
678   for(int anId = 0; anId < anEnd; anId++)
679     if(vtkObject* anObject = myActorCollection->GetItemAsObject(anId))
680       if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(anObject)){
681         aSize += anActor->GetMemorySize();
682         //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; anActor = "<<aSize / (1024.0 * 1024.0)<<endl;
683       }
684
685   // Convert to mega bytes
686   return aSize / (1024.0 * 1024.0);
687 }
688
689 int
690 VISU::Prs3d_i
691 ::GetNumberOfActors()
692 {
693   return myActorCollection->GetNumberOfItems();
694 }