]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_Prs3d_i.cc
Salome HOME
Merge from V5_1_3_BR branch (07/12/09)
[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     SUIT_MessageBox::warning( 0,
380                               QObject::tr("WRN_VISU"),
381                               QObject::tr("WRN_NO_VISIBLE_ELEMENTS"),
382                               QObject::tr("BUT_OK"));
383     return;
384   }
385
386   if (aDataSet->GetLength() > eps)
387     throw std::runtime_error("Diagonal of the actor is too large !!!");
388 }
389
390
391 //----------------------------------------------------------------------------
392 void
393 VISU::Prs3d_i
394 ::RemoveFromStudy()
395 {
396   struct TEvent: public TInvokeSignalEvent
397   {
398     VISU::Prs3d_i* myRemovable;
399   
400     TEvent(const TSignal& theSignal,
401            VISU::Prs3d_i* theRemovable):
402       TInvokeSignalEvent(theSignal),
403       myRemovable(theRemovable)
404     {}
405   
406     virtual
407     void
408     Execute()
409     {
410       //TInvokeSignalEvent::Execute();
411       myRemovable->Destroy();
412     }
413   };
414
415   ProcessVoidEvent(new TEvent(myRemoveActorsFromRendererSignal, this));
416 }
417
418
419 //----------------------------------------------------------------------------
420 VISU_PipeLine*
421 VISU::Prs3d_i
422 ::GetPipeLine() const
423 {
424   if(!myPipeLine.GetPointer())
425     throw std::runtime_error("VISU::Prs3d_i::myPipeLine == NULL !!!");
426
427   return myPipeLine.GetPointer();
428 }
429
430 //----------------------------------------------------------------------------
431 void
432 VISU::Prs3d_i
433 ::SetPipeLine(VISU_PipeLine* thePipeLine)
434 {
435   myPipeLine = thePipeLine;
436   if(thePipeLine)
437     thePipeLine->Delete();
438 }
439
440 //----------------------------------------------------------------------------
441 bool 
442 VISU::Prs3d_i
443 ::IsPipeLineExists()
444 {
445   return myPipeLine.GetPointer() != NULL;
446 }
447
448 //----------------------------------------------------------------------------
449 VISU_PipeLine* 
450 VISU::Prs3d_i
451 ::GetActorPipeLine()
452 {
453   return GetPipeLine();
454 }
455
456 //----------------------------------------------------------------------------
457 vtkDataSet* 
458 VISU::Prs3d_i
459 ::GetInput()
460 {
461   return GetPipeLine()->GetInput();
462 }
463
464 //----------------------------------------------------------------------------
465 Handle(SALOME_InteractiveObject)
466 VISU::Prs3d_i
467 ::GetIO()
468 {
469   if( myIO.IsNull() )
470     myIO = new SALOME_InteractiveObject(GetActorEntry().c_str(), "VISU", GetName().c_str());
471
472   return myIO;
473 }
474
475 //----------------------------------------------------------------------------
476 std::string
477 VISU::Prs3d_i
478 ::GetActorEntry()
479 {
480   return GetEntry();
481 }
482
483
484 //----------------------------------------------------------------------------
485 void
486 VISU::Prs3d_i
487 ::CreateActor(VISU_Actor* theActor)
488 {
489   try{
490     SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
491
492     Handle(SALOME_InteractiveObject) anIO = GetIO();
493     if(!anIO.IsNull() && anIO->hasEntry()){
494       theActor->setIO(anIO);
495     }
496
497     Update();
498     CheckDataSet();
499
500     theActor->SetPrs3d(this);
501     theActor->SetShrinkFactor(aResourceMgr->integerValue("VISU", "shrink_factor", 80)/100.);
502     theActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
503     theActor->SetPipeLine(GetActorPipeLine());
504     if(theActor->GetPipeLine() != GetPipeLine()){
505        // To decrease actor'ss pipeline reference counter
506       theActor->GetPipeLine()->Delete();
507     }
508
509     theActor->SetFactory(this);
510     theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
511
512     myActorCollection->AddItem(theActor);
513     theActor->Delete();
514   }catch(std::bad_alloc& ex){
515     throw std::runtime_error("CreateActor >> No enough memory");
516     throw ex;
517   } catch(std::exception&){
518     throw;
519   }catch(...) {
520     throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
521   }
522 }
523
524 //----------------------------------------------------------------------------
525 void
526 VISU::Prs3d_i
527 ::RemoveActor(VISU_ActorBase* theActor)
528 {
529   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
530   myActorCollection->RemoveItem(theActor);
531 }
532
533 //----------------------------------------------------------------------------
534 void
535 VISU::Prs3d_i
536 ::RemoveActors()
537 {
538   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
539   ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
540   myActorCollection->RemoveAllItems();
541 }
542
543 //----------------------------------------------------------------------------
544 void
545 VISU::Prs3d_i
546 ::UpdateActor(VISU_ActorBase* theActor)
547 {
548   if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(theActor)){
549     if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<anActor);
550     anActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
551     anActor->ShallowCopyPL(GetPipeLine());
552     anActor->highlight(anActor->isHighlighted());
553   }
554 }
555
556 void
557 VISU::Prs3d_i
558 ::UpdateActors()
559 {
560   if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
561   Update();
562   CheckDataSet();
563   ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
564 }
565
566
567 //----------------------------------------------------------------------------
568 // Clipping planes
569 void
570 VISU::Prs3d_i
571 ::RemoveAllClippingPlanes()
572 {
573   GetPipeLine()->RemoveAllClippingPlanes();
574 }
575
576 //----------------------------------------------------------------------------
577 bool
578 VISU::Prs3d_i
579 ::AddClippingPlane(vtkPlane* thePlane)
580 {
581   return GetPipeLine()->AddClippingPlane(thePlane);
582 }
583
584 //----------------------------------------------------------------------------
585 vtkIdType
586 VISU::Prs3d_i
587 ::GetNumberOfClippingPlanes() const
588 {
589   return GetPipeLine()->GetNumberOfClippingPlanes();
590 }
591
592 //----------------------------------------------------------------------------
593 vtkPlane* 
594 VISU::Prs3d_i::
595 GetClippingPlane(vtkIdType theID) const
596 {
597   return GetPipeLine()->GetClippingPlane(theID);
598 }
599
600 //----------------------------------------------------------------------------
601 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
602 {
603   GetPipeLine()->RemoveClippingPlane(theID);
604 }
605
606 //----------------------------------------------------------------------------
607 void
608 VISU::Prs3d_i
609 ::SetPlaneParam(vtkFloatingPointType theDir[3], 
610                 vtkFloatingPointType theDist, 
611                 vtkPlane* thePlane) 
612 {
613   GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
614 }
615
616
617 //----------------------------------------------------------------------------
618 void
619 VISU::Prs3d_i
620 ::GetBounds(vtkFloatingPointType aBounds[6])
621 {
622   GetPipeLine()->GetMapper()->GetBounds(aBounds);
623 }
624
625 //----------------------------------------------------------------------------
626 void 
627 VISU::Prs3d_i
628 ::SetOffset(const CORBA::Float* theOffsets)
629 {
630   myOffset[0] = theOffsets[0];
631   myOffset[1] = theOffsets[1];
632   myOffset[2] = theOffsets[2];
633   myParamsTime.Modified();
634 }
635
636 //----------------------------------------------------------------------------
637 void
638 VISU::Prs3d_i
639 ::SetOffset(CORBA::Float theDx,
640             CORBA::Float theDy,
641             CORBA::Float theDz)
642 {
643   myOffset[0] = theDx;
644   myOffset[1] = theDy;
645   myOffset[2] = theDz;
646   myParamsTime.Modified();
647 }
648
649 //----------------------------------------------------------------------------
650 void
651 VISU::Prs3d_i
652 ::GetOffset(CORBA::Float* theOffsets)
653 {
654   theOffsets[0] = myOffset[0];
655   theOffsets[1] = myOffset[1];
656   theOffsets[2] = myOffset[2];
657 }
658
659 //----------------------------------------------------------------------------
660 void 
661 VISU::Prs3d_i
662 ::GetOffset(CORBA::Float& theDx,
663             CORBA::Float& theDy,
664             CORBA::Float& theDz)
665 {
666   theDx = myOffset[0];
667   theDy = myOffset[1];
668   theDz = myOffset[2];
669 }
670
671
672 //----------------------------------------------------------------------------
673 CORBA::Float
674 VISU::Prs3d_i
675 ::GetMemorySize()
676 {
677   // To calculate memory used by VISU PipeLine
678   CORBA::Float aSize = GetPipeLine()->GetMemorySize();
679   //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; GetPipeLine = "<<aSize / (1024.0 * 1024.0)<<endl;
680
681   // To calculate memory used by VISU Actos
682   int anEnd = myActorCollection->GetNumberOfItems();
683   for(int anId = 0; anId < anEnd; anId++)
684     if(vtkObject* anObject = myActorCollection->GetItemAsObject(anId))
685       if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(anObject)){
686         aSize += anActor->GetMemorySize();
687         //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; anActor = "<<aSize / (1024.0 * 1024.0)<<endl;
688       }
689
690   // Convert to mega bytes
691   return aSize / (1024.0 * 1024.0);
692 }
693
694 int
695 VISU::Prs3d_i
696 ::GetNumberOfActors()
697 {
698   return myActorCollection->GetNumberOfItems();
699 }