1 // Copyright (C) 2007-2012 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 // SALOME OBJECT : implementation of interactive object visualization for OCC and VTK viewers
24 // File : SALOME_Actor.cxx
25 // Author : Nicolas REJNERI
28 \class SALOME_Actor SALOME_Actor.h
29 \brief Abstract class of SALOME Objects in VTK.
32 #include "VTKViewer_Actor.h"
34 #include "VTKViewer_Transform.h"
35 #include "VTKViewer_TransformFilter.h"
36 #include "VTKViewer_GeometryFilter.h"
40 #include <vtkPolyData.h>
41 #include <vtkObjectFactory.h>
42 #include <vtkDataSetMapper.h>
43 #include <vtkPolyDataMapper.h>
44 #include <vtkRenderer.h>
45 #include <vtkPassThroughFilter.h>
53 int VTKViewer_POINT_SIZE = 5;
54 int VTKViewer_LINE_WIDTH = 3;
57 vtkStandardNewMacro(VTKViewer_Actor);
65 myIsHighlighted(false),
66 myIsPreselected(false),
67 myRepresentation(VTKViewer::Representation::Surface),
69 myProperty(vtkProperty::New()),
70 PreviewProperty(NULL),
72 myIsResolveCoincidentTopology(true),
73 myStoreMapping(false),
74 myGeomFilter(VTKViewer_GeometryFilter::New()),
75 myTransformFilter(VTKViewer_TransformFilter::New())
77 vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
78 myPolygonOffsetUnits);
80 for(int i = 0; i < 6; i++)
81 myPassFilter.push_back(vtkPassThroughFilter::New());
90 SetPreviewProperty(NULL);
92 myGeomFilter->Delete();
94 myTransformFilter->Delete();
96 for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++)
98 myPassFilter[i]->Delete();
100 myProperty->Delete();
110 return myName.c_str();
115 \param theName - new name
119 ::setName(const char* theName)
125 To publish the actor an all its internal devices
129 ::AddToRender(vtkRenderer* theRenderer)
131 theRenderer->AddActor(this);
135 To remove the actor an all its internal devices
139 ::RemoveFromRender(vtkRenderer* theRenderer)
141 theRenderer->RemoveActor(this);
145 Used to obtain all dependent actors
149 ::GetChildActors(vtkActorCollection*)
153 Apply view transformation
154 \param theTransform - view transformation
158 ::SetTransform(VTKViewer_Transform* theTransform)
160 myTransformFilter->SetTransform(theTransform);
165 To insert some additional filters and then sets the given #vtkMapper
169 ::SetMapper(vtkMapper* theMapper)
171 InitPipeLine(theMapper);
179 ::InitPipeLine(vtkMapper* theMapper)
183 myPassFilter[ anId ]->SetInput( theMapper->GetInput() );
184 myPassFilter[ anId + 1]->SetInput( myPassFilter[ anId ]->GetOutput() );
187 myGeomFilter->SetStoreMapping( myStoreMapping );
188 myGeomFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
191 myPassFilter[ anId ]->SetInput( myGeomFilter->GetOutput() );
192 myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
195 myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
198 myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
199 myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
202 if(vtkDataSetMapper* aMapper = dynamic_cast<vtkDataSetMapper*>(theMapper)){
203 aMapper->SetInput(myPassFilter[anId]->GetOutput());
204 }else if(vtkPolyDataMapper* aMapper = dynamic_cast<vtkPolyDataMapper*>(theMapper)){
205 aMapper->SetInput(myPassFilter[anId]->GetPolyDataOutput());
208 Superclass::SetMapper(theMapper);
216 ::Render(vtkRenderer *ren, vtkMapper* m)
218 if(vtkDataSet* aDataSet = GetInput()){
219 static vtkFloatingPointType PERCENTS_OF_DETAILS = 0.50;
220 vtkIdType aNbOfPoints = vtkIdType(aDataSet->GetNumberOfPoints()*PERCENTS_OF_DETAILS);
222 SetNumberOfCloudPoints(aNbOfPoints);
225 if(myIsResolveCoincidentTopology){
226 int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
227 vtkFloatingPointType aFactor, aUnit;
228 vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
230 vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
231 vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
232 myPolygonOffsetUnits);
233 Superclass::Render(ren,m);
235 vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
236 vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
238 Superclass::Render(ren,m);
243 Set ResolveCoincidentTopology flag
244 \param theIsResolve - new flag value
248 ::SetResolveCoincidentTopology(bool theIsResolve)
250 myIsResolveCoincidentTopology = theIsResolve;
254 Set polygon offset parameters
255 \param factor, units - Opengl polygon offset parameters
259 ::SetPolygonOffsetParameters(vtkFloatingPointType factor,
260 vtkFloatingPointType units)
262 myPolygonOffsetFactor = factor;
263 myPolygonOffsetUnits = units;
267 Get polygon offset parameters
268 \param factor, units - Opengl polygon offset parameters
272 ::GetPolygonOffsetParameters(vtkFloatingPointType& factor,
273 vtkFloatingPointType& units)
275 factor = myPolygonOffsetFactor;
276 units = myPolygonOffsetUnits;
280 \return shrink factor
290 \return true if the actor is shrunkable
300 \return true if the actor is shrunk
310 Insert shrink filter into pipeline
318 Remove shrink filter from pipeline
326 Allows to get initial #vtkDataSet
332 return myPassFilter.front()->GetOutput();
336 To calculatate last modified time
342 unsigned long mTime = this->Superclass::GetMTime();
343 unsigned long time = myTransformFilter->GetMTime();
344 mTime = ( time > mTime ? time : mTime );
345 if(vtkDataSet *aDataSet = dynamic_cast<vtkDataSet*>(myPassFilter[0]->GetInput())){ // bad usage of GetInput
346 time = aDataSet->GetMTime();
347 mTime = ( time > mTime ? time : mTime );
353 Set representation (VTK_SURFACE, VTK_POINTS, VTK_WIREFRAME and so on)
354 param theMode - new mode
358 ::SetRepresentation(int theMode)
360 using namespace VTKViewer::Representation;
361 switch(myRepresentation){
364 case SurfaceWithEdges :
365 myProperty->SetAmbient(GetProperty()->GetAmbient());
366 myProperty->SetDiffuse(GetProperty()->GetDiffuse());
367 myProperty->SetSpecular(GetProperty()->GetSpecular());
374 case SurfaceWithEdges :
375 GetProperty()->SetAmbient(myProperty->GetAmbient());
376 GetProperty()->SetDiffuse(myProperty->GetDiffuse());
377 GetProperty()->SetSpecular(myProperty->GetSpecular());
380 GetProperty()->SetAmbient(1.0);
381 GetProperty()->SetDiffuse(0.0);
382 GetProperty()->SetSpecular(0.0);
387 myGeomFilter->SetInside(true);
388 myGeomFilter->SetWireframeMode(true);
389 GetProperty()->SetRepresentation(VTK_WIREFRAME);
392 GetProperty()->SetPointSize(VTKViewer_POINT_SIZE);
393 GetProperty()->SetRepresentation(theMode);
394 myGeomFilter->SetWireframeMode(false);
395 myGeomFilter->SetInside(false);
398 GetProperty()->SetRepresentation(theMode);
399 myGeomFilter->SetWireframeMode(true);
400 myGeomFilter->SetInside(false);
403 case SurfaceWithEdges :
404 GetProperty()->SetRepresentation(theMode);
405 myGeomFilter->SetWireframeMode(false);
406 myGeomFilter->SetInside(false);
410 myRepresentation = theMode;
414 \return current representation mode
418 ::GetRepresentation()
420 return myRepresentation;
424 Maps VTK index of a node to corresponding object index
428 ::GetNodeObjId(int theVtkID)
434 Get coordinates of a node for given object index
436 vtkFloatingPointType*
438 ::GetNodeCoord(int theObjID)
440 return GetInput()->GetPoint(theObjID);
444 Get corresponding #vtkCell for given object index
448 ::GetElemCell(int theObjID)
450 return GetInput()->GetCell(theObjID);
454 Maps VTK index of a cell to corresponding object index
458 ::GetElemObjId(int theVtkID)
465 \return object dimension. Virtual method should be redifined by derived classes
469 ::GetObjDimension( const int theObjId )
471 if ( vtkCell* aCell = GetElemCell(theObjId) )
472 return aCell->GetCellDimension();
477 Infinitive means actor without size (point for example),
478 which is not taken into account in calculation of boundaries of the scene
482 ::SetInfinitive(bool theIsInfinite)
484 myIsInfinite = theIsInfinite;
488 \return infinive flag
497 static vtkFloatingPointType MAX_DISTANCE = 0.9*VTK_LARGE_FLOAT;
498 vtkFloatingPointType aBounds[6];
500 for(int i = 0; i < 6; i++)
501 if(fabs(aBounds[i]) > MAX_DISTANCE)
504 static vtkFloatingPointType MIN_DISTANCE = 1.0/VTK_LARGE_FLOAT;
505 if(GetLength() < MIN_DISTANCE)
512 \return current bounding box
514 vtkFloatingPointType*
518 return Superclass::GetBounds();
523 \return current bounding box
527 ::GetBounds(vtkFloatingPointType theBounds[6])
529 Superclass::GetBounds(theBounds);
535 ::IsSetCamera() const
542 ::IsResizable() const
549 ::SetSize( const vtkFloatingPointType )
555 ::SetCamera( vtkCamera* )
561 ::SetOpacity(vtkFloatingPointType theOpacity)
563 myOpacity = theOpacity;
564 GetProperty()->SetOpacity(theOpacity);
580 ::SetColor(vtkFloatingPointType r,
581 vtkFloatingPointType g,
582 vtkFloatingPointType b)
584 GetProperty()->SetColor(r,g,b);
592 ::SetColor(const vtkFloatingPointType theRGB[3])
594 SetColor(theRGB[0],theRGB[1],theRGB[2]);
602 ::GetColor(vtkFloatingPointType& r,
603 vtkFloatingPointType& g,
604 vtkFloatingPointType& b)
606 vtkFloatingPointType aColor[3];
607 GetProperty()->GetColor(aColor);
619 ::SetMaterial(std::vector<vtkProperty*> theProps)
640 return myDisplayMode;
648 ::setDisplayMode(int theMode)
650 SetRepresentation(theMode + 1);
651 myDisplayMode = GetRepresentation() - 1;
656 \return true if the descendant of the VTKViewer_Actor will implement its own highlight or not
666 \return true if the VTKViewer_Actor is already highlighted
672 return myIsHighlighted;
676 \return true if the VTKViewer_Actor is already preselected
682 return myIsPreselected;
686 Set preselection mode
690 ::SetPreSelected(bool thePreselect)
692 myIsPreselected = thePreselect;
696 Just to update visibility of the highlight devices
700 ::highlight(bool theIsHighlight)
702 myIsHighlighted = theIsHighlight;
706 * On/Off representation 2D quadratic element as arked polygon
708 void VTKViewer_Actor::SetQuadraticArcMode(bool theFlag){
709 myGeomFilter->SetQuadraticArcMode(theFlag);
713 * Return true if 2D quadratic element displayed as arked polygon
715 bool VTKViewer_Actor::GetQuadraticArcMode() const{
716 return myGeomFilter->GetQuadraticArcMode();
719 * Set Max angle for representation 2D quadratic element as arked polygon
721 void VTKViewer_Actor::SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle){
722 myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
726 * Return Max angle of the representation 2D quadratic element as arked polygon
728 vtkFloatingPointType VTKViewer_Actor::GetQuadraticArcAngle() const{
729 return myGeomFilter->GetQuadraticArcAngle();
733 * Return pointer to the dataset, which used to calculation of the bounding box of the actor.
734 * By default it is the input dataset.
736 vtkDataSet* VTKViewer_Actor::GetHighlightedDataSet() {
742 vtkCxxSetObjectMacro(VTKViewer_Actor,PreviewProperty,vtkProperty);