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"
36 #include <vtkActorCollection.h>
37 #include <vtkUnstructuredGrid.h>
38 #include <vtkDataSet.h>
39 #include <vtkMapper.h>
41 #include <boost/bind.hpp>
44 static int MYDEBUG = 1;
46 static int MYDEBUG = 0;
50 //----------------------------------------------------------------------------
51 VISU::Prs3d_i::Prs3d_i() :
52 PrsObject_i(SALOMEDS::Study::_nil()),
53 myActorCollection(vtkActorCollection::New()),
54 myIsActiveSatate(true)
56 if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
57 myOffset[0] = myOffset[1] = myOffset[2] = 0;
58 myActorCollection->Delete();
62 //----------------------------------------------------------------------------
65 ::SameAs(const Prs3d_i* theOrigin)
67 if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
68 VISU::TSetModified aModified(this);
70 GetPipeLine()->SameAs(anOrigin->GetPipeLine());
71 anOrigin->GetOffset(myOffset);
76 //----------------------------------------------------------------------------
79 struct TInvokeSignalEvent: public SALOME_Event
81 typedef boost::signal0<void> TSignal;
82 const TSignal& mySignal;
84 TInvokeSignalEvent(const TSignal& theSignal):
97 //----------------------------------------------------------------------------
98 VISU::Prs3d_i::~Prs3d_i()
100 if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
101 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
102 if(myResult) myResult->Destroy();
106 //----------------------------------------------------------------------------
109 ::SetInput(bool theReInit)
112 if(myMeshName != ""){
113 myPreviousResult = myResult;
114 myPreviousMeshName = myMeshName;
122 //----------------------------------------------------------------------------
127 SetCResult(myPreviousResult);
128 myMeshName = myPreviousMeshName;
132 //----------------------------------------------------------------------------
135 ::Apply(bool theReInit)
138 if(SetInput(theReInit)){
139 if(myActorCollection->GetNumberOfItems())
143 }catch(std::exception& exc){
144 INFOS("Follow exception was occured :\n"<<exc.what());
146 INFOS("Unknown exception was occured!");
153 //----------------------------------------------------------------------------
156 ::SetCResult(VISU::Result_i* theResult)
158 if(GetCResult() == theResult)
162 SetStudyDocument(theResult->GetStudyDocument());
163 theResult->Register();
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 Handle(SALOME_InteractiveObject) anIO = GetIO();
489 if(!anIO.IsNull() && anIO->hasEntry()){
490 theActor->setIO(anIO);
496 theActor->SetPrs3d(this);
497 theActor->SetShrinkFactor();
498 theActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
499 theActor->SetPipeLine(GetActorPipeLine());
500 if(theActor->GetPipeLine() != GetPipeLine()){
501 // To decrease actor'ss pipeline reference counter
502 theActor->GetPipeLine()->Delete();
505 theActor->SetFactory(this);
506 theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
508 myActorCollection->AddItem(theActor);
510 }catch(std::bad_alloc& ex){
511 throw std::runtime_error("CreateActor >> No enough memory");
513 } catch(std::exception&){
516 throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
520 //----------------------------------------------------------------------------
523 ::RemoveActor(VISU_ActorBase* theActor)
525 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
526 myActorCollection->RemoveItem(theActor);
529 //----------------------------------------------------------------------------
534 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
535 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
536 myActorCollection->RemoveAllItems();
539 //----------------------------------------------------------------------------
542 ::UpdateActor(VISU_ActorBase* theActor)
544 if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(theActor)){
545 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<anActor);
546 anActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
547 anActor->ShallowCopyPL(GetPipeLine());
555 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
558 ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
562 //----------------------------------------------------------------------------
566 ::RemoveAllClippingPlanes()
568 GetPipeLine()->RemoveAllClippingPlanes();
571 //----------------------------------------------------------------------------
574 ::AddClippingPlane(vtkPlane* thePlane)
576 return GetPipeLine()->AddClippingPlane(thePlane);
579 //----------------------------------------------------------------------------
582 ::GetNumberOfClippingPlanes() const
584 return GetPipeLine()->GetNumberOfClippingPlanes();
587 //----------------------------------------------------------------------------
590 GetClippingPlane(vtkIdType theID) const
592 return GetPipeLine()->GetClippingPlane(theID);
595 //----------------------------------------------------------------------------
596 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
598 GetPipeLine()->RemoveClippingPlane(theID);
601 //----------------------------------------------------------------------------
604 ::SetPlaneParam(vtkFloatingPointType theDir[3],
605 vtkFloatingPointType theDist,
608 GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
612 //----------------------------------------------------------------------------
615 ::GetBounds(vtkFloatingPointType aBounds[6])
617 GetPipeLine()->GetMapper()->GetBounds(aBounds);
620 //----------------------------------------------------------------------------
623 ::SetOffset(const CORBA::Float* theOffsets)
625 myOffset[0] = theOffsets[0];
626 myOffset[1] = theOffsets[1];
627 myOffset[2] = theOffsets[2];
628 myParamsTime.Modified();
631 //----------------------------------------------------------------------------
634 ::SetOffset(CORBA::Float theDx,
641 myParamsTime.Modified();
644 //----------------------------------------------------------------------------
647 ::GetOffset(CORBA::Float* theOffsets)
649 theOffsets[0] = myOffset[0];
650 theOffsets[1] = myOffset[1];
651 theOffsets[2] = myOffset[2];
654 //----------------------------------------------------------------------------
657 ::GetOffset(CORBA::Float& theDx,
667 //----------------------------------------------------------------------------
672 // To calculate memory used by VISU PipeLine
673 CORBA::Float aSize = GetPipeLine()->GetMemorySize();
674 //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; GetPipeLine = "<<aSize / (1024.0 * 1024.0)<<endl;
676 // To calculate memory used by VISU Actos
677 int anEnd = myActorCollection->GetNumberOfItems();
678 for(int anId = 0; anId < anEnd; anId++)
679 if(vtkObject* anObject = myActorCollection->GetItemAsObject(anId))
680 if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(anObject)){
681 aSize += anActor->GetMemorySize();
682 //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; anActor = "<<aSize / (1024.0 * 1024.0)<<endl;
685 // Convert to mega bytes
686 return aSize / (1024.0 * 1024.0);
691 ::GetNumberOfActors()
693 return myActorCollection->GetNumberOfItems();