Salome HOME
sources v1.2
[modules/smesh.git] / src / OBJECT / SMESH_Actor.cxx
1 //  SMESH OBJECT : interactive object for SMESH 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Actor.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SMESH
27 //  $Header$
28
29 using namespace std;
30 /*!
31   \class SMESH_Actor SMESH_Actor.h
32   \brief ...
33 */
34
35 #include "SMESH_Actor.h"
36 #include "SMESH_Grid.h"
37 #include "utilities.h"
38
39 // VTK Includes
40 #include <vtkObjectFactory.h>
41 #include <vtkMergePoints.h>
42 #include <vtkDataSetMapper.h>
43 #include <vtkFeatureEdges.h>
44 #include <vtkGeometryFilter.h>
45
46 //-------------------------------------------------------------
47 // Main methods
48 //-------------------------------------------------------------
49
50 SMESH_Actor* SMESH_Actor::New()
51 {
52   // First try to create the object from the vtkObjectFactory
53   vtkObject* ret = vtkObjectFactory::CreateInstance("SMESH_Actor");
54   if(ret)
55     {
56       return (SMESH_Actor*)ret;
57     }
58   // If the factory was unable to create the object, then create it here.
59   return new SMESH_Actor;
60 }
61
62
63 SMESH_Actor::SMESH_Actor()
64 {
65   this->Device = vtkActor::New();
66
67   this->EdgeDevice = vtkActor::New();
68   EdgeDevice->VisibilityOff();
69   EdgeDevice->PickableOff();
70
71   this->EdgeShrinkDevice = vtkActor::New();
72   EdgeShrinkDevice->VisibilityOff();
73   EdgeShrinkDevice->PickableOff();
74
75   myIO = NULL;
76   myName = "";
77   myDisplayMode = 0;
78
79   ishighlighted = false;
80   ispreselected = false;
81
82   edgeColor.r = 0.;
83   edgeColor.g = 0.;
84   edgeColor.b = 0.;
85   
86   edgeHighlightColor.r = 1.;
87   edgeHighlightColor.g = 1.;
88   edgeHighlightColor.b = 1.;
89
90   edgePreselectedColor.r = 0.;
91   edgePreselectedColor.g = 1.;
92   edgePreselectedColor.b = 1.;
93
94   actorColor.r = 1.;
95   actorColor.g = 1.;
96   actorColor.b = 0.;
97
98   actorHighlightColor.r = 1.;
99   actorHighlightColor.g = 1.;
100   actorHighlightColor.b = 1.;
101
102   actorPreselectedColor.r = 0.;
103   actorPreselectedColor.g = 1.;
104   actorPreselectedColor.b = 1.;
105
106   actorNodeColor.r = 1.;
107   actorNodeColor.g = 1.;
108   actorNodeColor.b = 0.;
109
110   actorNodeSize = 2 ;
111   
112 }
113
114 SMESH_Actor::~SMESH_Actor()
115 {
116   this->EdgeDevice->Delete();
117   this->EdgeShrinkDevice->Delete();
118 }
119
120 void SMESH_Actor::setReader(vtkUnstructuredGridReader* r) {
121   myReader=r;
122 }
123
124 vtkUnstructuredGridReader* SMESH_Actor::getReader() {
125   return (myReader);
126 }
127
128 vtkMapper* SMESH_Actor::getMapper() {
129   return (this->Mapper);
130 }
131
132 void SMESH_Actor::ShallowCopy(vtkProp *prop)
133 {
134   SMESH_Actor *f = SMESH_Actor::SafeDownCast(prop);
135   if ( f != NULL )
136     {
137       this->setName( f->getName() );
138       if ( f->hasIO() )
139         this->setIO( f->getIO() );
140       this->setDisplayMode( f->getDisplayMode() );
141
142       // Copy devices
143       vtkActor* tempDev = vtkActor::New();
144       tempDev->ShallowCopy(f->Device);
145       vtkProperty* prp = vtkProperty::New();
146       prp->DeepCopy(f->Device->GetProperty());
147       tempDev->SetProperty(prp);
148       prp = vtkProperty::New();
149       prp->DeepCopy(f->Device->GetBackfaceProperty());
150       tempDev->SetBackfaceProperty(prp);
151       this->Device = tempDev;
152       
153       tempDev = vtkActor::New();
154       tempDev->ShallowCopy(f->EdgeDevice);
155       prp = vtkProperty::New();
156       prp->DeepCopy(f->EdgeDevice->GetProperty());
157       tempDev->SetProperty(prp);
158       prp = vtkProperty::New();
159       prp->DeepCopy(f->EdgeDevice->GetBackfaceProperty());
160       tempDev->SetBackfaceProperty(prp);
161       this->EdgeDevice = tempDev;
162
163       tempDev = vtkActor::New();
164       tempDev->ShallowCopy(f->EdgeShrinkDevice);
165       prp = vtkProperty::New();
166       prp->DeepCopy(f->EdgeShrinkDevice->GetProperty());
167       tempDev->SetProperty(prp);
168       prp = vtkProperty::New();
169       prp->DeepCopy(f->EdgeShrinkDevice->GetBackfaceProperty());
170       tempDev->SetBackfaceProperty(prp);
171       this->EdgeShrinkDevice = tempDev;
172
173       // Copy data source
174       this->DataSource = f->DataSource;
175
176       this->myReader   = f->myReader;
177     }
178
179   // Now do superclass
180   this->SALOME_Actor::ShallowCopy(prop);
181
182   // Here we need to modify default ShallowCopy() results
183   // Create copies of properties
184   if ( f != NULL ) {
185     vtkProperty* prp = vtkProperty::New();
186     prp->DeepCopy(f->GetProperty());
187     this->SetProperty(prp);
188
189     prp = vtkProperty::New();
190     prp->DeepCopy(f->GetBackfaceProperty());
191     this->SetBackfaceProperty(prp);
192
193     // Copy the mapper
194     vtkDataSetMapper* mpr = vtkDataSetMapper::New();
195     mpr->ShallowCopy(f->GetMapper());
196     mpr->SetInput(f->DataSource);
197     this->SetMapper(mpr);
198   }
199 }
200
201 void SMESH_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper )
202 {
203    if (this->Mapper == NULL) {
204     MESSAGE ("No mapper for actor.")
205     return;
206   }
207
208    if ( myDisplayMode == 1 ) {
209      EdgeDevice->VisibilityOn();
210      EdgeShrinkDevice->VisibilityOff();
211    } else if ( myDisplayMode == 2 ) {
212      EdgeShrinkDevice->VisibilityOn();
213      EdgeDevice->VisibilityOff();
214    } else {
215      EdgeShrinkDevice->VisibilityOff();
216      EdgeDevice->VisibilityOff();
217    }
218      
219
220   vtkMapper *bestMapper;
221   bestMapper = this->Mapper;
222
223   /* render the property */
224   if (!this->Property) {
225     // force creation of a property
226     this->GetProperty();
227   }
228
229   if ( ishighlighted ) {
230    if ( myDisplayMode == 1 ) {
231      EdgeDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
232      this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
233    } else if ( myDisplayMode == 2 ) {
234      EdgeShrinkDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
235    } else {
236      this->GetProperty()->SetColor(actorHighlightColor.r,actorHighlightColor.g,actorHighlightColor.b);
237    }
238   } else if (! ispreselected ) {
239     if ( myDisplayMode == 1 ) {
240       EdgeDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
241       this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
242     }
243     else if ( myDisplayMode == 2 ) 
244       EdgeShrinkDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
245     else
246       this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
247   }
248   else {
249     if ( myDisplayMode == 1 )
250       EdgeDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
251     else if ( myDisplayMode == 2 ) 
252       EdgeShrinkDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
253     else
254       this->GetProperty()->SetColor(actorPreselectedColor.r,actorPreselectedColor.g,actorPreselectedColor.b);
255   }
256
257   this->Property->Render(this, ren);
258   if (this->BackfaceProperty) {
259     this->BackfaceProperty->BackfaceRender(this, ren);
260     this->Device->SetBackfaceProperty(this->BackfaceProperty);
261   }
262   this->Device->SetProperty(this->Property);
263   
264   /* render the texture */
265   if (this->Texture) {
266     this->Texture->Render(ren);
267   }
268   
269   
270   // Store information on time it takes to render.
271   // We might want to estimate time from the number of polygons in mapper.
272   this->Device->Render(ren,bestMapper);
273   this->EstimatedRenderTime = bestMapper->GetTimeToDraw();
274 }
275
276 int SMESH_Actor::RenderOpaqueGeometry(vtkViewport *vp)
277 {
278   int          renderedSomething = 0; 
279   vtkRenderer  *ren = (vtkRenderer *)vp;
280   
281   if ( ! this->Mapper ) {
282     return 0;
283   }
284   
285   // make sure we have a property
286   if (!this->Property) {
287     // force creation of a property
288     this->GetProperty();
289   }
290   
291   if ( ishighlighted ) {
292    if ( myDisplayMode == 1 ) {
293      EdgeDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
294    } else if ( myDisplayMode == 2 ) {
295      EdgeShrinkDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b);
296    } else {
297      this->GetProperty()->SetColor(actorHighlightColor.r,actorHighlightColor.g,actorHighlightColor.b);
298    }
299   } else if (! ispreselected ) {
300     if ( myDisplayMode == 1 )
301       EdgeDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
302     else if ( myDisplayMode == 2 ) 
303       EdgeShrinkDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b);
304     else
305       this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b);
306   }
307   else {
308     if ( myDisplayMode == 1 )
309       EdgeDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
310     else if ( myDisplayMode == 2 ) 
311       EdgeShrinkDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b);
312     else
313       this->GetProperty()->SetColor(actorPreselectedColor.r,actorPreselectedColor.g,actorPreselectedColor.b);    
314   }
315
316   // is this actor opaque ?
317   if (this->GetIsOpaque()) {
318     this->Property->Render(this, ren);
319     
320     // render the backface property
321     if (this->BackfaceProperty) {
322       this->BackfaceProperty->BackfaceRender(this, ren);
323     }
324     
325     // render the texture 
326     if (this->Texture) {
327       this->Texture->Render(ren);
328     }
329     this->Render(ren,this->Mapper);
330     
331     renderedSomething = 1;
332   }
333   
334   return renderedSomething; 
335 }
336
337
338 void SMESH_Actor::SetColor(float r,float g,float b)
339 {
340   actorColor.r = r;
341   actorColor.g = g;
342   actorColor.b = b;
343 }
344
345 void SMESH_Actor::GetColor(float& r,float& g,float& b)
346 {
347   r = actorColor.r;
348   g = actorColor.g;
349   b = actorColor.b;
350 }
351
352 void SMESH_Actor::SetPreselectedColor(float r,float g,float b)
353 {
354   actorPreselectedColor.r = r;
355   actorPreselectedColor.g = g;
356   actorPreselectedColor.b = b;
357 }
358
359 void SMESH_Actor::GetPreselectedColor(float& r,float& g,float& b)
360 {
361   r = actorPreselectedColor.r;
362   g = actorPreselectedColor.g;
363   b = actorPreselectedColor.b;
364 }
365
366 void SMESH_Actor::SetHighlightColor(float r,float g,float b)
367 {
368   actorHighlightColor.r = r;
369   actorHighlightColor.g = g;
370   actorHighlightColor.b = b;
371 }
372
373 void SMESH_Actor::GetHighlightColor(float& r,float& g,float& b)
374 {
375   r = actorHighlightColor.r;
376   g = actorHighlightColor.g;
377   b = actorHighlightColor.b;
378 }
379
380 void SMESH_Actor::SetEdgeColor(float r,float g,float b)
381 {
382   edgeColor.r = r;
383   edgeColor.g = g;
384   edgeColor.b = b;
385 }
386
387 void SMESH_Actor::GetEdgeColor(float& r,float& g,float& b)
388 {
389   r = edgeColor.r;
390   g = edgeColor.g;
391   b = edgeColor.b;
392 }
393
394 void SMESH_Actor::SetEdgeHighlightColor(float r,float g,float b)
395 {
396   edgeHighlightColor.r = r;
397   edgeHighlightColor.g = g;
398   edgeHighlightColor.b = b;
399 }
400
401 void SMESH_Actor::GetEdgeHighlightColor(float& r,float& g,float& b)
402 {
403   r = edgeHighlightColor.r;
404   g = edgeHighlightColor.g;
405   b = edgeHighlightColor.b;
406 }
407
408 void SMESH_Actor::SetEdgePreselectedColor(float r,float g,float b)
409 {
410   edgePreselectedColor.r = r;
411   edgePreselectedColor.g = g;
412   edgePreselectedColor.b = b;
413 }
414
415 void SMESH_Actor::GetEdgePreselectedColor(float& r,float& g,float& b)
416 {
417   r = edgePreselectedColor.r;
418   g = edgePreselectedColor.g;
419   b = edgePreselectedColor.b;
420 }
421
422
423 void SMESH_Actor::SetNodeColor(float r,float g,float b)
424
425   actorNodeColor.r = r ;
426   actorNodeColor.g = g ;
427   actorNodeColor.b = b ;
428 }
429
430 void SMESH_Actor::GetNodeColor(float& r,float& g,float& b)
431
432   r = actorNodeColor.r ;
433   g = actorNodeColor.g ;
434   b = actorNodeColor.b ;
435 }
436
437 void SMESH_Actor::SetNodeSize(int size)
438 {
439   actorNodeSize = size ;
440 }
441
442 int SMESH_Actor::GetNodeSize()
443 {
444   return actorNodeSize ;
445 }
446
447
448 void SMESH_Actor::AddNode(int idSMESHDSnode,int idVTKnode)
449 {
450   if (DataSource->IsA("SMESH_Grid")) {
451     ((SMESH_Grid*)DataSource)->AddNode(idSMESHDSnode, idVTKnode);
452   } else 
453     MESSAGE("AddNode() method has been moved to SMESH_Grid class");
454 }
455 void SMESH_Actor::AddElement(int idSMESHDSelement, int idVTKelement)
456 {
457   if (DataSource->IsA("SMESH_Grid")) {
458     ((SMESH_Grid*)DataSource)->AddElement(idSMESHDSelement, idVTKelement);
459   } else 
460     MESSAGE("AddElement() method has been moved to SMESH_Grid class");
461 }
462
463 void SMESH_Actor::SetIdsVTKNode(const TColStd_DataMapOfIntegerInteger& mapVTK)
464 {
465   if (DataSource->IsA("SMESH_Grid")) {
466     ((SMESH_Grid*)DataSource)->SetIdsVTKNode(mapVTK);
467   } else 
468     MESSAGE("SetIdsVTKNode() method has been moved to SMESH_Grid class");
469 }
470 void SMESH_Actor::SetIdsSMESHDSNode(const TColStd_DataMapOfIntegerInteger& mapSMESHDS)
471 {
472   if (DataSource->IsA("SMESH_Grid")) {
473     ((SMESH_Grid*)DataSource)->SetIdsSMESHDSNode(mapSMESHDS);
474   } else 
475     MESSAGE("SetIdsSMESHDSNode() method has been moved to SMESH_Grid class");
476 }
477
478 void SMESH_Actor::SetIdsVTKElement(const TColStd_DataMapOfIntegerInteger& mapVTK)
479 {
480   if (DataSource->IsA("SMESH_Grid")) {
481     ((SMESH_Grid*)DataSource)->SetIdsVTKElement(mapVTK);
482   } else 
483     MESSAGE("SetIdsVTKElement() method has been moved to SMESH_Grid class");
484 }
485 void SMESH_Actor::SetIdsSMESHDSElement(const TColStd_DataMapOfIntegerInteger& mapSMESHDS)
486 {
487   if (DataSource->IsA("SMESH_Grid")) {
488     ((SMESH_Grid*)DataSource)->SetIdsSMESHDSElement(mapSMESHDS);
489   } else 
490     MESSAGE("SetIdsSMESHDSElement() method has been moved to SMESH_Grid class");
491 }
492
493 int SMESH_Actor::GetIdVTKNode(int idSMESHDSnode)
494 {
495   if (DataSource->IsA("SMESH_Grid")) {
496     return ((SMESH_Grid*)DataSource)->GetIdVTKNode(idSMESHDSnode);
497   } else {
498     MESSAGE("GetIdVTKNode() method has been moved to SMESH_Grid class");
499     return -1;
500   }
501 }
502 int SMESH_Actor::GetIdVTKElement(int idSMESHDSelement)
503 {
504   if (DataSource->IsA("SMESH_Grid")) {
505     return ((SMESH_Grid*)DataSource)->GetIdVTKElement(idSMESHDSelement);
506   } else {
507     MESSAGE("GetIdVTKElement() method has been moved to SMESH_Grid class");
508     return -1;
509   }
510
511 }
512
513 int SMESH_Actor::GetIdSMESHDSNode(int idVTKnode)
514 {
515   if (DataSource->IsA("SMESH_Grid")) {
516     return ((SMESH_Grid*)DataSource)->GetIdSMESHDSNode(idVTKnode);
517   } else {
518     MESSAGE("GetIdSMESHDSNode() method has been moved to SMESH_Grid class");
519     return -1;
520   }
521 }
522
523 int SMESH_Actor::GetIdSMESHDSElement(int idVTKelement)
524 {
525   if (DataSource->IsA("SMESH_Grid")) {
526     return ((SMESH_Grid*)DataSource)->GetIdSMESHDSElement(idVTKelement);
527   } else {
528     MESSAGE("AddNode() method has been moved to SMESH_Grid class");
529     return -1;
530   }
531 }
532
533 void SMESH_Actor::ClearNode()
534 {
535   if (DataSource->IsA("SMESH_Grid")) {
536     ((SMESH_Grid*)DataSource)->ClearNode();
537   } else 
538     MESSAGE("ClearNode() method has been moved to SMESH_Grid class");
539 }
540
541 void SMESH_Actor::ClearElement()
542 {
543   if (DataSource->IsA("SMESH_Grid")) {
544     ((SMESH_Grid*)DataSource)->ClearElement();
545   } else 
546     MESSAGE("ClearElement() method has been moved to SMESH_Grid class");
547 }
548
549 void SMESH_Actor::RemoveNode(int id)
550 {
551   if (DataSource->IsA("SMESH_Grid")) {
552     ((SMESH_Grid*)DataSource)->RemoveNode(id);
553   } else 
554     MESSAGE("RemoveNode() method has been moved to SMESH_Grid class");
555 }
556 void SMESH_Actor::RemoveElement(int id)
557 {
558   if (DataSource->IsA("SMESH_Grid")) {
559     ((SMESH_Grid*)DataSource)->RemoveElement(id);
560   } else 
561     MESSAGE("RemoveElement() method has been moved to SMESH_Grid class");
562 }
563
564 void SMESH_Actor::setDisplayMode(int thenewmode) {
565   myDisplayMode = thenewmode;
566   if ( myDisplayMode == 1 ) {
567     EdgeDevice->VisibilityOn();
568     EdgeShrinkDevice->VisibilityOff();
569   } else if ( myDisplayMode == 2 ) {
570     EdgeDevice->VisibilityOff();
571     EdgeShrinkDevice->VisibilityOn();
572   } else {
573     EdgeDevice->VisibilityOff();
574     EdgeShrinkDevice->VisibilityOff();
575   }
576 }
577
578 float SMESH_Actor::GetShrinkFactor()
579 {
580   return myShrinkFactor;
581 }
582
583 void SMESH_Actor::SetShrinkFactor(float value )
584 {
585   if ( value <= 0.1 ) 
586     value = 0.8;
587
588   myShrinkFactor = value;
589 }
590
591 void SMESH_Actor::GetChildActors(vtkActorCollection* actors)
592 {
593   actors->AddItem(EdgeDevice);
594   actors->AddItem(EdgeShrinkDevice);
595 }
596
597 void SMESH_Actor::SetVisibility(bool visibility) 
598 {
599   if ( visibility ) {
600     this->VisibilityOn();
601     if ( myDisplayMode == 1 ) {
602       EdgeDevice->VisibilityOn();
603       EdgeShrinkDevice->VisibilityOff();
604     } else if ( myDisplayMode == 2 ) {
605       EdgeDevice->VisibilityOff();
606       EdgeShrinkDevice->VisibilityOn();
607     } else {
608       EdgeDevice->VisibilityOff();
609       EdgeShrinkDevice->VisibilityOff();
610     }
611   } else {
612     this->VisibilityOff();
613     EdgeDevice->VisibilityOff();
614     EdgeShrinkDevice->VisibilityOff();    
615   }
616 }
617