Salome HOME
Fix for Bug NPAL12883
[modules/geom.git] / src / OBJECT / GEOM_Actor.cxx
1 //  GEOM OBJECT : interactive object for Geometry entities visualization
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : GEOM_Actor.cxx
25 //  Author : Christophe ATTANASIO
26 //  Module : GEOM
27 //  $Header$
28
29 /*!
30   \class GEOM_Actor GEOM_Actor.h
31   \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer.
32 */
33 #include "GEOM_Actor.h" 
34  
35 #include "GEOM_DeviceActor.h" 
36 #include "GEOM_VertexSource.h" 
37 #include "GEOM_EdgeSource.h" 
38 #include "GEOM_WireframeFace.h" 
39 #include "GEOM_ShadingFace.h"
40 #include "SVTK_Actor.h"
41
42 #include <vtkObjectFactory.h> 
43 #include <vtkRenderer.h> 
44 #include <vtkProperty.h> 
45 #include <vtkPointPicker.h>
46 #include <vtkCellPicker.h>
47  
48 #include <TopAbs_ShapeEnum.hxx>
49 #include <TopExp_Explorer.hxx>
50 #include <Poly_Triangulation.hxx>
51 #include <BRepMesh_IncrementalMesh.hxx>
52 #include <Bnd_Box.hxx>
53 #include <TopoDS.hxx>
54 #include <BRep_Tool.hxx>
55 #include <BRepBndLib.hxx>
56 #include <TopTools_ListOfShape.hxx>
57 #include <TopoDS_Iterator.hxx>
58 #include <TopExp.hxx>
59  
60 #include <vtkPolyDataWriter.h> 
61  
62 #include <vtkAppendPolyData.h>  
63 #include <vtkPolyDataMapper.h>  
64 #include <vtkPolyData.h>  
65 #include <vtkTransform.h>
66 #include <vtkMatrix4x4.h>
67 #include <vtkMath.h>
68 #include <vtkCamera.h>
69
70 //vtkStandardNewMacro(GEOM_Actor);
71
72 #ifndef MYDEBUG
73 //#define MYDEBUG
74 #endif
75
76 GEOM_Actor::GEOM_Actor(): 
77   //  myDisplayMode(eWireframe), 
78   myIsSelected(false), 
79  
80   myVertexActor(GEOM_DeviceActor::New(),true), 
81   myVertexSource(GEOM_VertexSource::New(),true), 
82  
83   myIsolatedEdgeActor(GEOM_DeviceActor::New(),true), 
84   myIsolatedEdgeSource(GEOM_EdgeSource::New(),true), 
85  
86   myOneFaceEdgeActor(GEOM_DeviceActor::New(),true), 
87   myOneFaceEdgeSource(GEOM_EdgeSource::New(),true), 
88  
89   mySharedEdgeActor(GEOM_DeviceActor::New(),true), 
90   mySharedEdgeSource(GEOM_EdgeSource::New(),true), 
91  
92   myWireframeFaceActor(GEOM_DeviceActor::New(),true), 
93   myWireframeFaceSource(GEOM_WireframeFace::New(),true), 
94  
95   myShadingFaceActor(GEOM_DeviceActor::New(),true), 
96   myShadingFaceSource(GEOM_ShadingFace::New(),true), 
97  
98   myHighlightActor(GEOM_DeviceActor::New(),true), 
99   myAppendFilter(vtkAppendPolyData::New(),true), 
100   myPolyDataMapper(vtkPolyDataMapper::New(),true),
101
102   myHighlightProp(vtkProperty::New()),
103   myPreHighlightProp(vtkProperty::New()),
104   myShadingFaceProp(vtkProperty::New())
105   
106
107 #ifdef MYDEBUG
108   cout <<this<< " GEOM_Actor::GEOM_Actor"<<endl;
109 #endif
110
111   myPolyDataMapper->SetInput(myAppendFilter->GetOutput()); 
112   vtkProperty* aProperty; 
113
114   myHighlightProp->SetAmbient(0.5);
115   myHighlightProp->SetDiffuse(0.3);
116   myHighlightProp->SetSpecular(0.2);
117   myHighlightProp->SetRepresentationToSurface();
118   myHighlightProp->SetAmbientColor(1, 1, 1);
119   myHighlightProp->SetDiffuseColor(1, 1, 1);
120   myHighlightProp->SetSpecularColor(0.5, 0.5, 0.5);
121   myHighlightActor->SetProperty(myHighlightProp.GetPointer());
122
123   this->myHighlightActor->SetInput(myAppendFilter->GetOutput(),false);
124
125   myPreHighlightProp->SetColor(0,1,1);
126   myPreHighlightProp->SetPointSize(SALOME_POINT_SIZE+2);
127   myPreHighlightProp->SetLineWidth(SALOME_LINE_WIDTH+1);
128   myPreHighlightProp->SetRepresentationToWireframe();
129
130   myAppendFilter->AddInput(myVertexSource->GetOutput()); 
131   myVertexActor->SetInput(myVertexSource->GetOutput(),false); 
132   aProperty = myVertexActor->GetProperty(); 
133   aProperty->SetRepresentation(VTK_POINTS); 
134   aProperty->SetPointSize(3); 
135   aProperty->SetColor(1, 1, 0);
136  
137   myAppendFilter->AddInput(myIsolatedEdgeSource->GetOutput()); 
138   myIsolatedEdgeActor->SetInput(myIsolatedEdgeSource->GetOutput(),false); 
139   aProperty = myIsolatedEdgeActor->GetProperty(); 
140   aProperty->SetRepresentation(VTK_WIREFRAME); 
141   aProperty->SetColor(1, 0, 0);
142  
143   myAppendFilter->AddInput(myOneFaceEdgeSource->GetOutput()); 
144   myOneFaceEdgeActor->SetInput(myOneFaceEdgeSource->GetOutput(),false); 
145   aProperty = myOneFaceEdgeActor->GetProperty(); 
146   aProperty->SetRepresentation(VTK_WIREFRAME); 
147   aProperty->SetColor(0, 1, 0);
148  
149   myAppendFilter->AddInput(mySharedEdgeSource->GetOutput()); 
150   mySharedEdgeActor->SetInput(mySharedEdgeSource->GetOutput(),false); 
151   aProperty = mySharedEdgeActor->GetProperty(); 
152   aProperty->SetRepresentation(VTK_WIREFRAME); 
153   aProperty->SetColor(1, 1, 0);
154  
155   myAppendFilter->AddInput(myWireframeFaceSource->GetOutput()); 
156   myWireframeFaceActor->SetInput(myWireframeFaceSource->GetOutput(),false); 
157   aProperty = myWireframeFaceActor->GetProperty(); 
158   aProperty->SetRepresentation(VTK_WIREFRAME); 
159   aProperty->SetColor(0.5, 0.5, 0.5);
160
161   myShadingFaceActor->SetInput(myShadingFaceSource->GetOutput(),true); 
162
163   myShadingFaceProp->SetRepresentation(VTK_SURFACE); 
164   myShadingFaceProp->SetInterpolationToGouraud(); 
165   myShadingFaceProp->SetAmbient(1.0);
166   myShadingFaceProp->SetDiffuse(1.0);
167   myShadingFaceProp->SetSpecular(0.4);
168   myShadingFaceProp->SetAmbientColor(0.329412, 0.223529, 0.027451);
169   myShadingFaceProp->SetDiffuseColor(0.780392, 0.568627, 0.113725);
170   myShadingFaceProp->SetSpecularColor(0.992157, 0.941176, 0.807843);
171
172   myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer());
173
174   // Toggle display mode 
175   setDisplayMode(0); // WIRE FRAME
176
177
178  
179  
180 GEOM_Actor::~GEOM_Actor() 
181
182 #ifdef MYDEBUG
183   cout <<this<< " ~GEOM_Actor::GEOM_Actor"<<endl;
184 #endif
185   myHighlightProp->Delete();
186   myPreHighlightProp->Delete();
187   myShadingFaceProp->Delete();
188
189  
190 GEOM_Actor*  
191 GEOM_Actor:: 
192 New() 
193
194   GEOM_Actor* anObject = new GEOM_Actor(); 
195   anObject->SetMapper(anObject->myPolyDataMapper.Get()); 
196   return anObject; 
197
198  
199  
200 void Write(vtkPolyData* theDataSet, const char* theFileName){ 
201   vtkPolyDataWriter* aWriter = vtkPolyDataWriter::New(); 
202   cout<<"Write - "<<theFileName<<"' : "<<theDataSet->GetNumberOfPoints()<<"; "<<theDataSet->GetNumberOfCells()<<endl; 
203   aWriter->SetInput(theDataSet); 
204   aWriter->SetFileName(theFileName); 
205   //aWriter->Write(); 
206   aWriter->Delete(); 
207
208  
209 void 
210 GEOM_Actor:: 
211 SetModified() 
212
213   this->myVertexSource->Modified(); 
214   this->myIsolatedEdgeSource->Modified(); 
215   this->myOneFaceEdgeSource->Modified(); 
216   this->mySharedEdgeSource->Modified(); 
217   this->myWireframeFaceSource->Modified(); 
218   this->myShadingFaceSource->Modified(); 
219
220
221 void  
222 GEOM_Actor:: 
223 SetMapper(vtkMapper* theMapper) 
224
225   SALOME_Actor::SetMapper(theMapper); 
226
227
228 void 
229 GEOM_Actor:: 
230 AddToRender(vtkRenderer* theRenderer)
231 {
232   //SALOME_Actor::AddToRender(theRenderer);
233   
234   theRenderer->AddActor(this); 
235  
236   this->myHighlightActor->AddToRender(theRenderer); 
237   
238
239   myShadingFaceActor->AddToRender(theRenderer); 
240   myWireframeFaceActor->AddToRender(theRenderer); 
241  
242   mySharedEdgeActor->AddToRender(theRenderer); 
243   myOneFaceEdgeActor->AddToRender(theRenderer); 
244   myIsolatedEdgeActor->AddToRender(theRenderer); 
245  
246   myVertexActor->AddToRender(theRenderer); 
247 }
248  
249 void 
250 GEOM_Actor:: 
251 RemoveFromRender(vtkRenderer* theRenderer)
252 {
253   //SALOME_Actor::RemoveFromRender(theRenderer);
254
255   
256   theRenderer->RemoveActor(this);
257
258   myHighlightActor->RemoveFromRender(theRenderer); 
259   myShadingFaceActor->RemoveFromRender(theRenderer); 
260   myWireframeFaceActor->RemoveFromRender(theRenderer); 
261  
262   mySharedEdgeActor->RemoveFromRender(theRenderer); 
263   myOneFaceEdgeActor->RemoveFromRender(theRenderer); 
264   myIsolatedEdgeActor->RemoveFromRender(theRenderer); 
265  
266   myVertexActor->RemoveFromRender(theRenderer);
267
268   
269   SetSelected(false);
270   SetVisibility(false);
271 }
272
273 void  
274 GEOM_Actor:: 
275 setDisplayMode(int theMode) 
276
277 #ifdef MYDEBUG
278   cout << "GEOM_Actor::SetDisplayMode = "<<theMode  <<endl;
279 #endif
280   VTKViewer_Actor::setDisplayMode(theMode);
281   SetVisibility(GetVisibility()); 
282
283
284 void  
285 GEOM_Actor:: 
286 SetSelected(bool theIsSelected) 
287
288 #ifdef MYDEBUG
289   cout << "GEOM_Actor::SetSelected = "<<theIsSelected  <<endl;
290 #endif
291
292   myIsSelected = theIsSelected; 
293   SetVisibility(GetVisibility()); 
294
295
296 void  
297 GEOM_Actor:: 
298 SetVisibility(int theVisibility) 
299
300 #ifdef MYDEBUG
301   cout << "GEOM_Actor::SetVisibility = "<<theVisibility <<"  myIsSelected="<< myIsSelected
302        << " theVisibility="<<theVisibility<<" myIsPreselected="<<myIsPreselected<<endl;
303 #endif
304
305   SALOME_Actor::SetVisibility(theVisibility);
306
307   this->myHighlightActor->SetVisibility(theVisibility && (myIsSelected || myIsPreselected));
308   
309 //   if(myDisplayMode == (int)eShading)
310 //     this->myHighlightActor->SetInput(myShadingFaceSource->GetOutput(),false);
311 //   else
312 //     this->myHighlightActor->SetInput(myAppendFilter->GetOutput(),false);
313   
314   myShadingFaceActor->SetVisibility(theVisibility && (myDisplayMode == (int)eShading) && (!myIsSelected || !myIsPreselected)); 
315   myWireframeFaceActor->SetVisibility(theVisibility && (myDisplayMode ==(int)eWireframe) && !myIsSelected);
316
317   mySharedEdgeActor->SetVisibility(theVisibility && myDisplayMode == (int)eWireframe && !myIsSelected);
318   myOneFaceEdgeActor->SetVisibility(theVisibility && myDisplayMode == (int)eWireframe && !myIsSelected);
319   myIsolatedEdgeActor->SetVisibility(theVisibility && !myIsSelected);
320
321   myVertexActor->SetVisibility(false);// must be added new mode points 
322 }
323  
324
325 void
326 GEOM_Actor
327 ::SetNbIsos(const int theNb[2])
328 {
329   myNbIsos[0] = theNb[0];
330   myNbIsos[1] = theNb[1];
331 }
332
333 void
334 GEOM_Actor
335 ::GetNbIsos(int &theNbU,int &theNbV)
336 {
337   theNbU = myNbIsos[0];
338   theNbV = myNbIsos[1];
339 }
340
341 static 
342 void 
343 MeshShape(const TopoDS_Shape& theShape,
344           float& theDeflection, 
345           bool theIsRelative)
346
347   static Standard_Real RELATIVE_DEFLECTION = 0.0001; 
348   Standard_Real aDeflection = theDeflection; 
349
350   if(theDeflection <= 0) { // Compute default theDeflection
351     Bnd_Box B;
352     BRepBndLib::Add(theShape, B);
353     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
354     B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
355     Standard_Real aDiagonal = (aXmax-aXmin)*(aXmax-aXmin) +
356                               (aYmax-aYmin)*(aYmax-aYmin) +
357                               (aZmax-aZmin)*(aZmax-aZmin);
358     aDiagonal = sqrt(aDiagonal); 
359     aDeflection = aDiagonal*RELATIVE_DEFLECTION; 
360  
361     if(theIsRelative) 
362       theDeflection = RELATIVE_DEFLECTION; 
363     else 
364       theDeflection = aDeflection; 
365   }
366   
367   BRepMesh_IncrementalMesh aMesh(theShape,aDeflection);
368 }
369
370 void  
371 GEOM_Actor:: 
372 SetDeflection(float theDeflection, bool theIsRelative) 
373
374   myDeflection = theDeflection; 
375   myIsRelative = theIsRelative; 
376  
377   MeshShape(myShape,myDeflection,myIsRelative); 
378  
379   SetModified(); 
380
381
382 void  
383 GEOM_Actor:: 
384 SetShape(const TopoDS_Shape& theShape, 
385          float theDeflection, 
386          bool theIsRelative) 
387
388   myShape = theShape; 
389  
390   myVertexSource->Clear(); 
391   myIsolatedEdgeSource->Clear(); 
392   myOneFaceEdgeSource->Clear(); 
393   mySharedEdgeSource->Clear(); 
394   myWireframeFaceSource->Clear(); 
395   myShadingFaceSource->Clear(); 
396  
397   TopExp_Explorer aVertexExp(theShape,TopAbs_VERTEX);
398   for(; aVertexExp.More(); aVertexExp.Next()){
399      const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertexExp.Current());
400      myVertexSource->AddVertex(aVertex);
401   } 
402   SetDeflection(theDeflection,theIsRelative); 
403  
404   // look if edges are free or shared 
405   TopTools_IndexedDataMapOfShapeListOfShape anEdgeMap;
406   TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,anEdgeMap);
407
408   SetShape(theShape,anEdgeMap); 
409 }
410
411 void  
412 GEOM_Actor:: 
413 SetShape(const TopoDS_Shape& theShape, 
414          const TopTools_IndexedDataMapOfShapeListOfShape& theEdgeMap) 
415
416   if(theShape.ShapeType() == TopAbs_COMPOUND) {
417     TopoDS_Iterator anItr(theShape);
418     for(; anItr.More(); anItr.Next()) {
419       SetShape(anItr.Value(),theEdgeMap);
420     }
421   }
422
423   switch(theShape.ShapeType()){
424     case TopAbs_WIRE: {
425       TopExp_Explorer anEdgeExp(theShape,TopAbs_EDGE);
426       for(; anEdgeExp.More(); anEdgeExp.Next()){
427         const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeExp.Current());
428         if(!BRep_Tool::Degenerated(anEdge))    
429           myIsolatedEdgeSource->AddEdge(anEdge);
430       }
431       break;
432     }
433     case TopAbs_EDGE: {
434       const TopoDS_Edge& anEdge = TopoDS::Edge(theShape);
435       if(!BRep_Tool::Degenerated(anEdge))    
436         myIsolatedEdgeSource->AddEdge(anEdge);
437       break;
438     }
439     case TopAbs_VERTEX: {
440       break;
441     }
442     default: {
443       TopExp_Explorer aFaceExp(theShape,TopAbs_FACE);
444       for(; aFaceExp.More(); aFaceExp.Next()) { 
445         const TopoDS_Face& aFace = TopoDS::Face(aFaceExp.Current());
446         myWireframeFaceSource->AddFace(aFace);
447         myShadingFaceSource->AddFace(aFace);
448         TopExp_Explorer anEdgeExp(aFaceExp.Current(), TopAbs_EDGE);
449         for(; anEdgeExp.More(); anEdgeExp.Next()) {
450           const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeExp.Current()); 
451           if(!BRep_Tool::Degenerated(anEdge)){
452             // compute the number of faces
453             int aNbOfFaces = theEdgeMap.FindFromKey(anEdge).Extent();
454             switch(aNbOfFaces){   
455             case 0:  // isolated edge
456               myIsolatedEdgeSource->AddEdge(anEdge);
457               break;
458             case 1:  // edge in only one face
459               myOneFaceEdgeSource->AddEdge(anEdge);
460               break;
461             default: // edge shared by at least two faces
462               mySharedEdgeSource->AddEdge(anEdge);
463             }
464           }
465         } 
466       }
467     }
468   } 
469
470
471 // OLD METHODS
472 void GEOM_Actor::setDeflection(double adef) {
473 #ifdef MYDEBUG
474   cout << "GEOM_Actor::setDeflection"<<endl;
475 #endif
476   SetDeflection((float)adef,GetIsRelative());
477 }
478
479
480 // warning! must be checked!
481 // SetHighlightProperty
482 // SetWireframeProperty
483 // SetShadingProperty
484
485 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop)
486 {
487 #ifdef MYDEBUG
488   cout << "GEOM_Actor::SetHighlightProperty"<<endl;
489 #endif
490   this->myHighlightActor->GetProperty()->DeepCopy(Prop);
491   
492 }
493
494 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop)
495 {
496 #ifdef MYDEBUG
497   cout << this << " GEOM_Actor::SetWireframeProperty"<<endl;
498 #endif
499   // must be filled
500   myWireframeFaceActor->SetProperty(Prop);
501 }
502
503 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop)
504 {
505 #ifdef MYDEBUG
506   cout << "GEOM_Actor::SetShadingProperty"<<endl;
507 #endif
508   myShadingFaceProp->DeepCopy(Prop);
509 }
510
511
512 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
513 {
514 #ifdef MYDEBUG
515   cout << "GEOM_Actor::Render"<<endl;
516 #endif
517
518   if(!GetVisibility())
519     return;
520   
521 /* render the property */
522   if (!this->Property) {
523     // force creation of a property
524     this->GetProperty();
525     this->Property->SetInterpolation(1);
526     this->Property->SetRepresentationToSurface();
527     this->Property->SetAmbient(0.3);
528     this->Property->SetAmbientColor(0.88,0.86,0.2);
529     this->Property->SetDiffuseColor(0.99,0.7,0.21);
530     this->Property->SetSpecularColor(0.99,0.98,0.83);
531   }
532
533   switch(myDisplayMode){
534   case 0://wireframe
535     myPreHighlightProp->SetRepresentationToWireframe();
536     myHighlightProp->SetRepresentationToWireframe();
537     break;
538   case 1://shading
539     myPreHighlightProp->SetRepresentationToSurface();
540     myHighlightProp->SetRepresentationToSurface();
541     break;
542   }
543
544   if(!myIsSelected){
545     if(myIsPreselected){
546       this->myHighlightActor->SetProperty(myPreHighlightProp.GetPointer());
547       myShadingFaceActor->SetProperty(myPreHighlightProp.GetPointer());
548     } else {
549       this->myHighlightActor->SetProperty(myShadingFaceProp.GetPointer());
550       myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer());
551     }
552   }
553   else{
554     this->myHighlightActor->SetProperty(myHighlightProp.GetPointer());
555     myShadingFaceActor->SetProperty(myHighlightProp.GetPointer());
556   }
557
558   this->Property->Render(this, ren);
559   if (this->BackfaceProperty) {
560     this->BackfaceProperty->BackfaceRender(this, ren);
561     this->Device->SetBackfaceProperty(this->BackfaceProperty);
562   }
563   this->Device->SetProperty(this->Property);
564   if(myShape.ShapeType() == TopAbs_VERTEX) {
565     if(ren){
566       //The parameter determine size of vertex actor relate to diagonal of RendererWindow
567       static vtkFloatingPointType delta = 0.01;
568       vtkFloatingPointType X1 = -1, Y1 = -1, Z1 = 0;
569       ren->ViewToWorld(X1,Y1,Z1);
570       vtkFloatingPointType X2 = +1, Y2 = +1, Z2 = 0;
571       ren->ViewToWorld(X2,Y2,Z2);
572       Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
573       this->SetScale(Z2*delta);
574     }
575     vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
576     this->GetMatrix(ren->GetActiveCamera(), aMatrix);
577     this->Device->SetUserMatrix(aMatrix);
578     this->Device->Render(ren,this->Mapper);
579     aMatrix->Delete();    
580   } else
581     this->Device->Render(ren, this->Mapper);
582 }
583
584 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *)
585 {
586 #ifdef MYDEBUG
587   cout << "GEOM_Actor::ReleaseGraphicsResources"<<endl;
588 #endif  
589 }
590
591
592
593 void GEOM_Actor::ShallowCopy(vtkProp *prop)
594 {
595 #ifdef MYDEBUG
596   cout << "GEOM_Actor::ShallowCopy"<<endl;
597 #endif
598   GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
599   if ( f != NULL )
600     {
601       this->SetShape(f->getTopo(),f->GetDeflection(),f->GetIsRelative());
602     }
603
604   // Now do superclass
605   this->SALOME_Actor::ShallowCopy(prop);
606 }
607
608 const TopoDS_Shape& GEOM_Actor::getTopo() {
609 #ifdef MYDEBUG
610   cout << "GEOM_Actor::getTopo"<<endl;
611 #endif
612   return myShape;
613 }
614
615 void GEOM_Actor::setInputShape(const TopoDS_Shape& ashape, double adef1,
616                                int imode, bool isVector)
617 {
618 #ifdef MYDEBUG
619   cout << "GEOM_Actor::setInputShape"<<endl;
620 #endif
621 }
622
623 double GEOM_Actor::getDeflection()
624 {
625 #ifdef MYDEBUG
626   cout << "GEOM_Actor::getDeflection"<<endl;
627 #endif
628   return (double) GetDeflection();
629 }
630
631
632 double GEOM_Actor::isVector()
633 {
634 #ifdef MYDEBUG
635   cout << "GEOM_Actor::isVector"<<endl;
636 #endif  
637   return 0;
638 }
639
640 void GEOM_Actor::SubShapeOn()
641 {
642 #ifdef MYDEBUG
643   cout << "GEOM_Actor::SubShapeOn"<<endl;
644 #endif  
645 }
646
647 void GEOM_Actor::SubShapeOff()
648 {
649 #ifdef MYDEBUG
650   cout << "GEOM_Actor::SubShapeOff"<<endl;
651 #endif
652 }
653
654 void GEOM_Actor::highlight(bool highlight)
655 {
656 #ifdef MYDEBUG
657   cout << "GEOM_Actor::highlight highlight="<<highlight<<endl;
658 #endif
659   SALOME_Actor::highlight(highlight);
660 }
661
662 void GEOM_Actor::SetOpacity(vtkFloatingPointType opa)
663 {
664   // enk:tested OK
665   myShadingFaceProp->SetOpacity(opa);
666   myHighlightProp->SetOpacity(opa);
667   myPreHighlightProp->SetOpacity(opa);
668 }
669
670 vtkFloatingPointType GEOM_Actor::GetOpacity()
671 {
672   // enk:tested OK
673   return myShadingFaceProp->GetOpacity(); 
674 }
675
676 void GEOM_Actor::SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b)
677 {
678   // enk:tested OK
679   myShadingFaceProp->SetColor(r,g,b);
680 }
681
682 void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b)
683 {
684   // enk:tested OK
685   vtkFloatingPointType aRGB[3];
686   myShadingFaceProp->GetColor(aRGB);
687   r = aRGB[0];
688   g = aRGB[1];
689   b = aRGB[2];
690 }
691
692 bool GEOM_Actor::IsInfinite()
693 {
694   return (bool)(myShape.Infinite());
695 }
696
697 /*!
698   To map current selection to VTK representation
699 */
700 void
701 GEOM_Actor
702 ::Highlight(bool theIsHighlight)
703 {
704   myIsSelected = theIsHighlight;
705 #ifdef MYDEBUG
706   cout << "GEOM_Actor::Highlight myIsSelected="<<myIsSelected<<endl;
707 #endif
708   
709   SALOME_Actor::Highlight(theIsHighlight); // this method call ::highlight(theIsHighlight) in the end
710   SetVisibility(GetVisibility());
711   
712 }
713
714 /*!
715   To process prehighlight (called from SVTK_InteractorStyle)
716 */
717 bool
718 GEOM_Actor
719 ::PreHighlight(vtkInteractorStyle *theInteractorStyle, 
720                SVTK_SelectionEvent* theSelectionEvent,
721                bool theIsHighlight)
722 {
723 #ifdef MYDEBUG
724   cout << "this="<<this<<"  GEOM_Actor::PreHighlight (3) theIsHighlight="<<theIsHighlight<<endl;
725 #endif
726   if ( !GetPickable() )
727     return false;  
728
729   myPreHighlightActor->SetVisibility( false );
730   bool anIsPreselected = myIsPreselected;
731   
732   Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
733   bool anIsChanged = (mySelectionMode != aSelectionMode);
734
735   if( !theIsHighlight ) {
736     SetPreSelected( false );
737   }else{
738     switch(aSelectionMode){
739     case ActorSelection : 
740     {
741       if( !mySelector->IsSelected( myIO ) ) {
742         SetPreSelected( true );
743       }
744     }
745     default:
746       break;
747     }
748   }
749
750   mySelectionMode = aSelectionMode;
751   anIsChanged |= (anIsPreselected != myIsPreselected);
752
753   SetVisibility(GetVisibility());
754   return anIsChanged;
755 }
756
757 /*!
758   To process highlight (called from SVTK_InteractorStyle)
759 */
760 bool
761 GEOM_Actor
762 ::Highlight(vtkInteractorStyle *theInteractorStyle, 
763             SVTK_SelectionEvent* theSelectionEvent,
764             bool theIsHighlight)
765 {
766   // define the selection of object
767 #ifdef MYDEBUG
768   cout << endl << "GEOM_Actor::Highlight (3) myIsSelected="<<myIsSelected<<endl;
769 #endif
770   bool aRet = SALOME_Actor::Highlight(theInteractorStyle,theSelectionEvent,theIsHighlight);
771   SetSelected(theIsHighlight);
772  
773   return aRet;
774 }
775
776 // Copy the follower's composite 4x4 matrix into the matrix provided.
777 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
778 {
779   double *pos, *vup;
780   double Rx[3], Ry[3], Rz[3], p1[3];
781   vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
782   int i;
783   double distance;
784   
785   this->GetOrientation();
786   this->Transform->Push();  
787   this->Transform->PostMultiply();  
788   this->Transform->Identity();
789
790   // apply user defined matrix last if there is one 
791   if (this->UserMatrix)
792     {
793     this->Transform->Concatenate(this->UserMatrix);
794     }
795
796   this->Transform->Translate(-this->Origin[0],
797                              -this->Origin[1],
798                              -this->Origin[2]);
799   // scale
800   this->Transform->Scale(this->Scale[0],
801                          this->Scale[1],
802                          this->Scale[2]);
803   
804   // rotate
805   this->Transform->RotateY(this->Orientation[1]);
806   this->Transform->RotateX(this->Orientation[0]);
807   this->Transform->RotateZ(this->Orientation[2]);
808
809   if (theCam)
810     {
811     // do the rotation
812     // first rotate y 
813     pos = theCam->GetPosition();
814     vup = theCam->GetViewUp();
815
816     if (theCam->GetParallelProjection())
817       {
818       theCam->GetDirectionOfProjection(Rz);
819       }
820     else
821       {
822       distance = sqrt(
823         (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
824         (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
825         (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
826       for (i = 0; i < 3; i++)
827         {
828         Rz[i] = (pos[i] - this->Position[i])/distance;
829         }
830       }
831   
832     vtkMath::Cross(vup,Rz,Rx);
833     vtkMath::Normalize(Rx);
834     vtkMath::Cross(Rz,Rx,Ry);
835     
836     matrix->Element[0][0] = Rx[0];
837     matrix->Element[1][0] = Rx[1];
838     matrix->Element[2][0] = Rx[2];
839     matrix->Element[0][1] = Ry[0];
840     matrix->Element[1][1] = Ry[1];
841     matrix->Element[2][1] = Ry[2];
842     matrix->Element[0][2] = Rz[0];
843     matrix->Element[1][2] = Rz[1];
844     matrix->Element[2][2] = Rz[2];
845     
846     this->Transform->Concatenate(matrix);
847     }
848   
849   // translate to projection reference point PRP
850   // this is the camera's position blasted through
851   // the current matrix
852   p1[0] = this->Origin[0] + this->Position[0];
853   p1[1] = this->Origin[1] + this->Position[1];
854   p1[2] = this->Origin[2] + this->Position[2];
855
856   this->Transform->Translate(p1[0],p1[1],p1[2]);
857   this->Transform->GetMatrix(result);
858   
859   matrix->Delete();
860   this->Transform->Pop();  
861 }