1 // VISU OBJECT : interactive object for VISU entities implementation
3 // Copyright (C) 2003 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
29 #include "VISU_Actor.h"
30 #include "VISU_PipeLine.hxx"
31 #include "VTKViewer_ShrinkFilter.h"
32 #include "VTKViewer_GeometryFilter.h"
38 #include <vtkProperty.h>
39 #include <vtkSmartPointer.h>
40 #include <vtkTextMapper.h>
41 #include <vtkTextActor.h>
42 #include <vtkProperty2D.h>
43 #include <vtkRenderer.h>
44 #include <vtkCellPicker.h>
46 #include <vtkPointPicker.h>
47 #include <vtkPoints.h>
48 #include <vtkInteractorStyle.h>
49 #include <vtkDataSet.h>
50 #include <vtkPolyData.h>
51 #include <vtkUnstructuredGrid.h>
52 #include <vtkPassThroughFilter.h>
54 #include <vtkShrinkFilter.h>
55 #include <vtkShrinkPolyData.h>
57 #include <vtkGeometryFilter.h>
58 #include <vtkObjectFactory.h>
60 #include <boost/bind.hpp>
62 #include "utilities.h"
64 #include "VISU_PipeLineUtils.hxx"
68 static int MYVTKDEBUG = 0;
71 static int MYDEBUG = 0;
73 static int MYDEBUG = 0;
76 //#define ENABLE_ANNOTATION
78 //----------------------------------------------------------------------------
79 //vtkStandardNewMacro(VISU_Actor);
81 //----------------------------------------------------------------------------
84 myIsVTKMapping(false),
88 myIsShrinkable(false),
89 myShrinkFilter(VTKViewer_ShrinkFilter::New()),
90 myAnnotationMapper(vtkTextMapper::New()),
91 myAnnotationActor(vtkTextActor::New())
93 if(MYDEBUG) MESSAGE("VISU_Actor::VISU_Actor - this = "<<this);
95 myShrinkFilter->Delete();
97 myStoreMapping = true;
99 myShrinkFilter->SetStoreMapping(true);
101 myAnnotationMapper->Delete();
102 myAnnotationActor->SetMapper(myAnnotationMapper.GetPointer());
104 myAnnotationActor->Delete();
105 myAnnotationActor->SetVisibility(0);
108 //----------------------------------------------------------------------------
111 ::DeepCopy(VISU_Actor *theActor)
113 highlight(theActor->isHighlighted());
114 SetRepresentation(theActor->GetRepresentation());
115 SetShrinkable(theActor->IsShrunkable());
116 SetShrinkFactor(theActor->GetShrinkFactor());
117 if(theActor->IsShrunk())
121 SetOpacity(theActor->GetOpacity());
122 SetLineWidth(theActor->GetLineWidth());
123 SetPosition(theActor->GetPosition());
127 //----------------------------------------------------------------------------
130 ::ShallowCopyPL(VISU_PipeLine* thePipeLine)
132 myPipeLine->ShallowCopy(thePipeLine, true);
133 GetMapper()->Update();
136 //----------------------------------------------------------------------------
140 if(MYDEBUG) MESSAGE("~VISU_Actor() - this = "<<this);
141 Superclass::SetProperty(NULL);
142 SetDebug(MYVTKDEBUG);
145 //----------------------------------------------------------------------------
148 ::setIO(const Handle(SALOME_InteractiveObject)& theIO)
150 Superclass::setIO(theIO);
151 myName = theIO->getName();
154 //----------------------------------------------------------------------------
157 ::SetPrs3d(VISU::Prs3d_i* thePrs3d)
169 //----------------------------------------------------------------------------
174 return myActorFactory;
179 ::SetFactory(VISU::TActorFactory* theActorFactory)
181 using namespace VISU;
183 if(myActorFactory == theActorFactory)
187 myDestroySignal.connect(boost::bind(&TActorFactory::RemoveActor,
191 myActorFactory = theActorFactory;
194 //----------------------------------------------------------------------------
197 ::UpdateFromFactory()
199 if(myUpdateFromFactoryTime.GetMTime() < myActorFactory->GetMTime()){
200 myUpdateFromFactoryTime.Modified();
201 myActorFactory->UpdateActor(this);
210 RemoveFromRender(GetRenderer());
213 //----------------------------------------------------------------------------
216 ::SetPipeLine(VISU_PipeLine* thePipeLine)
218 myPipeLine = thePipeLine;
220 if(vtkMapper *aMapper = myPipeLine->GetMapper()){
221 if(vtkDataSet *aDataSet = aMapper->GetInput()){
222 SetShrinkable(thePipeLine->IsShrinkable());
223 SetMapperInput(aDataSet);
234 return myPipeLine.GetPointer();
241 return GetPipeLine();
245 //----------------------------------------------------------------------------
248 ::SetRepresentation(int theMode)
250 Superclass::SetRepresentation(theMode);
251 if(myRepresentation == VTK_POINTS)
256 //----------------------------------------------------------------------------
263 if(vtkDataSet* aDataSet = myPassFilter[0]->GetOutput()){
264 myShrinkFilter->SetInput(aDataSet);
265 myPassFilter[1]->SetInput(myShrinkFilter->GetOutput());
276 if(vtkDataSet* aDataSet = myPassFilter[0]->GetOutput()){
277 myPassFilter[1]->SetInput(aDataSet);
278 myPassFilter[1]->Modified();
293 ::SetShrinkable(bool theIsShrinkable)
295 myIsShrinkable = theIsShrinkable;
302 return myIsShrinkable;
307 ::SetShrinkFactor(vtkFloatingPointType theValue)
309 myShrinkFilter->SetShrinkFactor(theValue);
317 return myShrinkFilter->GetShrinkFactor();
321 //----------------------------------------------------------------------------
324 ::SetOpacity(vtkFloatingPointType theValue)
326 GetProperty()->SetOpacity(theValue);
333 return GetProperty()->GetOpacity();
338 ::SetLineWidth(vtkFloatingPointType theLineWidth)
340 GetProperty()->SetLineWidth(theLineWidth);
347 return GetProperty()->GetLineWidth();
350 //==================================================================
351 // function: AddToRender
353 //==================================================================
356 ::AddToRender(vtkRenderer* theRenderer)
358 Superclass::AddToRender(theRenderer);
359 theRenderer->AddActor(myAnnotationActor.GetPointer());
362 //==================================================================
363 // function: RemoveFromRender
365 //==================================================================
368 ::RemoveFromRender(vtkRenderer* theRenderer)
370 theRenderer->RemoveActor(myAnnotationActor.GetPointer());
371 Superclass::RemoveFromRender(theRenderer);
372 myDestroySignal(this);
375 //----------------------------------------------------------------------------
378 ::SetVTKMapping(bool theIsVTKMapping)
380 myIsVTKMapping = theIsVTKMapping;
385 ::IsVTKMapping() const
387 return myIsVTKMapping;
390 //----------------------------------------------------------------------------
396 return Superclass::GetInput();
398 return GetCurrentPL()->GetOutput();
401 //----------------------------------------------------------------------------
406 static vtkFloatingPointType ERR_SIZE_CALC = 1.00;
407 vtkDataSet* aDataSet = GetMapper()->GetInput();
408 unsigned long int aSize = size_t(aDataSet->GetActualMemorySize() * 1024 * ERR_SIZE_CALC);
410 aDataSet = myGeomFilter->GetOutput();
411 aSize += aDataSet->GetActualMemorySize() * 1024;
414 aDataSet = myShrinkFilter->GetOutput();
415 aSize += aDataSet->GetActualMemorySize() * 1024;
421 //----------------------------------------------------------------------------
424 ::GetNodeObjId(vtkIdType theID)
427 return Superclass::GetNodeObjId(theID);
429 return VISU::GetNodeObjID(GetMapper()->GetInput(), theID);
434 ::GetNodeVTKID(vtkIdType theID)
439 return VISU::GetNodeVTKID(GetMapper()->GetInput(), theID);
442 vtkFloatingPointType*
444 ::GetNodeCoord(int theObjID)
447 return Superclass::GetNodeCoord(theObjID);
449 return VISU::GetNodeCoord(GetInput(), theObjID);
453 //----------------------------------------------------------------------------
456 ::GetElemObjId(vtkIdType theID)
459 return Superclass::GetElemObjId(theID);
461 return VISU::GetElemObjID(GetMapper()->GetInput(), theID);
466 ::GetElemVTKID(vtkIdType theID)
471 return VISU::GetElemVTKID(GetMapper()->GetInput(), theID);
476 ::GetElemCell(vtkIdType theObjID)
479 return Superclass::GetElemCell(theObjID);
481 return VISU::GetElemCell(GetInput(), theObjID);
485 //----------------------------------------------------------------------------
488 ::PreHighlight(vtkInteractorStyle* theInteractorStyle,
489 SVTK_SelectionEvent* theSelectionEvent,
492 bool aRet = Superclass::PreHighlight(theInteractorStyle,
495 #ifndef ENABLE_ANNOTATION
499 myAnnotationActor->SetVisibility(0);
501 switch(mySelectionMode){
503 vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
504 myCellPicker->Pick(theSelectionEvent->myX,
505 theSelectionEvent->myY,
509 if(myCellPicker->GetActor() != this)
512 vtkIdType aVTKId = myCellPicker->GetCellId();
513 if(aVTKId >= 0 && mySelector->IsValid(this,aVTKId,true) && hasIO()){
514 vtkIdType anObjId = GetElemObjId(aVTKId);
515 if(vtkCell* aCell = GetElemCell(anObjId)){
516 vtkPoints* aPts = aCell->GetPoints();
517 if(int aNbPts = aCell->GetNumberOfPoints()){
518 vtkFloatingPointType aCoord[3] = {0.0, 0.0, 0.0};
519 for(int i = 0; i < aNbPts; i++){
520 vtkFloatingPointType *aPntCoord = aPts->GetPoint(i);
521 aCoord[0] += aPntCoord[0];
522 aCoord[1] += aPntCoord[1];
523 aCoord[2] += aPntCoord[2];
525 // Display coordinates
526 vtkFloatingPointType aWorldCoord[4] = {aCoord[0]/aNbPts, aCoord[1]/aNbPts, aCoord[2]/aNbPts, 1.0};
527 aRenderer->SetWorldPoint(aWorldCoord);
528 aRenderer->WorldToDisplay();
529 vtkFloatingPointType aSelectionPoint[3];
530 aRenderer->GetDisplayPoint(aSelectionPoint);
531 myAnnotationActor->SetPosition(aSelectionPoint);
533 // To prepare the annotation text
534 std::ostringstream aStr;
535 aStr<<"Cell ID: "<< anObjId;
536 std::string aString = aStr.str();
537 myAnnotationMapper->SetInput(aString.c_str());
539 myAnnotationActor->SetVisibility(1);
547 vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
548 myPointPicker->Pick(theSelectionEvent->myX,
549 theSelectionEvent->myY,
553 if(myPointPicker->GetActor() != this)
556 vtkIdType aVtkId = myPointPicker->GetPointId();
557 if(aVtkId >= 0 && mySelector->IsValid(this,aVtkId,true) && hasIO()){
558 vtkIdType anObjId = GetNodeObjId( aVtkId );
559 if(vtkFloatingPointType* aCoord = GetNodeCoord(anObjId)){
560 // Display coordinates
561 vtkFloatingPointType aWorldCoord[4] = {aCoord[0], aCoord[1], aCoord[2], 1.0};
562 aRenderer->SetWorldPoint(aWorldCoord);
563 aRenderer->WorldToDisplay();
564 vtkFloatingPointType aSelectionPoint[3];
565 aRenderer->GetDisplayPoint(aSelectionPoint);
566 myAnnotationActor->SetPosition(aSelectionPoint);
568 // To prepare the annotation text
569 std::ostringstream aStr;
570 aStr<<"Node ID: "<< anObjId;
571 std::string aString = aStr.str();
572 myAnnotationMapper->SetInput(aString.c_str());
574 myAnnotationActor->SetVisibility(1);
580 case EdgeOfCellSelection: