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 <vtkRenderer.h>
46 #include <vtkCamera.h>
48 // OpenCASCADE Includes
49 #include "GEOM_OCCReader.h"
50 #include <BRep_Tool.hxx>
54 //-------------------------------------------------------------
56 //-------------------------------------------------------------
59 GEOM_Actor* GEOM_Actor::New()
61 // First try to create the object from the vtkObjectFactory
62 vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_Actor");
65 return (GEOM_Actor*)ret;
67 // If the factory was unable to create the object, then create it here.
68 return new GEOM_Actor;
72 GEOM_Actor::GEOM_Actor()
74 this->Device = vtkActor::New();
76 this->WireframeMapper = NULL;
77 this->ShadingMapper = NULL;
79 this->ShadingProperty = NULL;
80 this->WireframeProperty = NULL;
88 this->HighlightProperty = NULL;
89 this->myIsHighlighted = false;
91 this->subshape = false;
92 this->myIsInfinite = false;
95 GEOM_Actor::~GEOM_Actor()
97 if (WireframeMapper != NULL)
98 WireframeMapper->Delete();
99 if (ShadingMapper != NULL)
100 ShadingMapper->Delete();
101 if (ShadingProperty != NULL)
102 ShadingProperty->Delete();
103 if (WireframeProperty != NULL)
104 WireframeProperty->Delete();
105 if (HighlightProperty != NULL)
106 HighlightProperty->Delete();
110 void GEOM_Actor::ShallowCopy(vtkProp *prop)
112 GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
115 this->setInputShape(f->getTopo(),f->getDeflection(),f->getDisplayMode());
116 this->setName( f->getName() );
118 this->setIO( f->getIO() );
119 this->ShadingMapper = NULL;
120 this->WireframeMapper = NULL;
124 this->ShadingMapper = NULL;
125 this->WireframeMapper = NULL;
129 this->SALOME_Actor::ShallowCopy(prop);
132 //-------------------------------------------------------------
134 //-------------------------------------------------------------
137 void GEOM_Actor::setDisplayMode(int thenewmode) {
138 myDisplayMode = thenewmode;
139 if ( thenewmode >=1 ) {
140 if ((myShape.ShapeType() == TopAbs_WIRE) ||
141 (myShape.ShapeType() == TopAbs_EDGE) ||
142 (myShape.ShapeType() == TopAbs_VERTEX)) {
144 CreateWireframeMapper();
148 CreateShadingMapper();
150 CreateWireframeMapper();
153 void GEOM_Actor::setDeflection(double adef) {
157 void GEOM_Actor::setInputShape(const TopoDS_Shape& aShape,double adef,int imode) {
160 setDisplayMode(imode);
163 //-------------------------------------------------------------
165 //-------------------------------------------------------------
167 const TopoDS_Shape& GEOM_Actor::getTopo() {
171 double GEOM_Actor::getDeflection() {
175 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) {
176 this->WireframeProperty = Prop;
179 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) {
180 this->ShadingProperty = Prop;
184 //-------------------------------------------------------------
185 // Mapper creating function
186 //-------------------------------------------------------------
187 void GEOM_Actor::CreateMapper(int theMode) {
188 this->myIsInfinite = myShape.Infinite();
189 if(myShape.ShapeType() == TopAbs_VERTEX) {
190 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(myShape));
191 this->SetPosition(aPnt.X(),aPnt.Y(),aPnt.Z());
193 GEOM_OCCReader* aread = GEOM_OCCReader::New();
194 aread->setTopo(myShape);
195 aread->setDisplayMode(theMode);
196 aread->GetOutput()->ReleaseDataFlagOn();
198 vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New();
200 aMapper->SetInput(aread->GetOutput());
202 vtkPolyDataNormals *normals = vtkPolyDataNormals::New();
203 normals->SetInput(aread->GetOutput());
204 aMapper->SetInput(normals->GetOutput());
207 this->SetMapper(theMode == 0? WireframeMapper = aMapper : ShadingMapper = aMapper);
210 void GEOM_Actor::CreateShadingMapper() {
215 void GEOM_Actor::CreateWireframeMapper() {
219 //-------------------------------------------------------------
221 //-------------------------------------------------------------
223 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
225 /* render the property */
226 if (!this->Property) {
227 // force creation of a property
229 this->Property->SetInterpolation(1);
230 this->Property->SetRepresentationToSurface();
231 this->Property->SetAmbient(0.3);
232 this->Property->SetAmbientColor(0.88,0.86,0.2);
233 this->Property->SetDiffuseColor(0.99,0.7,0.21);
234 this->Property->SetSpecularColor(0.99,0.98,0.83);
237 if(!myIsHighlighted) {
238 if ( myIsPreselected )
239 this->Property = PreviewProperty;
240 else if(myDisplayMode >= 1) {
242 this->Property = ShadingProperty;
245 this->Property = WireframeProperty;
250 this->Property->Render(this, ren);
251 if (this->BackfaceProperty) {
252 this->BackfaceProperty->BackfaceRender(this, ren);
253 this->Device->SetBackfaceProperty(this->BackfaceProperty);
255 this->Device->SetProperty(this->Property);
256 // Store information on time it takes to render.
257 // We might want to estimate time from the number of polygons in mapper.
258 if(myDisplayMode >= 1) {
259 if((myShape.ShapeType() == TopAbs_WIRE) ||
260 (myShape.ShapeType() == TopAbs_EDGE) ||
261 (myShape.ShapeType() == TopAbs_VERTEX)) {
263 if(WireframeMapper==NULL) CreateWireframeMapper();
268 if(ShadingMapper==NULL) CreateShadingMapper();
272 if(WireframeMapper==NULL) CreateWireframeMapper();
274 if(myShape.ShapeType() == TopAbs_VERTEX) {
276 //The parameter determine size of vertex actor relate to diagonal of RendererWindow
277 static float delta = 0.01;
278 float X1 = -1, Y1 = -1, Z1 = 0;
279 ren->ViewToWorld(X1,Y1,Z1);
280 float X2 = +1, Y2 = +1, Z2 = 0;
281 ren->ViewToWorld(X2,Y2,Z2);
282 Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
283 this->SetScale(Z2*delta);
285 vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
286 this->GetMatrix(ren->GetActiveCamera(), aMatrix);
287 this->Device->SetUserMatrix(aMatrix);
288 this->Device->Render(ren,this->Mapper);
291 this->Device->Render(ren, this->Mapper);
292 if(WireframeMapper!=NULL) this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw();
293 else if(ShadingMapper!=NULL) this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw();
297 void GEOM_Actor::SubShapeOn()
301 void GEOM_Actor::SubShapeOff()
306 //-------------------------------------------------------------
308 //-------------------------------------------------------------
310 void GEOM_Actor::SetOpacity(float opa)
312 //HighlightProperty->SetOpacity(opa);
313 SALOME_Actor::SetOpacity(opa);
314 ShadingProperty->SetOpacity(opa);
317 float GEOM_Actor::GetOpacity() {
318 return ShadingProperty->GetOpacity();
321 //-------------------------------------------------------------
323 //-------------------------------------------------------------
324 void GEOM_Actor::SetColor(float r,float g,float b) {
325 ShadingProperty->SetColor(r,g,b);
328 void GEOM_Actor::GetColor(float& r,float& g,float& b) {
330 ShadingProperty->GetColor(color);
336 //-------------------------------------------------------------
338 //-------------------------------------------------------------
340 void GEOM_Actor::highlight(bool highlight) {
342 if(highlight && !myIsHighlighted) {
343 myIsHighlighted=true;
344 // build highlight property is necessary
345 if(HighlightProperty==NULL) {
346 HighlightProperty = vtkProperty::New();
347 HighlightProperty->SetAmbient(0.5);
348 HighlightProperty->SetDiffuse(0.3);
349 HighlightProperty->SetSpecular(0.2);
350 HighlightProperty->SetRepresentationToSurface();
351 HighlightProperty->SetAmbientColor(1, 1, 1);
352 HighlightProperty->SetDiffuseColor(1, 1, 1);
353 HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5);
356 this->Property = HighlightProperty;
359 else if (!highlight) {
360 if(myIsHighlighted) {
361 myIsHighlighted=false;
362 if(myDisplayMode==1) {
363 //unhilight in shading
364 this->Property = ShadingProperty;
367 //unhilight in wireframe
368 this->Property = WireframeProperty;
374 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop) {
375 this->HighlightProperty = Prop;
379 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *renWin)
381 vtkActor::ReleaseGraphicsResources(renWin);
383 // broadcast the message down to the individual LOD mappers
385 if(WireframeMapper) this->WireframeMapper->ReleaseGraphicsResources(renWin);
386 if(ShadingMapper) this->ShadingMapper->ReleaseGraphicsResources(renWin);
390 // Copy the follower's composite 4x4 matrix into the matrix provided.
391 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
394 double Rx[3], Ry[3], Rz[3], p1[3];
395 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
399 this->GetOrientation();
400 this->Transform->Push();
401 this->Transform->PostMultiply();
402 this->Transform->Identity();
404 // apply user defined matrix last if there is one
405 if (this->UserMatrix)
407 this->Transform->Concatenate(this->UserMatrix);
410 this->Transform->Translate(-this->Origin[0],
414 this->Transform->Scale(this->Scale[0],
419 this->Transform->RotateY(this->Orientation[1]);
420 this->Transform->RotateX(this->Orientation[0]);
421 this->Transform->RotateZ(this->Orientation[2]);
427 pos = theCam->GetPosition();
428 vup = theCam->GetViewUp();
430 if (theCam->GetParallelProjection())
432 theCam->GetDirectionOfProjection(Rz);
437 (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
438 (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
439 (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
440 for (i = 0; i < 3; i++)
442 Rz[i] = (pos[i] - this->Position[i])/distance;
446 vtkMath::Cross(vup,Rz,Rx);
447 vtkMath::Normalize(Rx);
448 vtkMath::Cross(Rz,Rx,Ry);
450 matrix->Element[0][0] = Rx[0];
451 matrix->Element[1][0] = Rx[1];
452 matrix->Element[2][0] = Rx[2];
453 matrix->Element[0][1] = Ry[0];
454 matrix->Element[1][1] = Ry[1];
455 matrix->Element[2][1] = Ry[2];
456 matrix->Element[0][2] = Rz[0];
457 matrix->Element[1][2] = Rz[1];
458 matrix->Element[2][2] = Rz[2];
460 this->Transform->Concatenate(matrix);
463 // translate to projection reference point PRP
464 // this is the camera's position blasted through
465 // the current matrix
466 p1[0] = this->Origin[0] + this->Position[0];
467 p1[1] = this->Origin[1] + this->Position[1];
468 p1[2] = this->Origin[2] + this->Position[2];
470 this->Transform->Translate(p1[0],p1[1],p1[2]);
471 this->Transform->GetMatrix(result);
474 this->Transform->Pop();