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