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"
37 #include <vtkActorCollection.h>
38 #include <vtkUnstructuredGrid.h>
39 #include <vtkDataSet.h>
40 #include <vtkMapper.h>
42 #include <boost/bind.hpp>
45 static int MYDEBUG = 1;
47 static int MYDEBUG = 0;
51 //----------------------------------------------------------------------------
52 VISU::Prs3d_i::Prs3d_i() :
53 PrsObject_i(SALOMEDS::Study::_nil()),
54 myActorCollection(vtkActorCollection::New()),
55 myIsActiveSatate(true)
57 if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
58 myOffset[0] = myOffset[1] = myOffset[2] = 0;
59 myActorCollection->Delete();
63 //----------------------------------------------------------------------------
66 ::SameAs(const Prs3d_i* theOrigin)
68 if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
69 VISU::TSetModified aModified(this);
71 GetPipeLine()->SameAs(anOrigin->GetPipeLine());
72 anOrigin->GetOffset(myOffset);
77 //----------------------------------------------------------------------------
80 struct TInvokeSignalEvent: public SALOME_Event
82 typedef boost::signal0<void> TSignal;
83 const TSignal& mySignal;
85 TInvokeSignalEvent(const TSignal& theSignal):
98 //----------------------------------------------------------------------------
99 VISU::Prs3d_i::~Prs3d_i()
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();
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());
167 theResult->Register();
173 VISU::TSetModified aModified(this);
175 myResult = theResult;
176 myParamsTime.Modified();
179 //----------------------------------------------------------------------------
182 ::SetResultEntry(const std::string& theResultEntry)
184 SetCResult(VISU::GetResult(GetStudyDocument(), theResultEntry));
187 //----------------------------------------------------------------------------
192 if(VISU::Result_i* aResult = GetCResult())
193 return aResult->GetEntry();
197 //----------------------------------------------------------------------------
206 //----------------------------------------------------------------------------
209 ::SetResultObject(VISU::Result_ptr theResult)
211 SetCResult(dynamic_cast<VISU::Result_i*>(GetServant(theResult).in()));
215 //----------------------------------------------------------------------------
220 return GetCResult()->_this();
224 //----------------------------------------------------------------------------
227 ::SetMeshName(const char* theMeshName)
229 if(myMeshName == theMeshName)
232 VISU::TSetModified aModified(this);
234 myMeshName = theMeshName;
235 myParamsTime.Modified();
239 //----------------------------------------------------------------------------
244 return CORBA::string_dup(myMeshName.c_str());
248 //----------------------------------------------------------------------------
251 ::GetCMeshName() const
257 //----------------------------------------------------------------------------
262 unsigned long int aTime = myParamsTime.GetMTime();
263 if(IsPipeLineExists())
264 aTime = std::max(aTime, GetPipeLine()->GetMTime());
268 //----------------------------------------------------------------------------
273 return myIsActiveSatate;
276 //----------------------------------------------------------------------------
279 ::SetActiveState(bool theState)
281 myIsActiveSatate = theState;
284 //----------------------------------------------------------------------------
287 ::Restore(SALOMEDS::SObject_ptr theSObject,
288 const Storable::TRestoringMap& theMap)
290 SALOMEDS::Study_var aStudy = theSObject->GetStudy();
291 SetStudyDocument(aStudy);
293 bool anIsExists = false;
294 QString aResultEntry = VISU::Storable::FindValue(theMap,"myResultEntry", &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))
302 VISU::Result_var aResult = VISU::Result::_narrow(anObject);
303 if(CORBA::is_nil(aResult))
306 CORBA::String_var anEntry = aSObject->GetID();
307 aResultEntry = anEntry.in();
310 SetResultEntry(aResultEntry.toLatin1().data());
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();
323 //----------------------------------------------------------------------------
326 ::ToStream(std::ostringstream& theStr)
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] );
337 //----------------------------------------------------------------------------
338 SALOMEDS::SObject_var
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);
347 return SALOMEDS::SObject::_nil();
351 //----------------------------------------------------------------------------
356 if(GetMTime() < myUpdateTime.GetMTime())
359 if(MYDEBUG) MESSAGE("Prs3d_i::Update - this = "<<this);
362 ProcessVoidEvent(new TVoidMemFunEvent<VISU_PipeLine>
363 (GetPipeLine(), &VISU_PipeLine::Update));
364 myUpdateTime.Modified();
365 }catch(std::exception&){
368 throw std::runtime_error("Prs3d_i::Update >> unexpected exception was caught!!!");
373 //----------------------------------------------------------------------------
378 vtkMapper *aMapper = GetPipeLine()->GetMapper();
379 vtkDataSet *aDataSet = aMapper->GetInput();
381 throw std::runtime_error("There is no input data !!!");
384 static float eps = VTK_LARGE_FLOAT * 0.1 ;
385 if (!aDataSet->GetNumberOfCells())
386 throw std::runtime_error("There are no visible elements");
388 if (aDataSet->GetLength() > eps)
389 throw std::runtime_error("Diagonal of the actor is too large !!!");
393 //----------------------------------------------------------------------------
398 struct TEvent: public TInvokeSignalEvent
400 VISU::Prs3d_i* myRemovable;
402 TEvent(const TSignal& theSignal,
403 VISU::Prs3d_i* theRemovable):
404 TInvokeSignalEvent(theSignal),
405 myRemovable(theRemovable)
412 //TInvokeSignalEvent::Execute();
413 myRemovable->Destroy();
417 ProcessVoidEvent(new TEvent(myRemoveActorsFromRendererSignal, this));
421 //----------------------------------------------------------------------------
424 ::GetPipeLine() const
426 if(!myPipeLine.GetPointer())
427 throw std::runtime_error("VISU::Prs3d_i::myPipeLine == NULL !!!");
429 return myPipeLine.GetPointer();
432 //----------------------------------------------------------------------------
435 ::SetPipeLine(VISU_PipeLine* thePipeLine)
437 myPipeLine = thePipeLine;
439 thePipeLine->Delete();
442 //----------------------------------------------------------------------------
447 return myPipeLine.GetPointer() != NULL;
450 //----------------------------------------------------------------------------
455 return GetPipeLine();
458 //----------------------------------------------------------------------------
463 return GetPipeLine()->GetInput();
466 //----------------------------------------------------------------------------
467 Handle(SALOME_InteractiveObject)
472 myIO = new SALOME_InteractiveObject(GetActorEntry().c_str(), "VISU", GetName().c_str());
477 //----------------------------------------------------------------------------
486 //----------------------------------------------------------------------------
489 ::CreateActor(VISU_Actor* theActor)
492 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
494 Handle(SALOME_InteractiveObject) anIO = GetIO();
495 if(!anIO.IsNull() && anIO->hasEntry()){
496 theActor->setIO(anIO);
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();
511 theActor->SetFactory(this);
512 theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
514 myActorCollection->AddItem(theActor);
516 }catch(std::bad_alloc& ex){
517 throw std::runtime_error("CreateActor >> No enough memory");
519 } catch(std::exception&){
522 throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
526 //----------------------------------------------------------------------------
529 ::RemoveActor(VISU_ActorBase* theActor)
531 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
532 myActorCollection->RemoveItem(theActor);
535 //----------------------------------------------------------------------------
540 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
541 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
542 myActorCollection->RemoveAllItems();
545 //----------------------------------------------------------------------------
548 ::UpdateActor(VISU_ActorBase* theActor)
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());
562 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
565 ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
569 //----------------------------------------------------------------------------
573 ::RemoveAllClippingPlanes()
575 GetPipeLine()->RemoveAllClippingPlanes();
578 //----------------------------------------------------------------------------
581 ::AddClippingPlane(vtkPlane* thePlane)
583 return GetPipeLine()->AddClippingPlane(thePlane);
586 //----------------------------------------------------------------------------
589 ::GetNumberOfClippingPlanes() const
591 return GetPipeLine()->GetNumberOfClippingPlanes();
594 //----------------------------------------------------------------------------
597 GetClippingPlane(vtkIdType theID) const
599 return GetPipeLine()->GetClippingPlane(theID);
602 //----------------------------------------------------------------------------
603 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
605 GetPipeLine()->RemoveClippingPlane(theID);
608 //----------------------------------------------------------------------------
611 ::SetPlaneParam(vtkFloatingPointType theDir[3],
612 vtkFloatingPointType theDist,
615 GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
619 //----------------------------------------------------------------------------
622 ::GetBounds(vtkFloatingPointType aBounds[6])
624 GetPipeLine()->GetMapper()->GetBounds(aBounds);
627 //----------------------------------------------------------------------------
630 ::SetOffset(const CORBA::Float* theOffsets)
632 myOffset[0] = theOffsets[0];
633 myOffset[1] = theOffsets[1];
634 myOffset[2] = theOffsets[2];
635 myParamsTime.Modified();
638 //----------------------------------------------------------------------------
641 ::SetOffset(CORBA::Float theDx,
648 myParamsTime.Modified();
651 //----------------------------------------------------------------------------
654 ::GetOffset(CORBA::Float* theOffsets)
656 theOffsets[0] = myOffset[0];
657 theOffsets[1] = myOffset[1];
658 theOffsets[2] = myOffset[2];
661 //----------------------------------------------------------------------------
664 ::GetOffset(CORBA::Float& theDx,
674 //----------------------------------------------------------------------------
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;
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;
692 // Convert to mega bytes
693 return aSize / (1024.0 * 1024.0);
698 ::GetNumberOfActors()
700 return myActorCollection->GetNumberOfItems();