// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 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://ww // GEOM OBJECT : interactive object for Geometry entities visualization // File : GEOM_Actor.cxx // Author : Christophe ATTANASIO // Module : GEOM // $Header$ // /*! \class GEOM_Actor GEOM_Actor.h \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer. */ #include "GEOM_Actor.h" #include "GEOM_DeviceActor.h" #include "GEOM_VertexSource.h" #include "GEOM_EdgeSource.h" #include "GEOM_WireframeFace.h" #include "GEOM_ShadingFace.h" #include "SVTK_Actor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utilities.h" #include "SALOME_InteractiveObject.hxx" //vtkStandardNewMacro(GEOM_Actor); #ifndef MYDEBUG //#define MYDEBUG #endif GEOM_Actor::GEOM_Actor(): // myDisplayMode(eWireframe), myIsSelected(false), myVectorMode(false), myVertexActor(GEOM_DeviceActor::New(),true), myVertexSource(GEOM_VertexSource::New(),true), myIsolatedEdgeActor(GEOM_DeviceActor::New(),true), myIsolatedEdgeSource(GEOM_EdgeSource::New(),true), myOneFaceEdgeActor(GEOM_DeviceActor::New(),true), myOneFaceEdgeSource(GEOM_EdgeSource::New(),true), mySharedEdgeActor(GEOM_DeviceActor::New(),true), mySharedEdgeSource(GEOM_EdgeSource::New(),true), myWireframeFaceActor(GEOM_DeviceActor::New(),true), myWireframeFaceSource(GEOM_WireframeFace::New(),true), myShadingFaceActor(GEOM_DeviceActor::New(),true), myShadingFaceSource(GEOM_ShadingFace::New(),true), myHighlightActor(GEOM_DeviceActor::New(),true), myAppendFilter(vtkAppendPolyData::New(),true), myPolyDataMapper(vtkPolyDataMapper::New(),true), myHighlightProp(vtkProperty::New()), myPreHighlightProp(vtkProperty::New()), myShadingFaceProp(vtkProperty::New()), isOnlyVertex(false) { #ifdef MYDEBUG MESSAGE (this<< " GEOM_Actor::GEOM_Actor"); #endif myPolyDataMapper->SetInput(myAppendFilter->GetOutput()); vtkProperty* aProperty; myHighlightProp->SetAmbient(0.5); myHighlightProp->SetDiffuse(0.3); myHighlightProp->SetSpecular(0.2); myHighlightProp->SetRepresentationToSurface(); myHighlightProp->SetAmbientColor(1, 1, 1); myHighlightProp->SetDiffuseColor(1, 1, 1); myHighlightProp->SetSpecularColor(0.5, 0.5, 0.5); myHighlightProp->SetPointSize(SALOME_POINT_SIZE); myHighlightActor->SetProperty(myHighlightProp.GetPointer()); this->myHighlightActor->SetInput(myAppendFilter->GetOutput(),false); myPreHighlightProp->SetColor(0,1,1); myPreHighlightProp->SetPointSize(SALOME_POINT_SIZE+2); myPreHighlightProp->SetLineWidth(SALOME_LINE_WIDTH+1); myPreHighlightProp->SetRepresentationToWireframe(); myAppendFilter->AddInput(myVertexSource->GetOutput()); myVertexActor->SetInput(myVertexSource->GetOutput(),false); aProperty = myVertexActor->GetProperty(); aProperty->SetRepresentation(VTK_POINTS); aProperty->SetPointSize(3); aProperty->SetColor(1, 1, 0); myAppendFilter->AddInput(myIsolatedEdgeSource->GetOutput()); myIsolatedEdgeActor->SetInput(myIsolatedEdgeSource->GetOutput(),false); aProperty = myIsolatedEdgeActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); aProperty->SetColor(1, 0, 0); myAppendFilter->AddInput(myOneFaceEdgeSource->GetOutput()); myOneFaceEdgeActor->SetInput(myOneFaceEdgeSource->GetOutput(),false); aProperty = myOneFaceEdgeActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); aProperty->SetColor(0, 1, 0); myAppendFilter->AddInput(mySharedEdgeSource->GetOutput()); mySharedEdgeActor->SetInput(mySharedEdgeSource->GetOutput(),false); aProperty = mySharedEdgeActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); aProperty->SetColor(1, 1, 0); myAppendFilter->AddInput(myWireframeFaceSource->GetOutput()); myWireframeFaceActor->SetInput(myWireframeFaceSource->GetOutput(),false); aProperty = myWireframeFaceActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); aProperty->SetColor(0.5, 0.5, 0.5); myShadingFaceActor->SetInput(myShadingFaceSource->GetOutput(),true); myShadingFaceProp->SetRepresentation(VTK_SURFACE); myShadingFaceProp->SetInterpolationToGouraud(); myShadingFaceProp->SetAmbient(1.0); myShadingFaceProp->SetDiffuse(1.0); myShadingFaceProp->SetSpecular(0.4); myShadingFaceProp->SetAmbientColor(0.329412, 0.223529, 0.027451); myShadingFaceProp->SetDiffuseColor(0.780392, 0.568627, 0.113725); myShadingFaceProp->SetSpecularColor(0.992157, 0.941176, 0.807843); myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer()); // Toggle display mode setDisplayMode(0); // WIRE FRAME } GEOM_Actor::~GEOM_Actor() { #ifdef MYDEBUG MESSAGE (this<< " ~GEOM_Actor::GEOM_Actor"); #endif myHighlightProp->Delete(); myPreHighlightProp->Delete(); myShadingFaceProp->Delete(); } GEOM_Actor* GEOM_Actor:: New() { GEOM_Actor* anObject = new GEOM_Actor(); anObject->SetMapper(anObject->myPolyDataMapper.Get()); return anObject; } void Write(vtkPolyData* theDataSet, const char* theFileName){ vtkPolyDataWriter* aWriter = vtkPolyDataWriter::New(); MESSAGE ("Write - "<GetNumberOfPoints()<<"; "<GetNumberOfCells()); aWriter->SetInput(theDataSet); aWriter->SetFileName(theFileName); //aWriter->Write(); aWriter->Delete(); } void GEOM_Actor:: SetModified() { this->myVertexSource->Modified(); this->myIsolatedEdgeSource->Modified(); this->myOneFaceEdgeSource->Modified(); this->mySharedEdgeSource->Modified(); this->myWireframeFaceSource->Modified(); this->myShadingFaceSource->Modified(); } void GEOM_Actor:: SetMapper(vtkMapper* theMapper) { SALOME_Actor::SetMapper(theMapper); } void GEOM_Actor:: AddToRender(vtkRenderer* theRenderer) { //SALOME_Actor::AddToRender(theRenderer); theRenderer->AddActor(this); this->myHighlightActor->AddToRender(theRenderer); myShadingFaceActor->AddToRender(theRenderer); myWireframeFaceActor->AddToRender(theRenderer); mySharedEdgeActor->AddToRender(theRenderer); myOneFaceEdgeActor->AddToRender(theRenderer); myIsolatedEdgeActor->AddToRender(theRenderer); myVertexActor->AddToRender(theRenderer); } void GEOM_Actor:: RemoveFromRender(vtkRenderer* theRenderer) { //SALOME_Actor::RemoveFromRender(theRenderer); theRenderer->RemoveActor(this); myHighlightActor->RemoveFromRender(theRenderer); myShadingFaceActor->RemoveFromRender(theRenderer); myWireframeFaceActor->RemoveFromRender(theRenderer); mySharedEdgeActor->RemoveFromRender(theRenderer); myOneFaceEdgeActor->RemoveFromRender(theRenderer); myIsolatedEdgeActor->RemoveFromRender(theRenderer); myVertexActor->RemoveFromRender(theRenderer); SetSelected(false); SetVisibility(false); } void GEOM_Actor:: setDisplayMode(int theMode) { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::SetDisplayMode = "<myHighlightActor->GetProperty()->DeepCopy(Prop); } void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) { #ifdef MYDEBUG MESSAGE ( this << " GEOM_Actor::SetWireframeProperty" ); #endif // must be filled myWireframeFaceActor->SetProperty(Prop); } void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::SetShadingProperty" ); #endif myShadingFaceProp->DeepCopy(Prop); } void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *theMapper) { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::Render" ); #endif if(!GetVisibility()) return; /* render the property */ if (!this->Property) { // force creation of a property this->GetProperty(); this->Property->SetInterpolation(1); this->Property->SetRepresentationToSurface(); this->Property->SetAmbient(0.3); this->Property->SetAmbientColor(0.88,0.86,0.2); this->Property->SetDiffuseColor(0.99,0.7,0.21); this->Property->SetSpecularColor(0.99,0.98,0.83); } switch(myDisplayMode){ case 0://wireframe myPreHighlightProp->SetRepresentationToWireframe(); myHighlightProp->SetRepresentationToWireframe(); break; case 1://shading myPreHighlightProp->SetRepresentationToSurface(); myHighlightProp->SetRepresentationToSurface(); break; } if(!myIsSelected){ if(myIsPreselected){ this->myHighlightActor->SetProperty(myPreHighlightProp.GetPointer()); myShadingFaceActor->SetProperty(myPreHighlightProp.GetPointer()); } else { this->myHighlightActor->SetProperty(myShadingFaceProp.GetPointer()); myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer()); } } else{ this->myHighlightActor->SetProperty(myHighlightProp.GetPointer()); myShadingFaceActor->SetProperty(myHighlightProp.GetPointer()); } this->Property->Render(this, ren); if (this->BackfaceProperty) { this->BackfaceProperty->BackfaceRender(this, ren); this->Device->SetBackfaceProperty(this->BackfaceProperty); } this->Device->SetProperty(this->Property); /* if(myShape.ShapeType() == TopAbs_VERTEX) { if(ren){ //The parameter determine size of vertex actor relate to diagonal of RendererWindow static vtkFloatingPointType delta = 0.01; vtkFloatingPointType X1 = -1, Y1 = -1, Z1 = 0; ren->ViewToWorld(X1,Y1,Z1); vtkFloatingPointType X2 = +1, Y2 = +1, Z2 = 0; ren->ViewToWorld(X2,Y2,Z2); Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1)); this->SetScale(Z2*delta); } vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); this->GetMatrix(ren->GetActiveCamera(), aMatrix); this->Device->SetUserMatrix(aMatrix); this->Device->Render(ren,theMapper); aMatrix->Delete(); } else*/ this->Device->Render(ren, theMapper); } void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *) { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::ReleaseGraphicsResources" ); #endif } void GEOM_Actor::ShallowCopy(vtkProp *prop) { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::ShallowCopy" ); #endif GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop); if ( f != NULL ) { this->SetShape(f->getTopo(),f->GetDeflection(),f->GetIsRelative()); } // Now do superclass this->SALOME_Actor::ShallowCopy(prop); } const TopoDS_Shape& GEOM_Actor::getTopo() { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::getTopo" ); #endif return myShape; } void GEOM_Actor::setInputShape(const TopoDS_Shape& ashape, double adef1, int imode, bool isVector) { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::setInputShape" ); #endif } double GEOM_Actor::getDeflection() { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::getDeflection" ); #endif return (double) GetDeflection(); } double GEOM_Actor::isVector() { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::isVector" ); #endif return 0; } void GEOM_Actor::SubShapeOn() { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::SubShapeOn" ); #endif } void GEOM_Actor::SubShapeOff() { #ifdef MYDEBUG MESSAGE ( "GEOM_Actor::SubShapeOff" ); #endif } void GEOM_Actor::highlight(bool highlight) { #ifdef MYDEBUG MESSAGE ( this << " GEOM_Actor::highlight highlight="<SetOpacity(opa); myHighlightProp->SetOpacity(opa); myPreHighlightProp->SetOpacity(opa); myVertexActor->GetProperty()->SetOpacity(opa); } vtkFloatingPointType GEOM_Actor::GetOpacity() { // enk:tested OK return myShadingFaceProp->GetOpacity(); } void GEOM_Actor::SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) { // enk:tested OK myShadingFaceProp->SetColor(r,g,b); // shading color (Shading) myIsolatedEdgeActor->GetProperty()->SetColor(r,g,b); // standalone edge color (Wireframe) myVertexActor->GetProperty()->SetColor(r,g,b); // vertex actor (Shading/Wireframe) myOneFaceEdgeActor->GetProperty()->SetColor(r,g,b); // standalone face edge color (Wireframe) mySharedEdgeActor->GetProperty()->SetColor(r,g,b); // share edge color (Wireframe) } void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) { // enk:tested OK vtkFloatingPointType aRGB[3]; myShadingFaceProp->GetColor(aRGB); r = aRGB[0]; g = aRGB[1]; b = aRGB[2]; } bool GEOM_Actor::IsInfinitive() { return ((bool)myShape.Infinite() || isOnlyVertex); } /*! To map current selection to VTK representation */ void GEOM_Actor ::Highlight(bool theIsHighlight) { myIsSelected = theIsHighlight; #ifdef MYDEBUG MESSAGE ( this << " GEOM_Actor::Highlight myIsSelected="<getEntry() << endl; int nbio = mySelector->IObjectCount(); // cout << " nbio = " << nbio << endl; if( !mySelector->IsSelected( myIO ) ) { // printf ("!!!!!!!!!!!!!!!!\n"); SetPreSelected( true ); } } default: break; } } mySelectionMode = aSelectionMode; anIsChanged |= (anIsPreselected != myIsPreselected); SetVisibility(GetVisibility()); return anIsChanged; } /*! To process highlight (called from SVTK_InteractorStyle) */ bool GEOM_Actor ::Highlight(vtkInteractorStyle *theInteractorStyle, SVTK_SelectionEvent* theSelectionEvent, bool theIsHighlight) { // define the selection of object #ifdef MYDEBUG MESSAGE ( std::endl << this << " GEOM_Actor::Highlight (3) myIsSelected="<GetOrientation(); this->Transform->Push(); this->Transform->PostMultiply(); this->Transform->Identity(); // apply user defined matrix last if there is one if (this->UserMatrix) { this->Transform->Concatenate(this->UserMatrix); } this->Transform->Translate(-this->Origin[0], -this->Origin[1], -this->Origin[2]); // scale this->Transform->Scale(this->Scale[0], this->Scale[1], this->Scale[2]); // rotate this->Transform->RotateY(this->Orientation[1]); this->Transform->RotateX(this->Orientation[0]); this->Transform->RotateZ(this->Orientation[2]); if (theCam) { // do the rotation // first rotate y pos = theCam->GetPosition(); vup = theCam->GetViewUp(); if (theCam->GetParallelProjection()) { theCam->GetDirectionOfProjection(Rz); } else { distance = sqrt( (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) + (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) + (pos[2] - this->Position[2])*(pos[2] - this->Position[2])); for (i = 0; i < 3; i++) { Rz[i] = (pos[i] - this->Position[i])/distance; } } vtkMath::Cross(vup,Rz,Rx); vtkMath::Normalize(Rx); vtkMath::Cross(Rz,Rx,Ry); matrix->Element[0][0] = Rx[0]; matrix->Element[1][0] = Rx[1]; matrix->Element[2][0] = Rx[2]; matrix->Element[0][1] = Ry[0]; matrix->Element[1][1] = Ry[1]; matrix->Element[2][1] = Ry[2]; matrix->Element[0][2] = Rz[0]; matrix->Element[1][2] = Rz[1]; matrix->Element[2][2] = Rz[2]; this->Transform->Concatenate(matrix); } // translate to projection reference point PRP // this is the camera's position blasted through // the current matrix p1[0] = this->Origin[0] + this->Position[0]; p1[1] = this->Origin[1] + this->Position[1]; p1[2] = this->Origin[2] + this->Position[2]; this->Transform->Translate(p1[0],p1[1],p1[2]); this->Transform->GetMatrix(result); matrix->Delete(); this->Transform->Pop(); }