1 // SALOME VTKViewer : build VTK viewer into Salome desktop
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
29 #include "SVTK_Renderer.h"
31 #include "SVTK_Trihedron.h"
32 #include "SVTK_CubeAxesActor2D.h"
33 #include "SVTK_RectPicker.h"
35 #include "SALOME_Actor.h"
36 #include "VTKViewer_Actor.h"
37 #include "VTKViewer_Transform.h"
38 #include "VTKViewer_Utilities.h"
40 #include <vtkCamera.h>
41 #include <vtkRenderer.h>
42 #include <vtkTextProperty.h>
43 #include <vtkObjectFactory.h>
44 #include <vtkCallbackCommand.h>
46 #include <vtkPicker.h>
47 #include <vtkPointPicker.h>
48 #include <vtkCellPicker.h>
50 #include <vtkProperty.h>
52 // undefining min and max because CASCADE's defines them and
53 // it clashes with std::min(), std::max() included in utilities.h
58 //----------------------------------------------------------------------------
59 vtkStandardNewMacro(SVTK_Renderer);
61 //----------------------------------------------------------------------------
64 myDevice(vtkRenderer::New()),
67 myEventCallbackCommand(vtkCallbackCommand::New()),
68 myPointPicker(vtkPointPicker::New()),
69 myCellPicker(vtkCellPicker::New()),
70 myPointRectPicker(SVTK_RectPicker::New()),
71 myCellRectPicker(SVTK_RectPicker::New()),
72 myPreHighlightProperty(vtkProperty::New()),
73 myHighlightProperty(vtkProperty::New()),
74 myTransform(VTKViewer_Transform::New()),
75 myCubeAxes(SVTK_CubeAxesActor2D::New()),
76 myTrihedron(SVTK_Trihedron::New()),
78 myIsTrihedronRelative(true)
81 myTransform->Delete();
83 SetSelectionTolerance();
85 myPointPicker->Delete();
86 myCellPicker->Delete();
88 myPointRectPicker->Delete();
89 myPointRectPicker->PickFromListOn();
91 myCellRectPicker->Delete();
92 myCellRectPicker->PickFromListOn();
93 myCellRectPicker->PickPointsOff();
95 //SetPreselectionProp();
96 myPreHighlightProperty->Delete();
97 myPreHighlightProperty->SetColor(0,1,1);
98 myPreHighlightProperty->SetPointSize(SALOME_POINT_SIZE+2);
99 myPreHighlightProperty->SetLineWidth(SALOME_LINE_WIDTH+2);
100 myPreHighlightProperty->SetRepresentationToPoints();
102 //SetSelectionProp();
103 myHighlightProperty->Delete();
104 myHighlightProperty->SetColor(1,1,0);
105 myHighlightProperty->SetPointSize(SALOME_POINT_SIZE+2);
106 myHighlightProperty->SetLineWidth(SALOME_LINE_WIDTH+2);
107 myHighlightProperty->SetRepresentationToPoints();
109 myTrihedron->Delete();
110 myCubeAxes->Delete();
111 myEventCallbackCommand->Delete();
113 myTrihedron->AddToRender(GetDevice());
114 GetDevice()->AddProp(GetCubeAxes());
116 myBndBox[0] = myBndBox[2] = myBndBox[4] = 0;
117 myBndBox[1] = myBndBox[3] = myBndBox[5] = myTrihedron->GetSize();
119 myCubeAxes->SetBounds(myBndBox);
120 myCubeAxes->SetCamera(GetDevice()->GetActiveCamera());
122 myCubeAxes->SetLabelFormat("%6.4g");
123 myCubeAxes->SetFlyModeToOuterEdges(); // ENK remarks: it must bee
124 myCubeAxes->SetFontFactor(0.8);
125 myCubeAxes->SetCornerOffset(0);
126 myCubeAxes->SetScaling(0);
127 myCubeAxes->SetNumberOfLabels(5);
128 myCubeAxes->VisibilityOff();
129 myCubeAxes->SetTransform(GetTransform());
131 vtkTextProperty* aTextProp = vtkTextProperty::New();
132 aTextProp->SetColor(1, 1, 1);
133 aTextProp->ShadowOn();
134 myCubeAxes->SetAxisTitleTextProperty(aTextProp);
135 myCubeAxes->SetAxisLabelTextProperty(aTextProp);
138 GetDevice()->GetActiveCamera()->ParallelProjectionOn();
139 GetDevice()->LightFollowCameraOn();
140 GetDevice()->TwoSidedLightingOn();
142 myEventCallbackCommand->SetClientData(this);
143 myEventCallbackCommand->SetCallback(SVTK_Renderer::ProcessEvents);
144 GetDevice()->AddObserver(vtkCommand::ConfigureEvent,
145 myEventCallbackCommand.GetPointer(),
147 GetDevice()->AddObserver(vtkCommand::ResetCameraEvent,
148 myEventCallbackCommand.GetPointer(),
150 GetDevice()->AddObserver(vtkCommand::ResetCameraClippingRangeEvent,
151 myEventCallbackCommand.GetPointer(),
158 vtkActorCollection* anActors = GetDevice()->GetActors();
159 vtkActorCollection* anActors2 = vtkActorCollection::New();
161 anActors->InitTraversal();
162 while(vtkActor* anAct = anActors->GetNextActor()){
163 if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
164 anActors2->AddItem(anActor);
168 anActors2->InitTraversal();
169 while(vtkActor* anAct = anActors2->GetNextActor()){
170 if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
171 RemoveActor(anActor);
181 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
182 unsigned long theEvent,
184 void* vtkNotUsed(theCallData))
186 SVTK_Renderer* self = reinterpret_cast<SVTK_Renderer*>(theClientData);
189 case vtkCommand::ConfigureEvent:
192 case vtkCommand::ResetCameraEvent:
195 case vtkCommand::ResetCameraClippingRangeEvent:
196 self->OnResetClippingRange();
201 //----------------------------------------------------------------------------
206 return myDevice.GetPointer();
211 ::Initialize(vtkRenderWindowInteractor* theInteractor,
212 SVTK_Selector* theSelector)
214 myInteractor = theInteractor;
215 mySelector = theSelector;
218 //----------------------------------------------------------------------------
221 ::AddActor(VTKViewer_Actor* theActor)
223 if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(theActor)){
224 anActor->SetInteractor(myInteractor);
225 anActor->SetTransform(GetTransform());
226 anActor->SetSelector(mySelector.GetPointer());
228 anActor->SetPointPicker(myPointPicker.GetPointer());
229 anActor->SetCellPicker(myCellPicker.GetPointer());
231 anActor->SetPointRectPicker(myPointRectPicker.GetPointer());
232 anActor->SetCellRectPicker(myCellRectPicker.GetPointer());
234 anActor->SetPreHighlightProperty(myPreHighlightProperty.GetPointer());
235 anActor->SetHighlightProperty(myHighlightProperty.GetPointer());
237 anActor->AddToRender(GetDevice());
244 ::RemoveActor(VTKViewer_Actor* theActor)
246 if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(theActor)){
247 // Order of the calls are important because VTKViewer_Actor::RemoveFromRender
248 // can leads do destruction of the actor
249 anActor->SetInteractor(NULL);
250 anActor->SetTransform(NULL);
251 anActor->SetSelector(NULL);
253 anActor->SetPointPicker(NULL);
254 anActor->SetCellPicker(NULL);
256 anActor->SetPointRectPicker(NULL);
257 anActor->SetCellRectPicker(NULL);
259 anActor->SetPreHighlightProperty(NULL);
260 anActor->SetHighlightProperty(NULL);
262 anActor->RemoveFromRender(GetDevice());
271 return myTransform.GetPointer();
276 ::GetScale( double theScale[3] )
278 myTransform->GetMatrixScale( theScale );
283 ::SetScale( double theScale[3] )
285 myTransform->SetMatrixScale( theScale[0], theScale[1], theScale[2] );
290 //----------------------------------------------------------------------------
293 ::SetSelectionProp(const double& theRed,
294 const double& theGreen,
295 const double& theBlue,
298 myHighlightProperty->SetColor( theRed, theGreen, theBlue );
299 myHighlightProperty->SetLineWidth( theWidth );
300 myHighlightProperty->SetPointSize( theWidth );
303 //----------------------------------------------------------------------------
306 ::SetPreselectionProp(const double& theRed,
307 const double& theGreen,
308 const double& theBlue,
311 myPreHighlightProperty->SetColor( theRed, theGreen, theBlue );
312 myPreHighlightProperty->SetLineWidth( theWidth );
313 myPreHighlightProperty->SetPointSize( theWidth );
316 //----------------------------------------------------------------------------
319 ::SetSelectionTolerance(const double& theTolNodes,
320 const double& theTolCell)
322 myPointPicker->SetTolerance( theTolNodes );
323 myCellPicker->SetTolerance( theTolCell );
325 myPointRectPicker->SetTolerance( theTolNodes );
326 myCellRectPicker->SetTolerance( theTolCell );
330 //----------------------------------------------------------------------------
331 /*! If parameter theIsForcedUpdate is true, recalculate parameters for
332 * trihedron and cube axes, even if trihedron and cube axes is invisible.
337 CheckBndBox(const float theBounds[6])
339 if(theBounds[0] > -VTK_LARGE_FLOAT && theBounds[1] < VTK_LARGE_FLOAT &&
340 theBounds[2] > -VTK_LARGE_FLOAT && theBounds[3] < VTK_LARGE_FLOAT &&
341 theBounds[4] > -VTK_LARGE_FLOAT && theBounds[5] < VTK_LARGE_FLOAT)
350 bool aTDisplayed = IsTrihedronDisplayed();
351 bool aCDisplayed = IsCubeAxesDisplayed();
354 aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_LARGE_FLOAT;
355 aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_LARGE_FLOAT;
357 int aVisibleNum = myTrihedron->GetVisibleActorCount(GetDevice());
360 myTrihedron->VisibilityOff();
363 myCubeAxes->VisibilityOff();
365 // if the new trihedron size have sufficient difference, then apply the value
366 double aSize = myTrihedron->GetSize();
367 if ( IsTrihedronRelative() )
369 ComputeTrihedronSize(GetDevice(),aSize,aSize,myTrihedronSize);
370 myTrihedron->SetSize(aSize);
373 myTrihedron->SetSize( myTrihedronSize );
375 // iterate through displayed objects and set size if necessary
376 vtkActorCollection* anActors = GetDevice()->GetActors();
377 anActors->InitTraversal();
378 while(vtkActor* anAct = anActors->GetNextActor()){
379 if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
380 if(anActor->IsResizable())
381 anActor->SetSize(0.5*aSize);
382 if(anActor->GetVisibility() && !anActor->IsInfinitive()){
383 float *aBounds = anActor->GetBounds();
384 if(CheckBndBox(aBounds))
385 for(int i = 0; i < 5; i = i + 2){
386 if(aBounds[i] < aNewBndBox[i])
387 aNewBndBox[i] = aBounds[i];
388 if(aBounds[i+1] > aNewBndBox[i+1])
389 aNewBndBox[i+1] = aBounds[i+1];
396 myTrihedron->VisibilityOn();
399 myCubeAxes->VisibilityOn();
402 double aSize = myTrihedron->GetSize();
403 aNewBndBox[0] = aNewBndBox[2] = aNewBndBox[4] = 0;
404 aNewBndBox[1] = aNewBndBox[3] = aNewBndBox[5] = aSize;
407 if(CheckBndBox(aNewBndBox)){
408 for(int i = 0; i < 6; i++)
409 myBndBox[i] = aNewBndBox[i];
410 myCubeAxes->SetBounds(myBndBox);
422 ::ResetCameraClippingRange(GetDevice());
427 ::SetTrihedronSize(int theSize, const bool theRelative)
429 if(myTrihedronSize != theSize || myIsTrihedronRelative != theRelative){
430 myTrihedronSize = theSize;
431 myIsTrihedronRelative = theRelative;
438 ::GetTrihedronSize() const
440 return myTrihedronSize;
445 ::IsTrihedronRelative() const
447 return myIsTrihedronRelative;
450 //----------------------------------------------------------------------------
455 return myTrihedron.GetPointer();
460 ::IsTrihedronDisplayed()
462 return myTrihedron->GetVisibility() == VTKViewer_Trihedron::eOn;
469 if(IsTrihedronDisplayed())
470 myTrihedron->VisibilityOff();
472 myTrihedron->VisibilityOn();
477 ::OnAdjustTrihedron()
483 //----------------------------------------------------------------------------
484 SVTK_CubeAxesActor2D*
488 return myCubeAxes.GetPointer();
493 ::IsCubeAxesDisplayed()
495 return myCubeAxes->GetVisibility() == 1;
502 if(IsCubeAxesDisplayed())
503 myCubeAxes->VisibilityOff();
505 myCubeAxes->VisibilityOn();
516 //----------------------------------------------------------------------------
521 int aTrihedronIsVisible = IsTrihedronDisplayed();
522 int aCubeAxesIsVisible = IsCubeAxesDisplayed();
524 myTrihedron->SetVisibility( VTKViewer_Trihedron::eOnlyLineOn );
525 myCubeAxes->SetVisibility(0);
527 ::ResetCamera(GetDevice(),true);
528 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
529 aCamera->SetPosition(1,-1,1);
530 aCamera->SetViewUp(0,0,1);
531 ::ResetCamera(GetDevice(),true);
533 if(aTrihedronIsVisible)
534 myTrihedron->VisibilityOn();
536 myTrihedron->VisibilityOff();
538 if(aCubeAxesIsVisible)
539 myCubeAxes->VisibilityOn();
541 myCubeAxes->VisibilityOff();
543 static float aCoeff = 3.0;
544 aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
548 //----------------------------------------------------------------------------
553 int aTrihedronWasVisible = false;
554 int aCubeAxesWasVisible = false;
556 aTrihedronWasVisible = IsTrihedronDisplayed();
557 if(aTrihedronWasVisible)
558 myTrihedron->VisibilityOff();
560 aCubeAxesWasVisible = IsCubeAxesDisplayed();
561 if(aCubeAxesWasVisible)
562 myCubeAxes->VisibilityOff();
564 if(myTrihedron->GetVisibleActorCount(GetDevice())){
565 myTrihedron->VisibilityOff();
566 myCubeAxes->VisibilityOff();
567 ::ResetCamera(GetDevice());
569 myTrihedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
570 myCubeAxes->SetVisibility(2);
571 ::ResetCamera(GetDevice(),true);
574 if(aTrihedronWasVisible)
575 myTrihedron->VisibilityOn();
577 myTrihedron->VisibilityOff();
579 if(aCubeAxesWasVisible)
580 myCubeAxes->VisibilityOn();
582 myCubeAxes->VisibilityOff();
584 ::ResetCameraClippingRange(GetDevice());
588 //----------------------------------------------------------------------------
591 ::OnResetClippingRange()
594 ::ResetCameraClippingRange(GetDevice());
598 //----------------------------------------------------------------------------
603 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
604 aCamera->SetPosition(1,0,0);
605 aCamera->SetViewUp(0,0,1);
606 aCamera->SetFocalPoint(0,0,0);
610 //----------------------------------------------------------------------------
615 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
616 aCamera->SetPosition(-1,0,0);
617 aCamera->SetViewUp(0,0,1);
618 aCamera->SetFocalPoint(0,0,0);
622 //----------------------------------------------------------------------------
627 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
628 aCamera->SetPosition(0,0,1);
629 aCamera->SetViewUp(0,1,0);
630 aCamera->SetFocalPoint(0,0,0);
634 //----------------------------------------------------------------------------
639 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
640 aCamera->SetPosition(0,0,-1);
641 aCamera->SetViewUp(0,1,0);
642 aCamera->SetFocalPoint(0,0,0);
646 //----------------------------------------------------------------------------
651 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
652 aCamera->SetPosition(0,-1,0);
653 aCamera->SetViewUp(0,0,1);
654 aCamera->SetFocalPoint(0,0,0);
658 //----------------------------------------------------------------------------
663 vtkCamera* aCamera = GetDevice()->GetActiveCamera();
664 aCamera->SetPosition(0,1,0);
665 aCamera->SetViewUp(0,0,1);
666 aCamera->SetFocalPoint(0,0,0);