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)
58 if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
59 myOffset[0] = myOffset[1] = myOffset[2] = 0;
60 myActorCollection->Delete();
64 //----------------------------------------------------------------------------
67 ::SameAs(const Prs3d_i* theOrigin)
69 if(Prs3d_i* anOrigin = const_cast<Prs3d_i*>(theOrigin)){
70 VISU::TSetModified aModified(this);
72 GetPipeLine()->SameAs(anOrigin->GetPipeLine());
73 anOrigin->GetOffset(myOffset);
78 //----------------------------------------------------------------------------
81 struct TInvokeSignalEvent: public SALOME_Event
83 typedef boost::signal0<void> TSignal;
84 const TSignal& mySignal;
86 TInvokeSignalEvent(const TSignal& theSignal):
99 //----------------------------------------------------------------------------
100 VISU::Prs3d_i::~Prs3d_i()
102 if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
103 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
107 //----------------------------------------------------------------------------
110 ::SetInput(bool theReInit)
113 if(myMeshName != ""){
114 myPreviousResult = myResult;
115 myPreviousMeshName = myMeshName;
123 //----------------------------------------------------------------------------
128 SetCResult(myPreviousResult);
129 myMeshName = myPreviousMeshName;
133 //----------------------------------------------------------------------------
136 ::Apply(bool theReInit)
139 if(SetInput(theReInit)){
140 if(myActorCollection->GetNumberOfItems())
144 }catch(std::exception& exc){
145 INFOS("Follow exception was occured :\n"<<exc.what());
147 INFOS("Unknown exception was occured!");
154 //----------------------------------------------------------------------------
157 ::SetCResult(VISU::Result_i* theResult)
159 if(GetCResult() == theResult)
163 SetStudyDocument(theResult->GetStudyDocument());
166 VISU::TSetModified aModified(this);
168 myResult = theResult;
169 myParamsTime.Modified();
172 //----------------------------------------------------------------------------
175 ::SetResultEntry(const std::string& theResultEntry)
177 SetCResult(VISU::GetResult(GetStudyDocument(), theResultEntry));
180 //----------------------------------------------------------------------------
185 if(VISU::Result_i* aResult = GetCResult())
186 return aResult->GetEntry();
190 //----------------------------------------------------------------------------
199 //----------------------------------------------------------------------------
202 ::SetResultObject(VISU::Result_ptr theResult)
204 SetCResult(dynamic_cast<VISU::Result_i*>(GetServant(theResult).in()));
208 //----------------------------------------------------------------------------
213 return GetCResult()->_this();
217 //----------------------------------------------------------------------------
220 ::SetMeshName(const char* theMeshName)
222 if(myMeshName == theMeshName)
225 VISU::TSetModified aModified(this);
227 myMeshName = theMeshName;
228 myParamsTime.Modified();
232 //----------------------------------------------------------------------------
237 return CORBA::string_dup(myMeshName.c_str());
241 //----------------------------------------------------------------------------
244 ::GetCMeshName() const
250 //----------------------------------------------------------------------------
255 unsigned long int aTime = myParamsTime.GetMTime();
256 if(IsPipeLineExists())
257 aTime = std::max(aTime, GetPipeLine()->GetMTime());
261 //----------------------------------------------------------------------------
266 return myIsActiveSatate;
269 //----------------------------------------------------------------------------
272 ::SetActiveState(bool theState)
274 myIsActiveSatate = theState;
277 //----------------------------------------------------------------------------
280 ::Restore(SALOMEDS::SObject_ptr theSObject,
281 const Storable::TRestoringMap& theMap)
283 SALOMEDS::Study_var aStudy = theSObject->GetStudy();
284 SetStudyDocument(aStudy);
286 bool anIsExists = false;
287 QString aResultEntry = VISU::Storable::FindValue(theMap,"myResultEntry", &anIsExists);
289 SALOMEDS::SObject_var aSObject = SALOMEDS::SObject::_duplicate(theSObject);
290 for(; aSObject->Depth() > 2 && !aResultEntry.isEmpty(); aSObject = aSObject->GetFather()){
291 CORBA::Object_var anObject = VISU::SObjectToObject(aSObject);
292 if(CORBA::is_nil(anObject))
295 VISU::Result_var aResult = VISU::Result::_narrow(anObject);
296 if(CORBA::is_nil(aResult))
299 CORBA::String_var anEntry = aSObject->GetID();
300 aResultEntry = anEntry.in();
303 SetResultEntry(aResultEntry.toLatin1().data());
307 SetMeshName((const char*)VISU::Storable::FindValue(theMap,"myMeshName").toLatin1());
308 SetName((const char*)VISU::Storable::FindValue(theMap,"myName").toLatin1(), false);
309 myOffset[0] = VISU::Storable::FindValue(theMap,"myOffset[0]").toFloat();
310 myOffset[1] = VISU::Storable::FindValue(theMap,"myOffset[1]").toFloat();
311 myOffset[2] = VISU::Storable::FindValue(theMap,"myOffset[2]").toFloat();
312 myParamsTime.Modified();
316 //----------------------------------------------------------------------------
319 ::ToStream(std::ostringstream& theStr)
321 Storable::DataToStream( theStr, "myResultEntry", GetResultEntry().c_str() );
322 Storable::DataToStream( theStr, "myMeshName", GetCMeshName().c_str() );
323 Storable::DataToStream( theStr, "myName", GetName().c_str() );
324 Storable::DataToStream( theStr, "myOffset[0]", myOffset[0] );
325 Storable::DataToStream( theStr, "myOffset[1]", myOffset[1] );
326 Storable::DataToStream( theStr, "myOffset[2]", myOffset[2] );
330 //----------------------------------------------------------------------------
331 SALOMEDS::SObject_var
335 const SALOMEDS::Study_var& aStudy = GetStudyDocument();
336 if(!CORBA::is_nil(aStudy.in())){
337 CORBA::String_var anIOR = GetID();
338 return aStudy->FindObjectIOR(anIOR);
340 return SALOMEDS::SObject::_nil();
344 //----------------------------------------------------------------------------
349 if(GetMTime() < myUpdateTime.GetMTime())
352 if(MYDEBUG) MESSAGE("Prs3d_i::Update - this = "<<this);
355 ProcessVoidEvent(new TVoidMemFunEvent<VISU_PipeLine>
356 (GetPipeLine(), &VISU_PipeLine::Update));
357 myUpdateTime.Modified();
358 }catch(std::exception&){
361 throw std::runtime_error("Prs3d_i::Update >> unexpected exception was caught!!!");
366 //----------------------------------------------------------------------------
371 vtkMapper *aMapper = GetPipeLine()->GetMapper();
372 vtkDataSet *aDataSet = aMapper->GetInput();
374 throw std::runtime_error("There is no input data !!!");
377 static float eps = VTK_LARGE_FLOAT * 0.1 ;
378 if (!aDataSet->GetNumberOfCells()) {
379 SUIT_MessageBox::warning( 0,
380 QObject::tr("WRN_VISU"),
381 QObject::tr("WRN_NO_VISIBLE_ELEMENTS"),
382 QObject::tr("BUT_OK"));
386 if (aDataSet->GetLength() > eps)
387 throw std::runtime_error("Diagonal of the actor is too large !!!");
391 //----------------------------------------------------------------------------
396 struct TEvent: public TInvokeSignalEvent
398 VISU::Prs3d_i* myRemovable;
400 TEvent(const TSignal& theSignal,
401 VISU::Prs3d_i* theRemovable):
402 TInvokeSignalEvent(theSignal),
403 myRemovable(theRemovable)
410 //TInvokeSignalEvent::Execute();
411 myRemovable->Destroy();
415 ProcessVoidEvent(new TEvent(myRemoveActorsFromRendererSignal, this));
419 //----------------------------------------------------------------------------
422 ::GetPipeLine() const
424 if(!myPipeLine.GetPointer())
425 throw std::runtime_error("VISU::Prs3d_i::myPipeLine == NULL !!!");
427 return myPipeLine.GetPointer();
430 //----------------------------------------------------------------------------
433 ::SetPipeLine(VISU_PipeLine* thePipeLine)
435 myPipeLine = thePipeLine;
437 thePipeLine->Delete();
440 //----------------------------------------------------------------------------
445 return myPipeLine.GetPointer() != NULL;
448 //----------------------------------------------------------------------------
453 return GetPipeLine();
456 //----------------------------------------------------------------------------
461 return GetPipeLine()->GetInput();
464 //----------------------------------------------------------------------------
465 Handle(SALOME_InteractiveObject)
470 myIO = new SALOME_InteractiveObject(GetActorEntry().c_str(), "VISU", GetName().c_str());
475 //----------------------------------------------------------------------------
484 //----------------------------------------------------------------------------
487 ::CreateActor(VISU_Actor* theActor)
490 SUIT_ResourceMgr* aResourceMgr = VISU::GetResourceMgr();
492 Handle(SALOME_InteractiveObject) anIO = GetIO();
493 if(!anIO.IsNull() && anIO->hasEntry()){
494 theActor->setIO(anIO);
500 theActor->SetPrs3d(this);
501 theActor->SetShrinkFactor(aResourceMgr->integerValue("VISU", "shrink_factor", 80)/100.);
502 theActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
503 theActor->SetPipeLine(GetActorPipeLine());
504 if(theActor->GetPipeLine() != GetPipeLine()){
505 // To decrease actor'ss pipeline reference counter
506 theActor->GetPipeLine()->Delete();
509 theActor->SetFactory(this);
510 theActor->ConnectToFactory(myUpdateActorsSignal, myRemoveActorsFromRendererSignal);
512 myActorCollection->AddItem(theActor);
514 }catch(std::bad_alloc& ex){
515 throw std::runtime_error("CreateActor >> No enough memory");
517 } catch(std::exception&){
520 throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
524 //----------------------------------------------------------------------------
527 ::RemoveActor(VISU_ActorBase* theActor)
529 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor<<"; "<<theActor->GetReferenceCount());
530 myActorCollection->RemoveItem(theActor);
533 //----------------------------------------------------------------------------
538 if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
539 ProcessVoidEvent(new TInvokeSignalEvent(myRemoveActorsFromRendererSignal));
540 myActorCollection->RemoveAllItems();
543 //----------------------------------------------------------------------------
546 ::UpdateActor(VISU_ActorBase* theActor)
548 if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(theActor)){
549 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<anActor);
550 anActor->SetPosition(myOffset[0],myOffset[1],myOffset[2]);
551 anActor->ShallowCopyPL(GetPipeLine());
552 anActor->highlight(anActor->isHighlighted());
560 if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
563 ProcessVoidEvent(new TInvokeSignalEvent(myUpdateActorsSignal));
567 //----------------------------------------------------------------------------
571 ::RemoveAllClippingPlanes()
573 GetPipeLine()->RemoveAllClippingPlanes();
576 //----------------------------------------------------------------------------
579 ::AddClippingPlane(vtkPlane* thePlane)
581 return GetPipeLine()->AddClippingPlane(thePlane);
584 //----------------------------------------------------------------------------
587 ::GetNumberOfClippingPlanes() const
589 return GetPipeLine()->GetNumberOfClippingPlanes();
592 //----------------------------------------------------------------------------
595 GetClippingPlane(vtkIdType theID) const
597 return GetPipeLine()->GetClippingPlane(theID);
600 //----------------------------------------------------------------------------
601 void VISU::Prs3d_i::RemoveClippingPlane(vtkIdType theID)
603 GetPipeLine()->RemoveClippingPlane(theID);
606 //----------------------------------------------------------------------------
609 ::SetPlaneParam(vtkFloatingPointType theDir[3],
610 vtkFloatingPointType theDist,
613 GetPipeLine()->SetPlaneParam(theDir, theDist, thePlane);
617 //----------------------------------------------------------------------------
620 ::GetBounds(vtkFloatingPointType aBounds[6])
622 GetPipeLine()->GetMapper()->GetBounds(aBounds);
625 //----------------------------------------------------------------------------
628 ::SetOffset(const CORBA::Float* theOffsets)
630 myOffset[0] = theOffsets[0];
631 myOffset[1] = theOffsets[1];
632 myOffset[2] = theOffsets[2];
633 myParamsTime.Modified();
636 //----------------------------------------------------------------------------
639 ::SetOffset(CORBA::Float theDx,
646 myParamsTime.Modified();
649 //----------------------------------------------------------------------------
652 ::GetOffset(CORBA::Float* theOffsets)
654 theOffsets[0] = myOffset[0];
655 theOffsets[1] = myOffset[1];
656 theOffsets[2] = myOffset[2];
659 //----------------------------------------------------------------------------
662 ::GetOffset(CORBA::Float& theDx,
672 //----------------------------------------------------------------------------
677 // To calculate memory used by VISU PipeLine
678 CORBA::Float aSize = GetPipeLine()->GetMemorySize();
679 //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; GetPipeLine = "<<aSize / (1024.0 * 1024.0)<<endl;
681 // To calculate memory used by VISU Actos
682 int anEnd = myActorCollection->GetNumberOfItems();
683 for(int anId = 0; anId < anEnd; anId++)
684 if(vtkObject* anObject = myActorCollection->GetItemAsObject(anId))
685 if(VISU_Actor* anActor = dynamic_cast<VISU_Actor*>(anObject)){
686 aSize += anActor->GetMemorySize();
687 //cout<<"Prs3d_i::GetMemorySize - "<<this<<"; anActor = "<<aSize / (1024.0 * 1024.0)<<endl;
690 // Convert to mega bytes
691 return aSize / (1024.0 * 1024.0);
696 ::GetNumberOfActors()
698 return myActorCollection->GetNumberOfItems();