]> SALOME platform Git repositories - modules/visu.git/blob - src/OBJECT/VISU_Actor.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/visu.git] / src / OBJECT / VISU_Actor.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
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   : 
25 //  Author : 
26 //  Module : VISU
27 //  $Header$
28
29 #include "VISU_Actor.h"
30 #include "VISU_PipeLine.hxx"
31 #include "VTKViewer_ShrinkFilter.h"
32 #include "VTKViewer_GeometryFilter.h"
33  
34 #include <stdexcept>
35 #include <sstream>
36
37 // VTK Includes
38 #include <vtkProperty.h>
39 #include <vtkSmartPointer.h>
40 #include <vtkTextMapper.h>
41 #include <vtkTextActor.h>
42 #include <vtkProperty2D.h>
43 #include <vtkRenderer.h>
44 #include <vtkCellPicker.h>
45 #include <vtkCell.h>
46 #include <vtkPointPicker.h>
47 #include <vtkPoints.h>
48 #include <vtkInteractorStyle.h>
49 #include <vtkDataSet.h>
50 #include <vtkPolyData.h>
51 #include <vtkUnstructuredGrid.h>
52 #include <vtkPassThroughFilter.h>
53
54 #include <vtkShrinkFilter.h>
55 #include <vtkShrinkPolyData.h>
56
57 #include <vtkGeometryFilter.h>
58 #include <vtkObjectFactory.h>
59
60 #include <boost/bind.hpp>
61
62 #include "utilities.h"
63
64 #include "VISU_PipeLineUtils.hxx"
65
66 using namespace std;
67
68 static int MYVTKDEBUG = 0;
69
70 #ifdef _DEBUG_
71 static int MYDEBUG = 0;
72 #else
73 static int MYDEBUG = 0;
74 #endif
75
76 //#define ENABLE_ANNOTATION
77
78 //----------------------------------------------------------------------------
79 //vtkStandardNewMacro(VISU_Actor);
80
81 //----------------------------------------------------------------------------
82 VISU_Actor
83 ::VISU_Actor():
84   myIsVTKMapping(false),
85   myPrs3d(NULL),
86   myActorFactory(NULL),
87   myIsShrunk(false),
88   myIsShrinkable(false),
89   myShrinkFilter(VTKViewer_ShrinkFilter::New()),
90   myAnnotationMapper(vtkTextMapper::New()),
91   myAnnotationActor(vtkTextActor::New())
92 {
93   if(MYDEBUG) MESSAGE("VISU_Actor::VISU_Actor - this = "<<this);
94
95   myShrinkFilter->Delete();
96
97   myStoreMapping = true;
98
99   myShrinkFilter->SetStoreMapping(true);
100
101   myAnnotationMapper->Delete();
102   myAnnotationActor->SetMapper(myAnnotationMapper.GetPointer());
103
104   myAnnotationActor->Delete();
105   myAnnotationActor->SetVisibility(0);
106 }
107
108 //----------------------------------------------------------------------------
109 void
110 VISU_Actor
111 ::DeepCopy(VISU_Actor *theActor)
112 {
113   highlight(theActor->isHighlighted());
114   SetRepresentation(theActor->GetRepresentation());
115   SetShrinkable(theActor->IsShrunkable());
116   SetShrinkFactor(theActor->GetShrinkFactor());
117   if(theActor->IsShrunk())
118     SetShrink();
119   else
120     UnShrink();
121   SetOpacity(theActor->GetOpacity());
122   SetLineWidth(theActor->GetLineWidth());
123   SetPosition(theActor->GetPosition());
124 }
125
126
127 //----------------------------------------------------------------------------
128 void
129 VISU_Actor
130 ::ShallowCopyPL(VISU_PipeLine* thePipeLine)
131 {
132   myPipeLine->ShallowCopy(thePipeLine, true);
133   GetMapper()->Update();
134 }
135
136 //----------------------------------------------------------------------------
137 VISU_Actor
138 ::~VISU_Actor()
139 {
140   if(MYDEBUG) MESSAGE("~VISU_Actor() - this = "<<this);
141   Superclass::SetProperty(NULL);
142   SetDebug(MYVTKDEBUG);
143 }
144
145 //----------------------------------------------------------------------------
146 void 
147 VISU_Actor
148 ::setIO(const Handle(SALOME_InteractiveObject)& theIO)
149 {
150   Superclass::setIO(theIO); 
151   myName = theIO->getName(); 
152 }
153
154 //----------------------------------------------------------------------------
155 void 
156 VISU_Actor
157 ::SetPrs3d(VISU::Prs3d_i* thePrs3d)
158
159   myPrs3d = thePrs3d;
160 }
161
162 VISU::Prs3d_i* 
163 VISU_Actor
164 ::GetPrs3d()
165
166   return myPrs3d;
167 }
168
169 //----------------------------------------------------------------------------
170 VISU::TActorFactory* 
171 VISU_Actor
172 ::GetFactory()
173
174   return myActorFactory;
175 }
176
177 void
178 VISU_Actor
179 ::SetFactory(VISU::TActorFactory* theActorFactory)
180
181   using namespace VISU;
182
183   if(myActorFactory == theActorFactory)
184     return;
185   
186   if(theActorFactory)
187     myDestroySignal.connect(boost::bind(&TActorFactory::RemoveActor,
188                                         theActorFactory,
189                                         _1));
190
191   myActorFactory = theActorFactory;
192 }
193
194 //----------------------------------------------------------------------------
195 void
196 VISU_Actor
197 ::UpdateFromFactory()
198 {
199   if(myUpdateFromFactoryTime.GetMTime() < myActorFactory->GetMTime()){
200     myUpdateFromFactoryTime.Modified();
201     myActorFactory->UpdateActor(this);
202     Update();
203   }
204 }
205
206 void
207 VISU_Actor
208 ::RemoveFromRender()
209 {
210   RemoveFromRender(GetRenderer());
211 }
212
213 //----------------------------------------------------------------------------
214 void
215 VISU_Actor
216 ::SetPipeLine(VISU_PipeLine* thePipeLine) 
217 {
218   myPipeLine = thePipeLine;
219   if(thePipeLine){
220     if(vtkMapper *aMapper = myPipeLine->GetMapper()){
221       if(vtkDataSet *aDataSet = aMapper->GetInput()){
222         SetShrinkable(thePipeLine->IsShrinkable());
223         SetMapperInput(aDataSet);
224       }
225     }
226   }
227   this->Modified();
228 }
229
230 VISU_PipeLine* 
231 VISU_Actor
232 ::GetPipeLine() 
233
234   return myPipeLine.GetPointer();
235 }
236
237 VISU_PipeLine* 
238 VISU_Actor
239 ::GetCurrentPL() 
240
241   return GetPipeLine();
242 }
243
244
245 //----------------------------------------------------------------------------
246 void
247 VISU_Actor
248 ::SetRepresentation(int theMode) 
249
250   Superclass::SetRepresentation(theMode);
251   if(myRepresentation == VTK_POINTS)
252     UnShrink();
253 }
254
255
256 //----------------------------------------------------------------------------
257 void
258 VISU_Actor
259 ::SetShrink()
260 {
261   if(!myIsShrinkable) 
262     return;
263   if(vtkDataSet* aDataSet = myPassFilter[0]->GetOutput()){
264     myShrinkFilter->SetInput(aDataSet);
265     myPassFilter[1]->SetInput(myShrinkFilter->GetOutput());
266     myIsShrunk = true;
267   }
268 }
269
270 void
271 VISU_Actor
272 ::UnShrink()
273 {
274   if(!myIsShrunk) 
275     return;
276   if(vtkDataSet* aDataSet = myPassFilter[0]->GetOutput()){
277     myPassFilter[1]->SetInput(aDataSet);
278     myPassFilter[1]->Modified();
279     myIsShrunk = false;
280     Modified();
281   }
282 }
283
284 bool
285 VISU_Actor
286 ::IsShrunk()
287 {
288   return myIsShrunk;
289 }
290
291 void
292 VISU_Actor
293 ::SetShrinkable(bool theIsShrinkable)
294 {
295   myIsShrinkable = theIsShrinkable;
296 }
297
298 bool
299 VISU_Actor
300 ::IsShrunkable() 
301
302   return myIsShrinkable;
303 }
304
305 void
306 VISU_Actor
307 ::SetShrinkFactor(vtkFloatingPointType theValue)
308 {
309   myShrinkFilter->SetShrinkFactor(theValue);
310   Modified();
311 }
312
313 vtkFloatingPointType
314 VISU_Actor
315 ::GetShrinkFactor()
316 {
317   return myShrinkFilter->GetShrinkFactor();
318 }
319
320
321 //----------------------------------------------------------------------------
322 void
323 VISU_Actor
324 ::SetOpacity(vtkFloatingPointType theValue)
325 {
326   GetProperty()->SetOpacity(theValue);
327 }
328
329 vtkFloatingPointType
330 VISU_Actor
331 ::GetOpacity()
332
333   return GetProperty()->GetOpacity();
334 }
335
336 void
337 VISU_Actor
338 ::SetLineWidth(vtkFloatingPointType theLineWidth)
339 {
340   GetProperty()->SetLineWidth(theLineWidth);
341 }
342
343 vtkFloatingPointType
344 VISU_Actor
345 ::GetLineWidth()
346 {
347   return GetProperty()->GetLineWidth();
348 }
349
350 //==================================================================
351 // function: AddToRender
352 // purpose :
353 //==================================================================
354 void
355 VISU_Actor
356 ::AddToRender(vtkRenderer* theRenderer)
357 {
358   Superclass::AddToRender(theRenderer);
359   theRenderer->AddActor(myAnnotationActor.GetPointer());
360 }
361
362 //==================================================================
363 // function: RemoveFromRender
364 // purpose :
365 //==================================================================
366 void
367 VISU_Actor
368 ::RemoveFromRender(vtkRenderer* theRenderer)
369 {
370   theRenderer->RemoveActor(myAnnotationActor.GetPointer());
371   Superclass::RemoveFromRender(theRenderer); 
372   myDestroySignal(this);
373 }
374
375 //----------------------------------------------------------------------------
376 void 
377 VISU_Actor
378 ::SetVTKMapping(bool theIsVTKMapping)
379 {
380   myIsVTKMapping = theIsVTKMapping;
381 }
382
383 bool 
384 VISU_Actor
385 ::IsVTKMapping() const
386 {
387   return myIsVTKMapping;
388 }
389
390 //----------------------------------------------------------------------------
391 vtkDataSet* 
392 VISU_Actor
393 ::GetInput()
394 {
395   if(myIsVTKMapping)
396     return Superclass::GetInput();
397
398   return GetCurrentPL()->GetOutput();
399 }
400
401 //----------------------------------------------------------------------------
402 unsigned long int
403 VISU_Actor
404 ::GetMemorySize()
405 {
406   static vtkFloatingPointType ERR_SIZE_CALC = 1.00;
407   vtkDataSet* aDataSet = GetMapper()->GetInput();
408   unsigned long int aSize = size_t(aDataSet->GetActualMemorySize() * 1024 * ERR_SIZE_CALC);
409
410   aDataSet = myGeomFilter->GetOutput();
411   aSize += aDataSet->GetActualMemorySize() * 1024;
412
413   if(IsShrunk()){
414     aDataSet = myShrinkFilter->GetOutput();
415     aSize += aDataSet->GetActualMemorySize() * 1024;
416   }
417
418   return aSize;
419 }
420
421 //----------------------------------------------------------------------------
422 vtkIdType
423 VISU_Actor
424 ::GetNodeObjId(vtkIdType theID)
425 {
426   if(myIsVTKMapping)
427     return Superclass::GetNodeObjId(theID);
428
429   return VISU::GetNodeObjID(GetMapper()->GetInput(), theID);
430 }
431
432 vtkIdType
433 VISU_Actor
434 ::GetNodeVTKID(vtkIdType theID)
435 {
436   if(myIsVTKMapping)
437     return theID;
438
439   return VISU::GetNodeVTKID(GetMapper()->GetInput(), theID);
440 }
441
442 vtkFloatingPointType*
443 VISU_Actor
444 ::GetNodeCoord(int theObjID)
445 {
446   if(myIsVTKMapping)
447     return Superclass::GetNodeCoord(theObjID);
448
449   return VISU::GetNodeCoord(GetInput(), theObjID);
450 }
451
452
453 //----------------------------------------------------------------------------
454 vtkIdType
455 VISU_Actor
456 ::GetElemObjId(vtkIdType theID)
457 {
458   if(myIsVTKMapping)
459     return Superclass::GetElemObjId(theID);
460
461   return VISU::GetElemObjID(GetMapper()->GetInput(), theID);
462 }
463
464 vtkIdType
465 VISU_Actor
466 ::GetElemVTKID(vtkIdType theID)
467 {
468   if(myIsVTKMapping)
469     return theID;
470
471   return VISU::GetElemVTKID(GetMapper()->GetInput(), theID);
472 }
473
474 vtkCell* 
475 VISU_Actor
476 ::GetElemCell(vtkIdType theObjID)
477 {
478   if(myIsVTKMapping)
479     return Superclass::GetElemCell(theObjID);
480
481   return VISU::GetElemCell(GetInput(), theObjID);
482 }
483
484
485 //----------------------------------------------------------------------------
486 bool
487 VISU_Actor
488 ::PreHighlight(vtkInteractorStyle* theInteractorStyle, 
489                SVTK_SelectionEvent* theSelectionEvent,
490                bool theIsHighlight)
491 {
492   bool aRet = Superclass::PreHighlight(theInteractorStyle,
493                                        theSelectionEvent,
494                                        theIsHighlight);
495 #ifndef ENABLE_ANNOTATION
496   return aRet;
497 #endif    
498   //
499   myAnnotationActor->SetVisibility(0);
500   if(theIsHighlight){
501     switch(mySelectionMode){
502     case CellSelection:{ 
503       vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
504       myCellPicker->Pick(theSelectionEvent->myX, 
505                          theSelectionEvent->myY, 
506                          0.0, 
507                          aRenderer);
508
509       if(myCellPicker->GetActor() != this)
510         return false;
511       
512       vtkIdType aVTKId = myCellPicker->GetCellId();
513       if(aVTKId >= 0  && mySelector->IsValid(this,aVTKId,true) && hasIO()){
514         vtkIdType anObjId = GetElemObjId(aVTKId);
515         if(vtkCell* aCell = GetElemCell(anObjId)){
516           vtkPoints* aPts = aCell->GetPoints();
517           if(int aNbPts = aCell->GetNumberOfPoints()){
518             vtkFloatingPointType aCoord[3] = {0.0, 0.0, 0.0};
519             for(int i = 0; i < aNbPts; i++){
520               vtkFloatingPointType *aPntCoord = aPts->GetPoint(i); 
521               aCoord[0] += aPntCoord[0];
522               aCoord[1] += aPntCoord[1];
523               aCoord[2] += aPntCoord[2];
524             }
525             // Display coordinates
526             vtkFloatingPointType aWorldCoord[4] = {aCoord[0]/aNbPts, aCoord[1]/aNbPts, aCoord[2]/aNbPts, 1.0};
527             aRenderer->SetWorldPoint(aWorldCoord);
528             aRenderer->WorldToDisplay();
529             vtkFloatingPointType aSelectionPoint[3];
530             aRenderer->GetDisplayPoint(aSelectionPoint);
531             myAnnotationActor->SetPosition(aSelectionPoint);
532             //
533             // To prepare the annotation text
534             std::ostringstream aStr;
535             aStr<<"Cell ID: "<< anObjId;
536             std::string aString = aStr.str();
537             myAnnotationMapper->SetInput(aString.c_str());
538             
539             myAnnotationActor->SetVisibility(1);
540             return true;
541           }
542         }
543       }
544       break;
545     }
546     case NodeSelection:{ 
547       vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
548       myPointPicker->Pick(theSelectionEvent->myX, 
549                           theSelectionEvent->myY, 
550                           0.0, 
551                           aRenderer);
552       
553       if(myPointPicker->GetActor() != this)
554         return false;
555
556       vtkIdType aVtkId = myPointPicker->GetPointId();
557       if(aVtkId >= 0  && mySelector->IsValid(this,aVtkId,true) && hasIO()){
558         vtkIdType anObjId = GetNodeObjId( aVtkId );
559         if(vtkFloatingPointType* aCoord = GetNodeCoord(anObjId)){
560           // Display coordinates
561           vtkFloatingPointType aWorldCoord[4] = {aCoord[0], aCoord[1], aCoord[2], 1.0};
562           aRenderer->SetWorldPoint(aWorldCoord);
563           aRenderer->WorldToDisplay();
564           vtkFloatingPointType aSelectionPoint[3];
565           aRenderer->GetDisplayPoint(aSelectionPoint);
566           myAnnotationActor->SetPosition(aSelectionPoint);
567           //
568           // To prepare the annotation text
569           std::ostringstream aStr;
570           aStr<<"Node ID: "<< anObjId;
571           std::string aString = aStr.str();
572           myAnnotationMapper->SetInput(aString.c_str());
573           
574           myAnnotationActor->SetVisibility(1);
575           return true;
576         }
577       }
578       break;
579     }
580     case EdgeOfCellSelection:
581       break;
582     default:
583       break;
584     }
585   }
586
587   return aRet;
588 }