-using namespace std;
-// File : VISU_Actor.cxx
-// Created : Wed Feb 20 18:04:42 CET 2002
-// Author : Laurent CORNABE with help of Nicolas REJNERI
-// Project : SALOME
-// Module : VISU
-// Copyright : PRINCIPIA RD
+// VISU OBJECT : interactive object for VISU entities implementation
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File :
+// Author :
+// Module : VISU
// $Header$
#include "VISU_Actor.h"
-#include "utilities.h"
+#include "VISU_PipeLine.hxx"
+#include "VTKViewer_ShrinkFilter.h"
+#include "VTKViewer_GeometryFilter.h"
+#include "VTKViewer_PassThroughFilter.h"
+#include <stdexcept>
+#include <sstream>
+
// VTK Includes
+#include <vtkProperty.h>
+#include <vtkSmartPointer.h>
+#include <vtkTextMapper.h>
+#include <vtkTextActor.h>
+#include <vtkProperty2D.h>
+#include <vtkRenderer.h>
+#include <vtkCellPicker.h>
+#include <vtkCell.h>
+#include <vtkPointPicker.h>
+#include <vtkPoints.h>
+#include <vtkInteractorStyle.h>
+#include <vtkDataSet.h>
+#include <vtkPolyData.h>
+#include <vtkUnstructuredGrid.h>
+
+#include <vtkShrinkFilter.h>
+#include <vtkShrinkPolyData.h>
+
+#include <vtkDataSetMapper.h>
+#include <vtkGeometryFilter.h>
#include <vtkObjectFactory.h>
-VISU_Actor* VISU_Actor::New(){
- vtkObject* ret = vtkObjectFactory::CreateInstance("VISU_Actor");
- if(ret) return (VISU_Actor*)ret;
- return new VISU_Actor;
-}
-VISU_Actor::VISU_Actor(){
- this->Device = vtkActor::New();
-
- this->EdgeDevice = vtkActor::New();
- EdgeDevice->VisibilityOff();
- EdgeDevice->PickableOff();
-
- this->DataSource = NULL;
- myScalarBar = NULL;
- this->myIO = NULL;
- this->myName = "";
- this->IsDefined = false;
- this->IsShrunk = false;
- this->IsShrinkable = false;
- this->VisuActorType = 0;
- this->Presentation = NULL;
- myHasScalarBar = false;
- this->HighlightProperty = NULL;
- this->ishighlighted = false;
- this->IsHighlighting = true;
- this->ResultAtNode = false;
- this->VectorComponent = -1;
- for (int i=0; i<6; i++)
- this->VABounds[i] = 0.;
- strcpy(this->FieldName,"");
-}
-
-
-VISU_Actor::~VISU_Actor()
-{
- this->EdgeDevice->Delete();
-}
-
-
-void VISU_Actor::setScalarBar(VISU_ScalarBarActor* theBar) {
- if (theBar) {
- myScalarBar = theBar;
- myHasScalarBar = true;
- } else {
- myScalarBar = NULL;
- myHasScalarBar = false;
+#include <boost/bind.hpp>
+
+#include "utilities.h"
+
+using namespace std;
+
+static int MYVTKDEBUG = 0;
+
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+#else
+static int MYDEBUG = 0;
+#endif
+
+//#define ENABLE_ANNOTATION
+
+//----------------------------------------------------------------------------
+vtkStandardNewMacro(VISU_Actor);
+
+//----------------------------------------------------------------------------
+VISU_Actor
+::VISU_Actor():
+ myIsVTKMapping(false),
+ myPrs3d(NULL),
+ myActorFactory(NULL),
+ myMapper(vtkDataSetMapper::New()),
+ myIsShrunk(false),
+ myIsShrinkable(false),
+ myShrinkFilter(VTKViewer_ShrinkFilter::New()),
+ myAnnotationMapper(vtkTextMapper::New()),
+ myAnnotationActor(vtkTextActor::New())
+{
+ if(MYDEBUG) MESSAGE("VISU_Actor::VISU_Actor - this = "<<this);
+
+ myMapper->Delete();
+ myShrinkFilter->Delete();
+
+ myStoreMapping = true;
+
+ myShrinkFilter->SetStoreMapping(true);
+
+ myAnnotationMapper->Delete();
+ myAnnotationActor->SetMapper(myAnnotationMapper.GetPointer());
+
+ myAnnotationActor->Delete();
+ myAnnotationActor->SetVisibility(0);
+}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::ShallowCopy(vtkProp *prop)
+{
+ VISU_Actor *anActor = VISU_Actor::SafeDownCast(prop);
+ if(anActor != NULL){
+ setName(anActor->getName());
+ if(anActor->hasIO()) setIO(anActor->getIO());
}
+ Superclass::ShallowCopy(prop);
}
+void
+VISU_Actor
+::ShallowCopyPL(VISU_PipeLine* thePipeLine)
+{
+ myPipeLine->ShallowCopy(thePipeLine);
-void VISU_Actor::setActor(vtkActor *Actor){
- this->Device=Actor;
+ vtkDataSet* aDatsSet = myMapper->GetInput();
+ GetMapper()->ShallowCopy(thePipeLine->GetMapper());
+
+ // To restore mapper input from pipeline
+ myMapper->SetInput(aDatsSet);
}
-void VISU_Actor::ShallowCopy(vtkProp *prop){
- VISU_Actor *f = VISU_Actor::SafeDownCast(prop);
- if ( f != NULL )
- {
- setName( f->getName() );
- if ( f->hasIO() )
- setIO( f->getIO() );
- }
- SALOME_Actor::ShallowCopy(prop);
-}
-
-void VISU_Actor::highlight(Standard_Boolean highlight) {
- if (this->IsHighlighting) {
- if(highlight && !ishighlighted) {
- ishighlighted=true;
- // build highlight property is necessary
- if(HighlightProperty==NULL) {
- HighlightProperty = vtkProperty::New();
- HighlightProperty->SetAmbient(0.5);
- HighlightProperty->SetDiffuse(0.3);
- HighlightProperty->SetSpecular(0.2);
- HighlightProperty->SetRepresentationToSurface();
- HighlightProperty->SetAmbientColor(1, 1, 1);
- HighlightProperty->SetDiffuseColor(1, 1, 1);
- HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5);
- }
- this->Property = HighlightProperty;
- }else if (!highlight) {
- if(ishighlighted) {
- ishighlighted=false;
+//----------------------------------------------------------------------------
+VISU_Actor
+::~VISU_Actor()
+{
+ if(MYDEBUG) MESSAGE("~VISU_Actor() - this = "<<this);
+ Superclass::SetProperty(NULL);
+ SetDebug(MYVTKDEBUG);
+}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::setIO(const Handle(SALOME_InteractiveObject)& theIO)
+{
+ Superclass::setIO(theIO);
+ myName = theIO->getName();
+}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::SetPrs3d(VISU::Prs3d_i* thePrs3d)
+{
+ myPrs3d = thePrs3d;
+}
+
+VISU::Prs3d_i*
+VISU_Actor
+::GetPrs3d()
+{
+ return myPrs3d;
+}
+
+//----------------------------------------------------------------------------
+VISU::TActorFactory*
+VISU_Actor
+::GetFactory()
+{
+ return myActorFactory;
+}
+
+void
+VISU_Actor
+::SetFactory(VISU::TActorFactory* theActorFactory)
+{
+ using namespace VISU;
+
+ if(myActorFactory == theActorFactory)
+ return;
+
+ if(theActorFactory)
+ myDestroySignal.connect(boost::bind(&TActorFactory::RemoveActor,
+ theActorFactory,
+ _1));
+
+ myActorFactory = theActorFactory;
+}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::UpdateFromFactory()
+{
+ myActorFactory->UpdateActor(this);
+ Update();
+}
+
+void
+VISU_Actor
+::RemoveFromRender()
+{
+ RemoveFromRender(GetRenderer());
+}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::SetMapperInput(vtkDataSet* theDataSet)
+{
+ myMapper->SetInput(theDataSet);
+ SetMapper(myMapper.GetPointer());
+}
+
+void
+VISU_Actor
+::SetPipeLine(VISU_PipeLine* thePipeLine)
+{
+ myPipeLine = thePipeLine;
+ if(thePipeLine){
+ if(vtkMapper *aMapper = myPipeLine->GetMapper()){
+ if(vtkDataSet *aDataSet = aMapper->GetInput()){
+ SetShrinkable(thePipeLine->IsShrinkable());
+
+ SetMapperInput(aDataSet);
}
}
}
+ this->Modified();
}
+VISU_PipeLine*
+VISU_Actor
+::GetPipeLine()
+{
+ return myPipeLine.GetPointer();
+}
-void VISU_Actor::setVABounds(const float bounds[6]){
- for (int i=0; i<6; i++)
- VABounds[i] = bounds[i];
+VISU_PipeLine*
+VISU_Actor
+::GetCurrentPL()
+{
+ return GetPipeLine();
}
-void VISU_Actor::getVABounds(float bounds[6]){
- for (int i=0; i<6; i++)
- bounds[i] = VABounds[i];
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::SetRepresentation(int theMode)
+{
+ Superclass::SetRepresentation(theMode);
+ if(myRepresentation == VTK_POINTS)
+ UnShrink();
}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::SetShrink()
+{
+ if(!myIsShrinkable)
+ return;
+ if(vtkDataSet* aDataSet = myPassFilter[0]->GetOutput()){
+ myShrinkFilter->SetInput(aDataSet);
+ myPassFilter[1]->SetInput(myShrinkFilter->GetOutput());
+ myIsShrunk = true;
+ }
+}
+
+void
+VISU_Actor
+::UnShrink()
+{
+ if(!myIsShrunk)
+ return;
+ if(vtkDataSet* aDataSet = myPassFilter[0]->GetOutput()){
+ myPassFilter[1]->SetInput(aDataSet);
+ myPassFilter[1]->Modified();
+ myIsShrunk = false;
+ Modified();
+ }
+}
+
+bool
+VISU_Actor
+::IsShrunk()
+{
+ return myIsShrunk;
+}
+
+void
+VISU_Actor
+::SetShrinkable(bool theIsShrinkable)
+{
+ myIsShrinkable = theIsShrinkable;
+}
+
+bool
+VISU_Actor
+::IsShrunkable()
+{
+ return myIsShrinkable;
+}
+
+void
+VISU_Actor
+::SetShrinkFactor(vtkFloatingPointType theValue)
+{
+ myShrinkFilter->SetShrinkFactor(theValue);
+ Modified();
+}
+
+vtkFloatingPointType
+VISU_Actor
+::GetShrinkFactor()
+{
+ return myShrinkFilter->GetShrinkFactor();
+}
+
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::SetOpacity(vtkFloatingPointType theValue)
+{
+ GetProperty()->SetOpacity(theValue);
+}
+
+vtkFloatingPointType
+VISU_Actor
+::GetOpacity()
+{
+ return GetProperty()->GetOpacity();
+}
+
+void
+VISU_Actor
+::SetLineWidth(vtkFloatingPointType theLineWidth)
+{
+ GetProperty()->SetLineWidth(theLineWidth);
+}
+
+vtkFloatingPointType
+VISU_Actor
+::GetLineWidth()
+{
+ return GetProperty()->GetLineWidth();
+}
+
+//==================================================================
+// function: AddToRender
+// purpose :
+//==================================================================
+void
+VISU_Actor
+::AddToRender(vtkRenderer* theRenderer)
+{
+ Superclass::AddToRender(theRenderer);
+ theRenderer->AddActor(myAnnotationActor.GetPointer());
+}
+
+//==================================================================
+// function: RemoveFromRender
+// purpose :
+//==================================================================
+void
+VISU_Actor
+::RemoveFromRender(vtkRenderer* theRenderer)
+{
+ theRenderer->RemoveActor(myAnnotationActor.GetPointer());
+ Superclass::RemoveFromRender(theRenderer);
+ myDestroySignal(this);
+}
+
+//----------------------------------------------------------------------------
+void
+VISU_Actor
+::SetVTKMapping(bool theIsVTKMapping)
+{
+ myIsVTKMapping = theIsVTKMapping;
+}
+
+bool
+VISU_Actor
+::IsVTKMapping() const
+{
+ return myIsVTKMapping;
+}
+
+//----------------------------------------------------------------------------
+vtkDataSet*
+VISU_Actor
+::GetInput()
+{
+ if(myIsVTKMapping)
+ return Superclass::GetInput();
+
+ return GetCurrentPL()->GetOutput();
+}
+
+//----------------------------------------------------------------------------
+vtkIdType
+VISU_Actor
+::GetNodeObjId(vtkIdType theID)
+{
+ if(myIsVTKMapping)
+ return Superclass::GetNodeObjId(theID);
+
+ vtkIdType anID = myGeomFilter->GetNodeObjId(theID);
+
+ if(myIsShrunk)
+ anID = myShrinkFilter->GetNodeObjId(anID);
+
+ return GetCurrentPL()->GetNodeObjID(anID);
+}
+
+vtkIdType
+VISU_Actor
+::GetNodeVTKID(vtkIdType theID)
+{
+ if(myIsVTKMapping)
+ return theID;
+
+ return GetCurrentPL()->GetNodeVTKID(theID);
+}
+
+vtkFloatingPointType*
+VISU_Actor
+::GetNodeCoord(int theObjID)
+{
+ if(myIsVTKMapping)
+ return Superclass::GetNodeCoord(theObjID);
+
+ return GetCurrentPL()->GetNodeCoord(theObjID);
+}
+
+
+//----------------------------------------------------------------------------
+vtkIdType
+VISU_Actor
+::GetElemObjId(vtkIdType theID)
+{
+ if(myIsVTKMapping)
+ return Superclass::GetElemObjId(theID);
+
+ vtkIdType anID = myGeomFilter->GetElemObjId(theID);
+
+ if(myIsShrunk)
+ anID = myShrinkFilter->GetElemObjId(anID);
+
+ return GetCurrentPL()->GetElemObjID(anID);
+}
+
+vtkIdType
+VISU_Actor
+::GetElemVTKID(vtkIdType theID)
+{
+ if(myIsVTKMapping)
+ return theID;
+
+ return GetCurrentPL()->GetElemVTKID(theID);
+}
+
+vtkCell*
+VISU_Actor
+::GetElemCell(vtkIdType theObjID)
+{
+ if(myIsVTKMapping)
+ return Superclass::GetElemCell(theObjID);
+
+ return GetCurrentPL()->GetElemCell(theObjID);
+}
+
+
+//----------------------------------------------------------------------------
+bool
+VISU_Actor
+::PreHighlight(vtkInteractorStyle* theInteractorStyle,
+ SVTK_SelectionEvent* theSelectionEvent,
+ bool theIsHighlight)
+{
+ bool aRet = Superclass::PreHighlight(theInteractorStyle,
+ theSelectionEvent,
+ theIsHighlight);
+#ifndef ENABLE_ANNOTATION
+ return aRet;
+#endif
+ //
+ myAnnotationActor->SetVisibility(0);
+ if(theIsHighlight){
+ switch(mySelectionMode){
+ case CellSelection:{
+ vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
+ myCellPicker->Pick(theSelectionEvent->myX,
+ theSelectionEvent->myY,
+ 0.0,
+ aRenderer);
+
+ if(myCellPicker->GetActor() != this)
+ return false;
+
+ vtkIdType aVTKId = myCellPicker->GetCellId();
+ if(aVTKId >= 0 && mySelector->IsValid(this,aVTKId,true) && hasIO()){
+ vtkIdType anObjId = GetElemObjId(aVTKId);
+ if(vtkCell* aCell = GetElemCell(anObjId)){
+ vtkPoints* aPts = aCell->GetPoints();
+ if(int aNbPts = aCell->GetNumberOfPoints()){
+ vtkFloatingPointType aCoord[3] = {0.0, 0.0, 0.0};
+ for(int i = 0; i < aNbPts; i++){
+ vtkFloatingPointType *aPntCoord = aPts->GetPoint(i);
+ aCoord[0] += aPntCoord[0];
+ aCoord[1] += aPntCoord[1];
+ aCoord[2] += aPntCoord[2];
+ }
+ // Display coordinates
+ vtkFloatingPointType aWorldCoord[4] = {aCoord[0]/aNbPts, aCoord[1]/aNbPts, aCoord[2]/aNbPts, 1.0};
+ aRenderer->SetWorldPoint(aWorldCoord);
+ aRenderer->WorldToDisplay();
+ vtkFloatingPointType aSelectionPoint[3];
+ aRenderer->GetDisplayPoint(aSelectionPoint);
+ myAnnotationActor->SetPosition(aSelectionPoint);
+ //
+ // To prepare the annotation text
+ std::ostringstream aStr;
+ aStr<<"Cell ID: "<< anObjId;
+ std::string aString = aStr.str();
+ myAnnotationMapper->SetInput(aString.c_str());
+
+ myAnnotationActor->SetVisibility(1);
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ case NodeSelection:{
+ vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
+ myPointPicker->Pick(theSelectionEvent->myX,
+ theSelectionEvent->myY,
+ 0.0,
+ aRenderer);
+
+ if(myPointPicker->GetActor() != this)
+ return false;
+
+ vtkIdType aVtkId = myPointPicker->GetPointId();
+ if(aVtkId >= 0 && mySelector->IsValid(this,aVtkId,true) && hasIO()){
+ vtkIdType anObjId = GetNodeObjId( aVtkId );
+ if(vtkFloatingPointType* aCoord = GetNodeCoord(anObjId)){
+ // Display coordinates
+ vtkFloatingPointType aWorldCoord[4] = {aCoord[0], aCoord[1], aCoord[2], 1.0};
+ aRenderer->SetWorldPoint(aWorldCoord);
+ aRenderer->WorldToDisplay();
+ vtkFloatingPointType aSelectionPoint[3];
+ aRenderer->GetDisplayPoint(aSelectionPoint);
+ myAnnotationActor->SetPosition(aSelectionPoint);
+ //
+ // To prepare the annotation text
+ std::ostringstream aStr;
+ aStr<<"Node ID: "<< anObjId;
+ std::string aString = aStr.str();
+ myAnnotationMapper->SetInput(aString.c_str());
+
+ myAnnotationActor->SetVisibility(1);
+ return true;
+ }
+ }
+ break;
+ }
+ case EdgeOfCellSelection:
+ break;
+ default:
+ break;
+ }
+ }
+
+ return aRet;
+}