1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // VISU OBJECT : interactive object for VISU entities implementation
23 // File : VISU_Prs3d_i.cc
24 // Author : Alexey PETROV
27 #include "VISU_Prs3d_i.hh"
28 #include "VISU_Prs3dUtils.hh"
29 #include "VISU_PipeLine.hxx"
31 #include "VISU_Result_i.hh"
32 #include "VISU_Actor.h"
34 #include "SALOME_Event.h"
35 #include "SUIT_ResourceMgr.h"
36 #include "SUIT_MessageBox.h"
38 #include <vtkActorCollection.h>
39 #include <vtkUnstructuredGrid.h>
40 #include <vtkDataSet.h>
41 #include <vtkMapper.h>
43 #include <boost/bind.hpp>
46 static int MYDEBUG = 1;
48 static int MYDEBUG = 0;
52 //----------------------------------------------------------------------------
53 VISU::Prs3d_i::Prs3d_i() :
54 PrsObject_i(SALOMEDS::Study::_nil()),
55 myActorCollection(vtkActorCollection::New()),
56 myIsActiveSatate(true),
57 myIsForcedHidden(false)
59 if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
60 myOffset[0] = myOffset[1] = myOffset[2] = 0;
61 myActorCollection->Delete();
65 //----------------------------------------------------------------------------
68 ::SameAs(const Prs3d_i* theOrigin)
70 if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
71 VISU::TSetModified aModified(this);
73 GetPipeLine()->SameAs(anOrigin->GetPipeLine());
74 anOrigin->GetOffset(myOffset);
76 SetForcedHidden(anOrigin->IsForcedHidden());
81 //----------------------------------------------------------------------------
84 struct TInvokeSignalEvent: public SALOME_Event
86 typedef boost::signal0<void> TSignal;
87 const TSignal& mySignal;
89 TInvokeSignalEvent(const TSignal& theSignal):
102 //----------------------------------------------------------------------------
103 VISU::Prs3d_i::~Prs3d_i()
105 if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
106 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
110 //----------------------------------------------------------------------------
113 ::SetInput(bool theReInit)
116 if(myMeshName != ""){
117 myPreviousResult = myResult;
118 myPreviousMeshName = myMeshName;
126 //----------------------------------------------------------------------------
131 SetCResult(myPreviousResult);
132 myMeshName = myPreviousMeshName;
136 //----------------------------------------------------------------------------
139 ::Apply(bool theReInit)
142 if(SetInput(theReInit)){
143 if(myActorCollection->GetNumberOfItems())
147 }catch(std::exception& exc){
148 INFOS("Follow exception was occured :\n"<<exc.what());
150 INFOS("Unknown exception was occured!");
157 //----------------------------------------------------------------------------
160 ::SetCResult(VISU::Result_i* theResult)
162 if(GetCResult() == theResult)
166 SetStudyDocument(theResult->GetStudyDocument());
169 VISU::TSetModified aModified(this);
171 myResult = theResult;
172 myParamsTime.Modified();
175 //----------------------------------------------------------------------------
178 ::SetResultEntry(const std::string& theResultEntry)
180 SetCResult(VISU::GetResult(GetStudyDocument(), theResultEntry));
183 //----------------------------------------------------------------------------
188 if(VISU::Result_i* aResult = GetCResult())
189 return aResult->GetEntry();
193 //----------------------------------------------------------------------------
202 //----------------------------------------------------------------------------
205 ::SetResultObject(VISU::Result_ptr theResult)
207 SetCResult(dynamic_cast<VISU::Result_i*>(GetServant(theResult).in()));
211 //----------------------------------------------------------------------------
216 return GetCResult()->_this();
220 //----------------------------------------------------------------------------
223 ::SetMeshName(const char* theMeshName)
225 if(myMeshName == theMeshName)
228 VISU::TSetModified aModified(this);
230 myMeshName = theMeshName;
231 myParamsTime.Modified();
235 //----------------------------------------------------------------------------
240 return CORBA::string_dup(myMeshName.c_str());
244 //----------------------------------------------------------------------------
247 ::GetCMeshName() const
253 //----------------------------------------------------------------------------
258 unsigned long int aTime = myParamsTime.GetMTime();
259 if(IsPipeLineExists())
260 aTime = std::max(aTime, GetPipeLine()->GetMTime());
264 //----------------------------------------------------------------------------
269 return myIsActiveSatate;
272 //----------------------------------------------------------------------------
275 ::SetActiveState(bool theState)
277 myIsActiveSatate = theState;
280 //----------------------------------------------------------------------------
283 ::Restore(SALOMEDS::SObject_ptr theSObject,
284 const Storable::TRestoringMap& theMap)
286 SALOMEDS::Study_var aStudy = theSObject->GetStudy();
287 SetStudyDocument(aStudy);
289 bool anIsExists = false;
290 QString aResultEntry = VISU::Storable::FindValue(theMap,"myResultEntry", &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))
298 VISU::Result_var aResult = VISU::Result::_narrow(anObject);
299 if(CORBA::is_nil(aResult))
302 CORBA::String_var anEntry = aSObject->GetID();
303 aResultEntry = anEntry.in();
306 SetResultEntry(aResultEntry.toLatin1().data());
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();
319 //----------------------------------------------------------------------------
322 ::ToStream(std::ostringstream& theStr)
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] );
333 //----------------------------------------------------------------------------
334 SALOMEDS::SObject_var
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);
343 return SALOMEDS::SObject::_nil();
347 //----------------------------------------------------------------------------
352 if(GetMTime() < myUpdateTime.GetMTime())
355 if(MYDEBUG) MESSAGE("Prs3d_i::Update - this = "<<this);
358 ProcessVoidEvent(new TVoidMemFunEvent<VISU_PipeLine>
359 (GetPipeLine(), &VISU_PipeLine::Update));
360 myUpdateTime.Modified();
361 }catch(std::exception&){
364 throw std::runtime_error("Prs3d_i::Update >> unexpected exception was caught!!!");
369 //----------------------------------------------------------------------------
374 vtkMapper *aMapper = GetPipeLine()->GetMapper();
375 vtkDataSet *aDataSet = aMapper->GetInput();
377 throw std::runtime_error("There is no input data !!!");
380 static float eps = VTK_LARGE_FLOAT * 0.1 ;
381 if (!aDataSet->GetNumberOfCells())
382 throw std::runtime_error("There are no visible elements");
384 if (aDataSet->GetLength() > eps)
385 throw std::runtime_error("Diagonal of the actor is too large !!!");
389 //----------------------------------------------------------------------------
394 struct TEvent: public TInvokeSignalEvent
396 VISU::Prs3d_i* myRemovable;
398 TEvent(const TSignal& theSignal,
399 VISU::Prs3d_i* theRemovable):
400 TInvokeSignalEvent(theSignal),
401 myRemovable(theRemovable)
408 //TInvokeSignalEvent::Execute();
409 myRemovable->Destroy();
413 ProcessVoidEvent(new TEvent(myRemoveActorsFromRendererSignal, this));
417 //----------------------------------------------------------------------------
420 ::GetPipeLine() const
422 if(!myPipeLine.GetPointer())
423 throw std::runtime_error("VISU::Prs3d_i::myPipeLine == NULL !!!");
425 return myPipeLine.GetPointer();
428 //----------------------------------------------------------------------------
431 ::SetPipeLine(VISU_PipeLine* thePipeLine)
433 myPipeLine = thePipeLine;
435 thePipeLine->Delete();
438 //----------------------------------------------------------------------------
443 return myPipeLine.GetPointer() != NULL;
446 //----------------------------------------------------------------------------
451 return GetPipeLine();
454 //----------------------------------------------------------------------------
459 return GetPipeLine()->GetInput();
462 //----------------------------------------------------------------------------
463 Handle(SALOME_InteractiveObject)
468 myIO = new SALOME_InteractiveObject(GetActorEntry().c_str(), "VISU", GetName().c_str());
473 //----------------------------------------------------------------------------
482 //----------------------------------------------------------------------------
485 ::CreateActor(VISU_Actor* theActor)
488 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
490 Handle(SALOME_InteractiveObject) anIO = GetIO();
491 if(!anIO.IsNull() && anIO->hasEntry()){
492 theActor->setIO(anIO);
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();
507 theActor->SetFactory(this);
508 theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
510 myActorCollection->AddItem(theActor);
512 }catch(std::bad_alloc& ex){
513 throw std::runtime_error("CreateActor >> No enough memory");
515 } catch(std::exception&){
518 throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
522 //----------------------------------------------------------------------------
525 ::RemoveActor(VISU_ActorBase* theActor)
527 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
528 myActorCollection->RemoveItem(theActor);
531 //----------------------------------------------------------------------------
536 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
537 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
538 myActorCollection->RemoveAllItems();
541 //----------------------------------------------------------------------------
544 ::UpdateActor(VISU_ActorBase* theActor)
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());
558 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
562 } catch( std::exception& ex ) {
563 if( !IsForcedHidden() ) {
564 if( HasVisibleActors() )
565 SetForcedHidden( true );
567 SUIT_MessageBox::warning( 0,
568 QObject::tr("WRN_VISU"),
569 QString( ex.what() ),
570 QObject::tr("BUT_OK") );
574 ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
578 //----------------------------------------------------------------------------
582 ::RemoveAllClippingPlanes()
584 GetPipeLine()->RemoveAllClippingPlanes();
587 //----------------------------------------------------------------------------
590 ::AddClippingPlane(vtkPlane* thePlane)
592 return GetPipeLine()->AddClippingPlane(thePlane);
595 //----------------------------------------------------------------------------
598 ::GetNumberOfClippingPlanes() const
600 return GetPipeLine()->GetNumberOfClippingPlanes();
603 //----------------------------------------------------------------------------
606 GetClippingPlane(vtkIdType theID) const
608 return GetPipeLine()->GetClippingPlane(theID);
611 //----------------------------------------------------------------------------
612 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
614 GetPipeLine()->RemoveClippingPlane(theID);
617 //----------------------------------------------------------------------------
620 ::SetPlaneParam(vtkFloatingPointType theDir[3],
621 vtkFloatingPointType theDist,
624 GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
628 //----------------------------------------------------------------------------
631 ::GetBounds(vtkFloatingPointType aBounds[6])
633 GetPipeLine()->GetMapper()->GetBounds(aBounds);
636 //----------------------------------------------------------------------------
639 ::SetOffset(const CORBA::Float* theOffsets)
641 myOffset[0] = theOffsets[0];
642 myOffset[1] = theOffsets[1];
643 myOffset[2] = theOffsets[2];
644 myParamsTime.Modified();
647 //----------------------------------------------------------------------------
650 ::SetOffset(CORBA::Float theDx,
657 myParamsTime.Modified();
660 //----------------------------------------------------------------------------
663 ::GetOffset(CORBA::Float* theOffsets)
665 theOffsets[0] = myOffset[0];
666 theOffsets[1] = myOffset[1];
667 theOffsets[2] = myOffset[2];
670 //----------------------------------------------------------------------------
673 ::GetOffset(CORBA::Float& theDx,
683 //----------------------------------------------------------------------------
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;
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;
701 // Convert to mega bytes
702 return aSize / (1024.0 * 1024.0);
707 ::GetNumberOfActors()
709 return myActorCollection->GetNumberOfItems();
716 myActorCollection->InitTraversal();
717 while( vtkActor* anActor = myActorCollection->GetNextActor() )
718 if( VISU_Actor* aVISUActor = dynamic_cast<VISU_Actor*>( anActor ) )
719 if( aVISUActor->GetVisibility() )
726 ::IsForcedHidden() const
728 return myIsForcedHidden;
733 ::SetForcedHidden( bool theFlag )
735 myIsForcedHidden = theFlag;