1 // Copyright (C) 2007-2010 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
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File : VISU_Prs3d_i.cc
25 // Author : Alexey PETROV
28 #include "VISU_Prs3d_i.hh"
29 #include "VISU_Prs3dUtils.hh"
30 #include "VISU_Gen_i.hh"
31 #include "VISU_PipeLine.hxx"
33 #include "VISU_Result_i.hh"
34 #include "VISU_Actor.h"
36 #include "SALOME_Event.h"
37 #include "SUIT_ResourceMgr.h"
38 #include "SUIT_MessageBox.h"
40 #include <VTKViewer_MarkerUtils.h>
42 #include <vtkActorCollection.h>
43 #include <vtkUnstructuredGrid.h>
44 #include <vtkDataSet.h>
45 #include <vtkMapper.h>
47 #include <boost/bind.hpp>
50 static int MYDEBUG = 1;
52 static int MYDEBUG = 0;
56 //----------------------------------------------------------------------------
57 VISU::Prs3d_i::Prs3d_i() :
58 PrsObject_i(SALOMEDS::Study::_nil()),
59 myActorCollection(vtkActorCollection::New()),
60 myIsActiveSatate(true),
61 myIsForcedHidden(false)
63 if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
64 myOffset[0] = myOffset[1] = myOffset[2] = 0;
65 myActorCollection->Delete();
67 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
68 myMarkerType = (VISU::MarkerType)aResourceMgr->integerValue("VISU", "type_of_marker", 1); // dot
69 myMarkerScale = (VISU::MarkerScale)aResourceMgr->integerValue("VISU", "marker_scale", 9); // 5 pixels
74 //----------------------------------------------------------------------------
77 ::SameAs(const Prs3d_i* theOrigin)
79 if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
80 VISU::TSetModified aModified(this);
82 GetPipeLine()->SameAs(anOrigin->GetPipeLine());
83 anOrigin->GetOffset(myOffset);
85 myMarkerType = anOrigin->GetMarkerType();
86 myMarkerScale = anOrigin->GetMarkerScale();
87 myMarkerId = anOrigin->GetMarkerTexture();
89 SetForcedHidden(anOrigin->IsForcedHidden());
94 //----------------------------------------------------------------------------
97 struct TInvokeSignalEvent: public SALOME_Event
99 typedef boost::signal0<void> TSignal;
100 const TSignal& mySignal;
102 TInvokeSignalEvent(const TSignal& theSignal):
115 //----------------------------------------------------------------------------
116 VISU::Prs3d_i::~Prs3d_i()
118 if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
119 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
123 //----------------------------------------------------------------------------
126 ::SetInput(bool theReInit)
129 if(myMeshName != ""){
130 myPreviousResult = myResult;
131 myPreviousMeshName = myMeshName;
139 //----------------------------------------------------------------------------
144 SetCResult(myPreviousResult);
145 myMeshName = myPreviousMeshName;
149 //----------------------------------------------------------------------------
152 ::Apply(bool theReInit)
155 if(SetInput(theReInit)){
156 if(myActorCollection->GetNumberOfItems())
160 }catch(std::exception& exc){
161 INFOS("Follow exception was occured :\n"<<exc.what());
163 INFOS("Unknown exception was occured!");
170 //----------------------------------------------------------------------------
173 ::SetCResult(VISU::Result_i* theResult)
175 if(GetCResult() == theResult)
179 SetStudyDocument(theResult->GetStudyDocument());
182 VISU::TSetModified aModified(this);
184 myResult = theResult;
185 myParamsTime.Modified();
188 //----------------------------------------------------------------------------
191 ::SetResultEntry(const std::string& theResultEntry)
193 SetCResult(VISU::GetResult(GetStudyDocument(), theResultEntry));
196 //----------------------------------------------------------------------------
201 if(VISU::Result_i* aResult = GetCResult())
202 return aResult->GetEntry();
206 //----------------------------------------------------------------------------
215 //----------------------------------------------------------------------------
218 ::SetResultObject(VISU::Result_ptr theResult)
220 SetCResult(dynamic_cast<VISU::Result_i*>(GetServant(theResult).in()));
224 //----------------------------------------------------------------------------
229 return GetCResult()->_this();
233 //----------------------------------------------------------------------------
236 ::SetMeshName(const char* theMeshName)
238 if(myMeshName == theMeshName)
241 VISU::TSetModified aModified(this);
243 myMeshName = theMeshName;
244 myParamsTime.Modified();
248 //----------------------------------------------------------------------------
253 return CORBA::string_dup(myMeshName.c_str());
257 //----------------------------------------------------------------------------
260 ::GetCMeshName() const
266 //----------------------------------------------------------------------------
271 unsigned long int aTime = myParamsTime.GetMTime();
272 if(IsPipeLineExists())
273 aTime = std::max(aTime, GetPipeLine()->GetMTime());
277 //----------------------------------------------------------------------------
282 return myIsActiveSatate;
285 //----------------------------------------------------------------------------
288 ::SetActiveState(bool theState)
290 myIsActiveSatate = theState;
293 //----------------------------------------------------------------------------
296 ::Restore(SALOMEDS::SObject_ptr theSObject,
297 const Storable::TRestoringMap& theMap)
299 SALOMEDS::Study_var aStudy = theSObject->GetStudy();
300 SetStudyDocument(aStudy);
302 bool anIsExists = false;
303 QString aResultEntry = VISU::Storable::FindValue(theMap,"myResultEntry", &anIsExists);
305 SALOMEDS::SObject_var aSObject = SALOMEDS::SObject::_duplicate(theSObject);
306 for(; aSObject->Depth() > 2 && !aResultEntry.isEmpty(); aSObject = aSObject->GetFather()){
307 CORBA::Object_var anObject = VISU::SObjectToObject(aSObject);
308 if(CORBA::is_nil(anObject))
311 VISU::Result_var aResult = VISU::Result::_narrow(anObject);
312 if(CORBA::is_nil(aResult))
315 CORBA::String_var anEntry = aSObject->GetID();
316 aResultEntry = anEntry.in();
319 SetResultEntry(aResultEntry.toLatin1().data());
323 SetMeshName((const char*)VISU::Storable::FindValue(theMap,"myMeshName").toLatin1());
324 SetName((const char*)VISU::Storable::FindValue(theMap,"myName").toLatin1(), false);
325 myOffset[0] = VISU::Storable::FindValue(theMap,"myOffset[0]").toFloat();
326 myOffset[1] = VISU::Storable::FindValue(theMap,"myOffset[1]").toFloat();
327 myOffset[2] = VISU::Storable::FindValue(theMap,"myOffset[2]").toFloat();
328 myMarkerType = VISU::MarkerType(VISU::Storable::FindValue(theMap,"myMarkerType").toInt());
329 myMarkerScale = VISU::MarkerScale(VISU::Storable::FindValue(theMap,"myMarkerScale").toInt());
330 myMarkerId = VISU::Storable::FindValue(theMap,"myMarkerId").toInt();
331 myParamsTime.Modified();
335 //----------------------------------------------------------------------------
338 ::ToStream(std::ostringstream& theStr)
340 Storable::DataToStream( theStr, "myResultEntry", GetResultEntry().c_str() );
341 Storable::DataToStream( theStr, "myMeshName", GetCMeshName().c_str() );
342 Storable::DataToStream( theStr, "myName", GetName().c_str() );
343 Storable::DataToStream( theStr, "myOffset[0]", myOffset[0] );
344 Storable::DataToStream( theStr, "myOffset[1]", myOffset[1] );
345 Storable::DataToStream( theStr, "myOffset[2]", myOffset[2] );
346 Storable::DataToStream( theStr, "myMarkerType", int(myMarkerType) );
347 Storable::DataToStream( theStr, "myMarkerScale", int(myMarkerScale) );
348 Storable::DataToStream( theStr, "myMarkerId", myMarkerId );
352 //----------------------------------------------------------------------------
353 SALOMEDS::SObject_var
357 const SALOMEDS::Study_var& aStudy = GetStudyDocument();
358 if(!CORBA::is_nil(aStudy.in())){
359 CORBA::String_var anIOR = GetID();
360 return aStudy->FindObjectIOR(anIOR);
362 return SALOMEDS::SObject::_nil();
366 //----------------------------------------------------------------------------
371 if(GetMTime() < myUpdateTime.GetMTime())
374 if(MYDEBUG) MESSAGE("Prs3d_i::Update - this = "<<this);
377 ProcessVoidEvent(new TVoidMemFunEvent<VISU_PipeLine>
378 (GetPipeLine(), &VISU_PipeLine::Update));
379 myUpdateTime.Modified();
380 }catch(std::exception&){
383 throw std::runtime_error("Prs3d_i::Update >> unexpected exception was caught!!!");
388 //----------------------------------------------------------------------------
393 vtkMapper *aMapper = GetPipeLine()->GetMapper();
394 vtkDataSet *aDataSet = aMapper->GetInput();
396 throw std::runtime_error("There is no input data !!!");
399 static float eps = VTK_LARGE_FLOAT * 0.1 ;
400 if (!aDataSet->GetNumberOfCells())
401 throw std::runtime_error("There are no visible elements");
403 if (aDataSet->GetLength() > eps)
404 throw std::runtime_error("Diagonal of the actor is too large !!!");
408 //----------------------------------------------------------------------------
413 struct TEvent: public TInvokeSignalEvent
415 VISU::Prs3d_i* myRemovable;
417 TEvent(const TSignal& theSignal,
418 VISU::Prs3d_i* theRemovable):
419 TInvokeSignalEvent(theSignal),
420 myRemovable(theRemovable)
427 //TInvokeSignalEvent::Execute();
428 myRemovable->Destroy();
432 ProcessVoidEvent(new TEvent(myRemoveActorsFromRendererSignal, this));
436 //----------------------------------------------------------------------------
439 ::GetPipeLine() const
441 if(!myPipeLine.GetPointer())
442 throw std::runtime_error("VISU::Prs3d_i::myPipeLine == NULL !!!");
444 return myPipeLine.GetPointer();
447 //----------------------------------------------------------------------------
450 ::SetPipeLine(VISU_PipeLine* thePipeLine)
452 myPipeLine = thePipeLine;
454 thePipeLine->Delete();
457 //----------------------------------------------------------------------------
462 return myPipeLine.GetPointer() != NULL;
465 //----------------------------------------------------------------------------
470 return GetPipeLine();
473 //----------------------------------------------------------------------------
478 return GetPipeLine()->GetInput();
481 //----------------------------------------------------------------------------
482 Handle(SALOME_InteractiveObject)
487 myIO = new SALOME_InteractiveObject(GetActorEntry().c_str(), "VISU", GetName().c_str());
492 //----------------------------------------------------------------------------
501 //----------------------------------------------------------------------------
504 ::CreateActor(VISU_Actor* theActor)
507 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
509 Handle(SALOME_InteractiveObject) anIO = GetIO();
510 if(!anIO.IsNull() && anIO->hasEntry()){
511 theActor->setIO(anIO);
517 theActor->SetPrs3d(this);
518 theActor->SetShrinkFactor(aResourceMgr->integerValue("VISU", "shrink_factor", 80)/100.);
519 theActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
521 if( myMarkerType != VISU::MT_USER )
522 theActor->SetMarkerStd( (VTK::MarkerType)myMarkerType, (VTK::MarkerScale)myMarkerScale );
523 else if( myMarkerId > 0 ) {
524 VTK::MarkerTexture aMarkerTexture;
525 if( LoadMarkerTexture( myMarkerId, aMarkerTexture ) )
526 theActor->SetMarkerTexture( myMarkerId, aMarkerTexture );
529 theActor->SetPipeLine(GetActorPipeLine());
530 if(theActor->GetPipeLine() != GetPipeLine()){
531 // To decrease actor'ss pipeline reference counter
532 theActor->GetPipeLine()->Delete();
535 theActor->SetFactory(this);
536 theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
538 myActorCollection->AddItem(theActor);
540 }catch(std::bad_alloc& ex){
541 throw std::runtime_error("CreateActor >> No enough memory");
543 } catch(std::exception&){
546 throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
550 //----------------------------------------------------------------------------
553 ::RemoveActor(VISU_ActorBase* theActor)
555 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
556 myActorCollection->RemoveItem(theActor);
559 //----------------------------------------------------------------------------
564 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
565 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
566 myActorCollection->RemoveAllItems();
569 //----------------------------------------------------------------------------
572 ::UpdateActor(VISU_ActorBase* theActor)
574 if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(theActor)){
575 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<anActor);
576 anActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
578 if( myMarkerType != VISU::MT_USER )
579 anActor->SetMarkerStd( (VTK::MarkerType)myMarkerType, (VTK::MarkerScale)myMarkerScale );
580 else if( myMarkerId > 0 ) {
581 VTK::MarkerTexture aMarkerTexture;
582 if( LoadMarkerTexture( myMarkerId, aMarkerTexture ) )
583 anActor->SetMarkerTexture( myMarkerId, aMarkerTexture );
586 anActor->ShallowCopyPL(GetPipeLine());
587 anActor->highlight(anActor->isHighlighted());
595 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
599 } catch( std::exception& ex ) {
600 if( !IsForcedHidden() ) {
601 if( HasVisibleActors() )
602 SetForcedHidden( true );
604 SUIT_MessageBox::warning( 0,
605 QObject::tr("WRN_VISU"),
606 QString( ex.what() ),
607 QObject::tr("BUT_OK") );
611 ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
615 //----------------------------------------------------------------------------
619 ::RemoveAllClippingPlanes()
621 GetPipeLine()->RemoveAllClippingPlanes();
624 //----------------------------------------------------------------------------
627 ::AddClippingPlane(vtkPlane* thePlane)
629 return GetPipeLine()->AddClippingPlane(thePlane);
632 //----------------------------------------------------------------------------
635 ::GetNumberOfClippingPlanes() const
637 return GetPipeLine()->GetNumberOfClippingPlanes();
640 //----------------------------------------------------------------------------
643 GetClippingPlane(vtkIdType theID) const
645 return GetPipeLine()->GetClippingPlane(theID);
648 //----------------------------------------------------------------------------
649 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
651 GetPipeLine()->RemoveClippingPlane(theID);
654 //----------------------------------------------------------------------------
657 ::SetPlaneParam(vtkFloatingPointType theDir[3],
658 vtkFloatingPointType theDist,
661 GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
665 //----------------------------------------------------------------------------
668 ::GetBounds(vtkFloatingPointType aBounds[6])
670 GetPipeLine()->GetMapper()->GetBounds(aBounds);
673 //----------------------------------------------------------------------------
676 ::SetOffset(const CORBA::Float* theOffsets)
678 myOffset[0] = theOffsets[0];
679 myOffset[1] = theOffsets[1];
680 myOffset[2] = theOffsets[2];
681 myParamsTime.Modified();
684 //----------------------------------------------------------------------------
687 ::SetOffset(CORBA::Float theDx,
694 myParamsTime.Modified();
697 //----------------------------------------------------------------------------
700 ::GetOffset(CORBA::Float* theOffsets)
702 theOffsets[0] = myOffset[0];
703 theOffsets[1] = myOffset[1];
704 theOffsets[2] = myOffset[2];
707 //----------------------------------------------------------------------------
710 ::GetOffset(CORBA::Float& theDx,
720 //----------------------------------------------------------------------------
725 // To calculate memory used by VISU PipeLine
726 CORBA::Float aSize = GetPipeLine()->GetMemorySize();
727 //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; GetPipeLine = "<<aSize / (1024.0 * 1024.0)<<endl;
729 // To calculate memory used by VISU Actos
730 int anEnd = myActorCollection->GetNumberOfItems();
731 for(int anId = 0; anId < anEnd; anId++)
732 if(vtkObject* anObject = myActorCollection->GetItemAsObject(anId))
733 if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(anObject)){
734 aSize += anActor->GetMemorySize();
735 //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; anActor = "<<aSize / (1024.0 * 1024.0)<<endl;
738 // Convert to mega bytes
739 return aSize / (1024.0 * 1024.0);
744 ::GetNumberOfActors()
746 return myActorCollection->GetNumberOfItems();
753 myActorCollection->InitTraversal();
754 while( vtkActor* anActor = myActorCollection->GetNextActor() )
755 if( VISU_Actor* aVISUActor = dynamic_cast<VISU_Actor*>( anActor ) )
756 if( aVISUActor->GetVisibility() )
763 ::IsForcedHidden() const
765 return myIsForcedHidden;
770 ::SetForcedHidden( bool theFlag )
772 myIsForcedHidden = theFlag;
775 //----------------------------------------------------------------------------
778 ::SetMarkerStd(VISU::MarkerType theMarkerType, VISU::MarkerScale theMarkerScale)
780 myMarkerType = theMarkerType;
781 myMarkerScale = theMarkerScale;
782 myParamsTime.Modified();
785 //----------------------------------------------------------------------------
788 ::SetMarkerTexture(CORBA::Long theMarkerId)
790 myMarkerType = VISU::MT_USER;
791 myMarkerId = theMarkerId;
792 myParamsTime.Modified();
795 //----------------------------------------------------------------------------
803 //----------------------------------------------------------------------------
808 return myMarkerScale;
811 //----------------------------------------------------------------------------
819 //----------------------------------------------------------------------------
822 ::LoadMarkerTexture(int theMarkerId, VTK::MarkerTexture& theMarkerTexture)
824 VISU::VISU_Gen_i* aVisuGen = VISU::VISU_Gen_i::GetVisuGenImpl();
828 const VISU::StudyId2MarkerMap& aStudyId2MarkerMap = aVisuGen->GetMarkerMap();
830 const SALOMEDS::Study_var& aStudy = GetStudyDocument();
831 if( CORBA::is_nil( aStudy.in() ) )
834 int aStudyId = aStudy->StudyId();
835 VISU::StudyId2MarkerMap::const_iterator aStudyId2MarkerIter = aStudyId2MarkerMap.find( aStudyId );
836 if( aStudyId2MarkerIter == aStudyId2MarkerMap.end() )
839 VTK::MarkerMap aMarkerMap = aStudyId2MarkerIter->second;
840 VTK::MarkerMap::const_iterator aMarkerIter = aMarkerMap.find( theMarkerId );
841 if( aMarkerIter == aMarkerMap.end() )
844 theMarkerTexture = aMarkerIter->second.second;