1 // GEOM OBJECT : interactive object for Geometry entities visualization
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : GEOM_Actor.cxx
25 // Author : Christophe ATTANASIO
30 \class GEOM_Actor GEOM_Actor.h
31 \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer.
34 #include "GEOM_Actor.h"
36 #include <vtkObjectFactory.h>
37 #include <vtkPolyData.h>
38 #include <vtkPolyDataMapper.h>
39 #include <vtkPolyDataNormals.h>
41 #include <vtkTransform.h>
42 #include <vtkMatrix4x4.h>
45 #include <vtkProperty.h>
46 #include <vtkRenderer.h>
47 #include <vtkCamera.h>
49 // OpenCASCADE Includes
50 #include "GEOM_OCCReader.h"
51 #include <BRep_Tool.hxx>
55 //-------------------------------------------------------------
57 //-------------------------------------------------------------
60 GEOM_Actor* GEOM_Actor::New()
62 // First try to create the object from the vtkObjectFactory
63 vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_Actor");
66 return (GEOM_Actor*)ret;
68 // If the factory was unable to create the object, then create it here.
69 return new GEOM_Actor;
73 GEOM_Actor::GEOM_Actor()
75 this->Device = vtkActor::New();
77 this->WireframeMapper = NULL;
78 this->ShadingMapper = NULL;
80 this->ShadingProperty = NULL;
81 this->WireframeProperty = NULL;
89 this->HighlightProperty = NULL;
90 this->myIsHighlighted = false;
92 this->subshape = false;
93 this->myIsInfinite = false;
96 GEOM_Actor::~GEOM_Actor()
98 if (WireframeMapper != NULL)
99 WireframeMapper->Delete();
100 if (ShadingMapper != NULL)
101 ShadingMapper->Delete();
102 if (ShadingProperty != NULL)
103 ShadingProperty->Delete();
104 if (WireframeProperty != NULL)
105 WireframeProperty->Delete();
106 if (HighlightProperty != NULL)
107 HighlightProperty->Delete();
111 void GEOM_Actor::ShallowCopy(vtkProp *prop)
113 GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
116 this->setInputShape(f->getTopo(),f->getDeflection(),f->getDisplayMode());
117 this->setName( f->getName() );
119 this->setIO( f->getIO() );
120 this->ShadingMapper = NULL;
121 this->WireframeMapper = NULL;
125 this->ShadingMapper = NULL;
126 this->WireframeMapper = NULL;
130 this->SALOME_Actor::ShallowCopy(prop);
133 //-------------------------------------------------------------
135 //-------------------------------------------------------------
138 void GEOM_Actor::setDisplayMode(int thenewmode) {
139 myDisplayMode = thenewmode;
140 if ( thenewmode >=1 ) {
141 if ((myShape.ShapeType() == TopAbs_WIRE) ||
142 (myShape.ShapeType() == TopAbs_EDGE) ||
143 (myShape.ShapeType() == TopAbs_VERTEX)) {
145 CreateWireframeMapper();
149 CreateShadingMapper();
151 CreateWireframeMapper();
154 void GEOM_Actor::setDeflection(double adef) {
158 void GEOM_Actor::setInputShape(const TopoDS_Shape& aShape,double adef,int imode) {
161 setDisplayMode(imode);
164 //-------------------------------------------------------------
166 //-------------------------------------------------------------
168 const TopoDS_Shape& GEOM_Actor::getTopo() {
172 double GEOM_Actor::getDeflection() {
176 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) {
177 this->WireframeProperty = Prop;
180 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) {
181 this->ShadingProperty = Prop;
185 //-------------------------------------------------------------
186 // Mapper creating function
187 //-------------------------------------------------------------
188 void GEOM_Actor::CreateMapper(int theMode) {
189 this->myIsInfinite = (bool)myShape.Infinite();
190 if(myShape.ShapeType() == TopAbs_VERTEX) {
191 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(myShape));
192 this->SetPosition(aPnt.X(),aPnt.Y(),aPnt.Z());
194 GEOM_OCCReader* aread = GEOM_OCCReader::New();
195 aread->setTopo(myShape);
196 aread->setDisplayMode(theMode);
197 aread->GetOutput()->ReleaseDataFlagOn();
199 vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New();
201 aMapper->SetInput(aread->GetOutput());
203 vtkPolyDataNormals *normals = vtkPolyDataNormals::New();
204 normals->SetInput(aread->GetOutput());
205 aMapper->SetInput(normals->GetOutput());
208 this->SetMapper(theMode == 0? WireframeMapper = aMapper : ShadingMapper = aMapper);
211 void GEOM_Actor::CreateShadingMapper() {
216 void GEOM_Actor::CreateWireframeMapper() {
220 //-------------------------------------------------------------
222 //-------------------------------------------------------------
224 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
226 /* render the property */
227 if (!this->Property) {
228 // force creation of a property
230 this->Property->SetInterpolation(1);
231 this->Property->SetRepresentationToSurface();
232 this->Property->SetAmbient(0.3);
233 this->Property->SetAmbientColor(0.88,0.86,0.2);
234 this->Property->SetDiffuseColor(0.99,0.7,0.21);
235 this->Property->SetSpecularColor(0.99,0.98,0.83);
238 if(!myIsHighlighted) {
239 if ( myIsPreselected )
240 this->Property = PreviewProperty;
241 else if(myDisplayMode >= 1) {
243 this->Property = ShadingProperty;
246 this->Property = WireframeProperty;
251 this->Property->Render(this, ren);
252 if (this->BackfaceProperty) {
253 this->BackfaceProperty->BackfaceRender(this, ren);
254 this->Device->SetBackfaceProperty(this->BackfaceProperty);
256 this->Device->SetProperty(this->Property);
257 // Store information on time it takes to render.
258 // We might want to estimate time from the number of polygons in mapper.
259 if(myDisplayMode >= 1) {
260 if((myShape.ShapeType() == TopAbs_WIRE) ||
261 (myShape.ShapeType() == TopAbs_EDGE) ||
262 (myShape.ShapeType() == TopAbs_VERTEX)) {
264 if(WireframeMapper==NULL) CreateWireframeMapper();
269 if(ShadingMapper==NULL) CreateShadingMapper();
273 if(WireframeMapper==NULL) CreateWireframeMapper();
275 if(myShape.ShapeType() == TopAbs_VERTEX) {
277 //The parameter determine size of vertex actor relate to diagonal of RendererWindow
278 static vtkFloatingPointType delta = 0.01;
279 vtkFloatingPointType X1 = -1, Y1 = -1, Z1 = 0;
280 ren->ViewToWorld(X1,Y1,Z1);
281 vtkFloatingPointType X2 = +1, Y2 = +1, Z2 = 0;
282 ren->ViewToWorld(X2,Y2,Z2);
283 Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
284 this->SetScale(Z2*delta);
286 vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
287 this->GetMatrix(ren->GetActiveCamera(), aMatrix);
288 this->Device->SetUserMatrix(aMatrix);
289 this->Device->Render(ren,this->Mapper);
292 this->Device->Render(ren, this->Mapper);
293 if(WireframeMapper!=NULL) this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw();
294 else if(ShadingMapper!=NULL) this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw();
298 void GEOM_Actor::SubShapeOn()
302 void GEOM_Actor::SubShapeOff()
307 //-------------------------------------------------------------
309 //-------------------------------------------------------------
311 void GEOM_Actor::SetOpacity(vtkFloatingPointType opa)
313 //HighlightProperty->SetOpacity(opa);
314 SALOME_Actor::SetOpacity(opa);
315 ShadingProperty->SetOpacity(opa);
318 vtkFloatingPointType GEOM_Actor::GetOpacity() {
319 return ShadingProperty->GetOpacity();
322 //-------------------------------------------------------------
324 //-------------------------------------------------------------
325 void GEOM_Actor::SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) {
326 ShadingProperty->SetColor(r,g,b);
329 void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) {
330 vtkFloatingPointType color[3];
331 ShadingProperty->GetColor(color);
337 //-------------------------------------------------------------
339 //-------------------------------------------------------------
341 void GEOM_Actor::highlight(bool highlight) {
343 if(highlight && !myIsHighlighted) {
344 myIsHighlighted=true;
345 // build highlight property is necessary
346 if(HighlightProperty==NULL) {
347 HighlightProperty = vtkProperty::New();
348 HighlightProperty->SetAmbient(0.5);
349 HighlightProperty->SetDiffuse(0.3);
350 HighlightProperty->SetSpecular(0.2);
351 HighlightProperty->SetRepresentationToSurface();
352 HighlightProperty->SetAmbientColor(1, 1, 1);
353 HighlightProperty->SetDiffuseColor(1, 1, 1);
354 HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5);
357 this->Property = HighlightProperty;
360 else if (!highlight) {
361 if(myIsHighlighted) {
362 myIsHighlighted=false;
363 if(myDisplayMode==1) {
364 //unhilight in shading
365 this->Property = ShadingProperty;
368 //unhilight in wireframe
369 this->Property = WireframeProperty;
375 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop) {
376 this->HighlightProperty = Prop;
380 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *renWin)
382 vtkActor::ReleaseGraphicsResources(renWin);
384 // broadcast the message down to the individual LOD mappers
386 if(WireframeMapper) this->WireframeMapper->ReleaseGraphicsResources(renWin);
387 if(ShadingMapper) this->ShadingMapper->ReleaseGraphicsResources(renWin);
391 // Copy the follower's composite 4x4 matrix into the matrix provided.
392 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
395 double Rx[3], Ry[3], Rz[3], p1[3];
396 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
400 this->GetOrientation();
401 this->Transform->Push();
402 this->Transform->PostMultiply();
403 this->Transform->Identity();
405 // apply user defined matrix last if there is one
406 if (this->UserMatrix)
408 this->Transform->Concatenate(this->UserMatrix);
411 this->Transform->Translate(-this->Origin[0],
415 this->Transform->Scale(this->Scale[0],
420 this->Transform->RotateY(this->Orientation[1]);
421 this->Transform->RotateX(this->Orientation[0]);
422 this->Transform->RotateZ(this->Orientation[2]);
428 pos = theCam->GetPosition();
429 vup = theCam->GetViewUp();
431 if (theCam->GetParallelProjection())
433 theCam->GetDirectionOfProjection(Rz);
438 (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
439 (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
440 (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
441 for (i = 0; i < 3; i++)
443 Rz[i] = (pos[i] - this->Position[i])/distance;
447 vtkMath::Cross(vup,Rz,Rx);
448 vtkMath::Normalize(Rx);
449 vtkMath::Cross(Rz,Rx,Ry);
451 matrix->Element[0][0] = Rx[0];
452 matrix->Element[1][0] = Rx[1];
453 matrix->Element[2][0] = Rx[2];
454 matrix->Element[0][1] = Ry[0];
455 matrix->Element[1][1] = Ry[1];
456 matrix->Element[2][1] = Ry[2];
457 matrix->Element[0][2] = Rz[0];
458 matrix->Element[1][2] = Rz[1];
459 matrix->Element[2][2] = Rz[2];
461 this->Transform->Concatenate(matrix);
464 // translate to projection reference point PRP
465 // this is the camera's position blasted through
466 // the current matrix
467 p1[0] = this->Origin[0] + this->Position[0];
468 p1[1] = this->Origin[1] + this->Position[1];
469 p1[2] = this->Origin[2] + this->Position[2];
471 this->Transform->Translate(p1[0],p1[1],p1[2]);
472 this->Transform->GetMatrix(result);
475 this->Transform->Pop();