]> SALOME platform Git repositories - modules/geom.git/blob - src/OBJECT/GEOM_Actor.cxx
Salome HOME
NRI : First integration.
[modules/geom.git] / src / OBJECT / GEOM_Actor.cxx
1 using namespace std;
2 //  File      : GEOM_Actor.cxx
3 //  Created   : Wed Feb 20 17:24:59 2002
4 //  Author    : Christophe ATTANASIO
5 //  Project   : SALOME
6 //  Module    : GEOM
7 //  Copyright : Open CASCADE 2002
8 //  $Header$
9
10 /*!
11   \class GEOM_Actor GEOM_Actor.h
12   \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer.
13 */
14
15 #include "GEOM_Actor.h"
16
17 // VTK Includes
18 #include <vtkObjectFactory.h>
19 #include <vtkPolyDataMapper.h>
20 #include <vtkPolyDataNormals.h>
21 #include <vtkMath.h>
22
23 // OpenCASCADE Includes
24 #include "GEOM_OCCReader.h"
25 #include <BRep_Tool.hxx>
26
27 //-------------------------------------------------------------
28 // Main methods
29 //-------------------------------------------------------------
30
31
32 GEOM_Actor* GEOM_Actor::New()
33 {
34   // First try to create the object from the vtkObjectFactory
35   vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_Actor");
36   if(ret)
37     {
38       return (GEOM_Actor*)ret;
39     }
40   // If the factory was unable to create the object, then create it here.
41   return new GEOM_Actor;
42 }
43
44
45 GEOM_Actor::GEOM_Actor()
46 {
47   this->Device = vtkActor::New();
48
49   this->WireframeMapper = NULL;
50   this->ShadingMapper = NULL;
51
52   this->ShadingProperty = NULL;
53   this->WireframeProperty = NULL;
54
55   this->deflection = 0;
56   myDisplayMode = 0; 
57
58   this->myIO = NULL;
59   this->myName = "";
60
61   this->HighlightProperty = NULL;
62   this->ishighlighted = false;
63
64   this->subshape = false;
65 }
66
67 GEOM_Actor::~GEOM_Actor()
68 {
69   if (WireframeMapper != NULL)
70     WireframeMapper->Delete();
71   if (ShadingMapper != NULL)
72     ShadingMapper->Delete();
73   if (ShadingProperty != NULL)
74     ShadingProperty->Delete();
75   if (WireframeProperty != NULL)
76     WireframeProperty->Delete();
77   if (HighlightProperty != NULL)
78     HighlightProperty->Delete();
79 }
80
81
82 void GEOM_Actor::ShallowCopy(vtkProp *prop)
83 {
84   GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
85   if ( f != NULL )
86     {
87       this->setInputShape(f->getTopo(),f->getDeflection(),f->getDisplayMode());
88       this->setName( f->getName() );
89       if ( f->hasIO() )
90         this->setIO( f->getIO() );
91       this->ShadingMapper = NULL;
92       this->WireframeMapper = NULL;
93     } else {
94       this->myIO = NULL;
95       this->myName = "";
96       this->ShadingMapper = NULL;
97       this->WireframeMapper = NULL;
98     }
99
100   // Now do superclass
101   this->SALOME_Actor::ShallowCopy(prop);
102 }
103
104 //-------------------------------------------------------------
105 // Set parameters
106 //-------------------------------------------------------------
107
108
109 void GEOM_Actor::setDisplayMode(int thenewmode) {
110   myDisplayMode = thenewmode;
111   if ( thenewmode >=1 ) {
112     if ((myShape.ShapeType() == TopAbs_WIRE) || 
113         (myShape.ShapeType() == TopAbs_EDGE) || 
114         (myShape.ShapeType() == TopAbs_VERTEX)) {
115       if ( !subshape )
116         CreateWireframeMapper();
117       else
118         return;
119     } else
120       CreateShadingMapper();
121   } else
122     CreateWireframeMapper();
123 }
124
125 void GEOM_Actor::setDeflection(double adef) {
126   deflection = adef;
127 }
128
129 void GEOM_Actor::setInputShape(const TopoDS_Shape& aShape,double adef,int imode) {
130   myShape = aShape;
131   deflection = adef;
132   setDisplayMode(imode);
133 }
134
135 //-------------------------------------------------------------
136 // Get parameters
137 //-------------------------------------------------------------
138
139 const TopoDS_Shape& GEOM_Actor::getTopo() {
140   return myShape;
141 }
142
143 double GEOM_Actor::getDeflection() {
144   return deflection;
145 }
146
147 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) {
148   this->WireframeProperty = Prop;
149 }
150
151 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) {
152   this->ShadingProperty = Prop;
153 }
154
155
156 //-------------------------------------------------------------
157 // Mapper creating function
158 //-------------------------------------------------------------
159 void GEOM_Actor::CreateMapper(int theMode) {
160   if(myShape.ShapeType() == TopAbs_VERTEX) {
161     gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(myShape));
162     this->SetPosition(aPnt.X(),aPnt.Y(),aPnt.Z());
163   }
164   GEOM_OCCReader* aread = GEOM_OCCReader::New();
165   aread->setTopo(myShape);
166   aread->setDisplayMode(theMode);
167   aread->GetOutput()->ReleaseDataFlagOn(); 
168     
169   vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New();
170   if (theMode == 0) { 
171     aMapper->SetInput(aread->GetOutput());
172   } else {
173     vtkPolyDataNormals *normals = vtkPolyDataNormals::New();
174     normals->SetInput(aread->GetOutput());
175     aMapper->SetInput(normals->GetOutput());
176   }
177   aread->Delete();
178   this->SetMapper(theMode == 0? WireframeMapper = aMapper : ShadingMapper = aMapper);
179 }
180
181 void GEOM_Actor::CreateShadingMapper() {
182   CreateMapper(1);
183 }
184
185
186 void GEOM_Actor::CreateWireframeMapper() {
187   CreateMapper(0);
188 }
189
190 //-------------------------------------------------------------
191 // Render function
192 //-------------------------------------------------------------
193
194 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
195 {
196   /* render the property */
197   if (!this->Property) {
198     // force creation of a property
199     this->GetProperty();
200     this->Property->SetInterpolation(1);
201     this->Property->SetRepresentationToSurface();
202     this->Property->SetAmbient(0.3);
203     this->Property->SetAmbientColor(0.88,0.86,0.2);
204     this->Property->SetDiffuseColor(0.99,0.7,0.21);
205     this->Property->SetSpecularColor(0.99,0.98,0.83);
206   }
207
208   if(!ishighlighted) {
209     if(myDisplayMode >= 1) {
210       // SHADING
211       this->Property = ShadingProperty;
212     }
213     else {
214       this->Property = WireframeProperty;     
215     }
216
217     if ( ispreselected )
218       this->Property = PreviewProperty;
219   }
220
221   this->Property->Render(this, ren);
222   if (this->BackfaceProperty) {
223     this->BackfaceProperty->BackfaceRender(this, ren);
224     this->Device->SetBackfaceProperty(this->BackfaceProperty);
225   }
226   this->Device->SetProperty(this->Property);
227   // Store information on time it takes to render.
228   // We might want to estimate time from the number of polygons in mapper.
229   if(myDisplayMode >= 1) {
230     if((myShape.ShapeType() == TopAbs_WIRE) || 
231        (myShape.ShapeType() == TopAbs_EDGE) || 
232        (myShape.ShapeType() == TopAbs_VERTEX)) {
233       if ( !subshape ) {
234         if(WireframeMapper==NULL) CreateWireframeMapper();
235       } else
236         return;
237     }
238     else {
239       if(ShadingMapper==NULL) CreateShadingMapper();
240     }
241   }
242   else {
243     if(WireframeMapper==NULL) CreateWireframeMapper();
244   }
245   if(myShape.ShapeType() == TopAbs_VERTEX) {
246     if(ren){
247       //The parameter determine size of vertex actor relate to diagonal of RendererWindow
248       static float delta = 0.01;
249       float X1 = -1, Y1 = -1, Z1 = 0;
250       ren->ViewToWorld(X1,Y1,Z1);
251       float X2 = +1, Y2 = +1, Z2 = 0;
252       ren->ViewToWorld(X2,Y2,Z2);
253       Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
254       this->SetScale(Z2*delta);
255     }
256     vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
257     this->GetMatrix(ren->GetActiveCamera(), aMatrix);
258     this->Device->SetUserMatrix(aMatrix);
259     this->Device->Render(ren,this->Mapper);
260     aMatrix->Delete();    
261   } else
262     this->Device->Render(ren, this->Mapper);
263   this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw();
264 }
265
266 // SubShape
267 void GEOM_Actor::SubShapeOn()
268 {
269   subshape = true;
270 }
271 void GEOM_Actor::SubShapeOff()
272 {
273   subshape = false;
274 }
275
276 //-------------------------------------------------------------
277 // Opacity methods
278 //-------------------------------------------------------------
279
280 void GEOM_Actor::SetOpacity(float opa)
281 {
282   //HighlightProperty->SetOpacity(opa);
283   SALOME_Actor::SetOpacity(opa);
284   ShadingProperty->SetOpacity(opa);
285 }
286
287 float GEOM_Actor::GetOpacity() {
288   return ShadingProperty->GetOpacity();
289 }
290
291 //-------------------------------------------------------------
292 // Color methods
293 //-------------------------------------------------------------
294 void GEOM_Actor::SetColor(float r,float g,float b) {
295   ShadingProperty->SetColor(r,g,b);  
296 }
297
298 void GEOM_Actor::GetColor(float& r,float& g,float& b) {
299   float color[3];
300    ShadingProperty->GetColor(color);
301    r = color[0];
302    g = color[1];
303    b = color[2];
304 }
305
306 //-------------------------------------------------------------
307 // Highlight methods
308 //-------------------------------------------------------------
309
310 void GEOM_Actor::highlight(Standard_Boolean highlight) {
311
312   if(highlight && !ishighlighted) {
313     ishighlighted=true;
314     // build highlight property is necessary
315     if(HighlightProperty==NULL) {
316       HighlightProperty = vtkProperty::New();
317       HighlightProperty->SetAmbient(0.5);
318       HighlightProperty->SetDiffuse(0.3);
319       HighlightProperty->SetSpecular(0.2);
320       HighlightProperty->SetRepresentationToSurface();
321       HighlightProperty->SetAmbientColor(1, 1, 1);
322       HighlightProperty->SetDiffuseColor(1, 1, 1);
323       HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5); 
324     }
325       
326     this->Property = HighlightProperty;
327  
328   }
329   else if (!highlight) {
330     if(ishighlighted) {
331       ishighlighted=false;
332       if(myDisplayMode==1) {
333         //unhilight in shading
334         this->Property = ShadingProperty;
335       }
336       else {
337         //unhilight in wireframe
338         this->Property = WireframeProperty;
339       }
340     }
341   }
342 }
343
344 bool GEOM_Actor::hasHighlight()
345 {
346   return true;
347 }
348
349 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop) {
350   this->HighlightProperty = Prop;
351 }
352
353
354 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *renWin) 
355 {
356   vtkActor::ReleaseGraphicsResources(renWin);
357   
358   // broadcast the message down to the individual LOD mappers
359
360   if(WireframeMapper) this->WireframeMapper->ReleaseGraphicsResources(renWin);
361   if(ShadingMapper) this->ShadingMapper->ReleaseGraphicsResources(renWin);
362 }
363
364
365 // Copy the follower's composite 4x4 matrix into the matrix provided.
366 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
367 {
368   double *pos, *vup;
369   double Rx[3], Ry[3], Rz[3], p1[3];
370   vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
371   int i;
372   double distance;
373   
374   this->GetOrientation();
375   this->Transform->Push();  
376   this->Transform->PostMultiply();  
377   this->Transform->Identity();
378
379   // apply user defined matrix last if there is one 
380   if (this->UserMatrix)
381     {
382     this->Transform->Concatenate(this->UserMatrix);
383     }
384
385   this->Transform->Translate(-this->Origin[0],
386                              -this->Origin[1],
387                              -this->Origin[2]);
388   // scale
389   this->Transform->Scale(this->Scale[0],
390                          this->Scale[1],
391                          this->Scale[2]);
392   
393   // rotate
394   this->Transform->RotateY(this->Orientation[1]);
395   this->Transform->RotateX(this->Orientation[0]);
396   this->Transform->RotateZ(this->Orientation[2]);
397
398   if (theCam)
399     {
400     // do the rotation
401     // first rotate y 
402     pos = theCam->GetPosition();
403     vup = theCam->GetViewUp();
404
405     if (theCam->GetParallelProjection())
406       {
407       theCam->GetDirectionOfProjection(Rz);
408       }
409     else
410       {
411       distance = sqrt(
412         (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
413         (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
414         (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
415       for (i = 0; i < 3; i++)
416         {
417         Rz[i] = (pos[i] - this->Position[i])/distance;
418         }
419       }
420   
421     vtkMath::Cross(vup,Rz,Rx);
422     vtkMath::Normalize(Rx);
423     vtkMath::Cross(Rz,Rx,Ry);
424     
425     matrix->Element[0][0] = Rx[0];
426     matrix->Element[1][0] = Rx[1];
427     matrix->Element[2][0] = Rx[2];
428     matrix->Element[0][1] = Ry[0];
429     matrix->Element[1][1] = Ry[1];
430     matrix->Element[2][1] = Ry[2];
431     matrix->Element[0][2] = Rz[0];
432     matrix->Element[1][2] = Rz[1];
433     matrix->Element[2][2] = Rz[2];
434     
435     this->Transform->Concatenate(matrix);
436     }
437   
438   // translate to projection reference point PRP
439   // this is the camera's position blasted through
440   // the current matrix
441   p1[0] = this->Origin[0] + this->Position[0];
442   p1[1] = this->Origin[1] + this->Position[1];
443   p1[2] = this->Origin[2] + this->Position[2];
444
445   this->Transform->Translate(p1[0],p1[1],p1[2]);
446   this->Transform->GetMatrix(result);
447   
448   matrix->Delete();
449   this->Transform->Pop();  
450 }