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
24 // File : VTKViewer_ViewFrame.cxx
25 // Author : Nicolas REJNERI
29 #include "VTKViewer_ViewFrame.h"
30 #include "VTKViewer_Utilities.h"
31 #include "VTKViewer_Trihedron.h"
32 #include "VTKViewer_RenderWindow.h"
33 //#include "VTKViewer_InteractorStyleSALOME.h"
35 #include "SALOME_Transform.h"
36 #include "SALOME_TransformFilter.h"
37 #include "SALOME_PassThroughFilter.h"
38 #include "SALOME_GeometryFilter.h"
40 #include "SALOME_Transform.h"
41 #include "SALOME_TransformFilter.h"
42 #include "SALOME_PassThroughFilter.h"
43 #include "SALOME_GeometryFilter.h"
45 #include "QAD_Settings.h"
46 #include "QAD_Config.h"
47 #include "QAD_Application.h"
48 #include "QAD_Desktop.h"
49 #include "SALOME_Selection.h"
50 #include "SALOME_InteractiveObject.hxx"
51 #include "VTKViewer_InteractorStyleSALOME.h"
53 #include "utilities.h"
57 #include <qcolordialog.h>
58 #include <qfiledialog.h>
59 #include <qapplication.h>
63 #include <vtkRenderer.h>
64 #include <vtkTransform.h>
71 VTKViewer_ViewFrame::VTKViewer_ViewFrame(QWidget* parent, const char* name)
72 : QAD_ViewFrame(parent, name)
74 m_ViewUp[0] = 0; m_ViewUp[1] = 0; m_ViewUp[2] = -1;
75 m_ViewNormal[0] = 0; m_ViewNormal[1] = 0; m_ViewNormal[2] = 1;
76 m_Triedron = VTKViewer_Trihedron::New();
77 m_Transform = SALOME_Transform::New();
78 //m_Renderer = VTKViewer_Renderer::New() ;
79 m_Renderer = vtkRenderer::New() ;
81 m_Triedron->AddToRender(m_Renderer);
85 void VTKViewer_ViewFrame::InitialSetup() {
86 m_RW = new VTKViewer_RenderWindow(this, "RenderWindow");
87 m_RW->getRenderWindow()->AddRenderer(m_Renderer);
89 m_Renderer->GetActiveCamera()->ParallelProjectionOn();
90 m_Renderer->LightFollowCameraOn();
91 m_Renderer->TwoSidedLightingOn();
93 // Set BackgroundColor
94 QString BgrColorRed = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
95 QString BgrColorGreen = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
96 QString BgrColorBlue = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
98 if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() )
99 m_Renderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
101 m_Renderer->SetBackground( 0, 0, 0 );
103 // Create an interactor.
104 m_RWInteractor = VTKViewer_RenderWindowInteractor::New();
105 m_RWInteractor->setGUIWindow(m_RW);
106 m_RWInteractor->SetRenderWindow(m_RW->getRenderWindow());
108 VTKViewer_InteractorStyleSALOME* RWS = VTKViewer_InteractorStyleSALOME::New();
109 RWS->setGUIWindow(m_RW);
110 m_RWInteractor->SetInteractorStyle(RWS);
112 m_RWInteractor->Initialize();
113 RWS->setTriedron(m_Triedron);
114 //SRN: additional initialization, to init CurrentRenderer of vtkInteractorStyle
115 RWS->FindPokedRenderer(0, 0);
117 setCentralWidget( m_RW );
121 VTKViewer_ViewFrame::~VTKViewer_ViewFrame() {
122 m_Transform->Delete() ;
123 // In order to ensure that the interactor unregisters
124 // this RenderWindow, we assign a NULL RenderWindow to
125 // it before deleting it.
126 m_RWInteractor->SetRenderWindow(NULL) ;
127 m_RWInteractor->Delete() ;
130 m_Renderer->RemoveAllProps();
131 // NRI : BugID 1137: m_Renderer->Delete() ;
132 m_Triedron->Delete();
133 MESSAGE("VTKViewer_ViewFrame::~VTKViewer_ViewFrame()");
137 Returns widget containing 3D-Viewer
139 QWidget* VTKViewer_ViewFrame::getViewWidget(){
143 bool VTKViewer_ViewFrame::isTrihedronDisplayed(){
144 return m_Triedron->GetVisibility() == VTKViewer_Trihedron::eOn;
147 void VTKViewer_ViewFrame::onAdjustTrihedron(){
148 if(!isTrihedronDisplayed())
150 int aVisibleNum = m_Triedron->GetVisibleActorCount(m_Renderer);
152 // calculating diagonal of visible props of the renderer
154 m_Triedron->VisibilityOff();
155 ::ComputeVisiblePropBounds(m_Renderer,bnd);
156 m_Triedron->VisibilityOn();
158 static bool CalcByDiag = false;
160 aLength = sqrt((bnd[1]-bnd[0])*(bnd[1]-bnd[0])+
161 (bnd[3]-bnd[2])*(bnd[3]-bnd[2])+
162 (bnd[5]-bnd[4])*(bnd[5]-bnd[4]));
164 aLength = bnd[1]-bnd[0];
165 aLength = max((bnd[3]-bnd[2]),aLength);
166 aLength = max((bnd[5]-bnd[4]),aLength);
169 static float aSizeInPercents = 105;
170 QString aSetting = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
171 if(!aSetting.isEmpty()) aSizeInPercents = aSetting.toFloat();
173 static float EPS_SIZE = 5.0E-3;
174 float aSize = m_Triedron->GetSize();
175 float aNewSize = aLength*aSizeInPercents/100.0;
176 // if the new trihedron size have sufficient difference, then apply the value
177 if(fabs(aNewSize-aSize) > aSize*EPS_SIZE || fabs(aNewSize-aSize) > aNewSize*EPS_SIZE)
178 m_Triedron->SetSize(aNewSize);
180 m_Triedron->Render(m_Renderer);
181 ::ResetCameraClippingRange(m_Renderer);
185 Display/hide Trihedron
187 void VTKViewer_ViewFrame::onViewTrihedron(){
188 if(!m_Triedron) return;
189 if(isTrihedronDisplayed())
190 m_Triedron->VisibilityOff();
192 m_Triedron->VisibilityOn();
198 Provides top projection of the active view
200 void VTKViewer_ViewFrame::onViewTop(){
201 vtkCamera* camera = m_Renderer->GetActiveCamera();
202 camera->SetPosition(0,0,1);
203 camera->SetViewUp(0,1,0);
204 camera->SetFocalPoint(0,0,0);
209 Provides bottom projection of the active view
211 void VTKViewer_ViewFrame::onViewBottom(){
212 vtkCamera* camera = m_Renderer->GetActiveCamera();
213 camera->SetPosition(0,0,-1);
214 camera->SetViewUp(0,1,0);
215 camera->SetFocalPoint(0,0,0);
220 Provides left projection of the active view
222 void VTKViewer_ViewFrame::onViewLeft(){
223 vtkCamera* camera = m_Renderer->GetActiveCamera();
224 camera->SetPosition(0,1,0);
225 camera->SetViewUp(0,0,1);
226 camera->SetFocalPoint(0,0,0);
231 Provides right projection of the active view
233 void VTKViewer_ViewFrame::onViewRight(){
234 vtkCamera* camera = m_Renderer->GetActiveCamera();
235 camera->SetPosition(0,-1,0);
236 camera->SetViewUp(0,0,1);
237 camera->SetFocalPoint(0,0,0);
242 Provides back projection of the active view
244 void VTKViewer_ViewFrame::onViewBack(){
245 vtkCamera* camera = m_Renderer->GetActiveCamera();
246 camera->SetPosition(-1,0,0);
247 camera->SetViewUp(0,0,1);
248 camera->SetFocalPoint(0,0,0);
253 Provides front projection of the active view
255 void VTKViewer_ViewFrame::onViewFront(){
256 vtkCamera* camera = m_Renderer->GetActiveCamera();
257 camera->SetPosition(1,0,0);
258 camera->SetViewUp(0,0,1);
259 camera->SetFocalPoint(0,0,0);
264 Fits all objects in the active view
266 void VTKViewer_ViewFrame::onViewFitAll(){
267 m_RWInteractor->GetInteractorStyleSALOME()->ViewFitAll();
268 // int aTriedronWasVisible = isTrihedronDisplayed();
269 // if(m_Triedron->GetVisibleActorCount(m_Renderer)){
270 // m_Triedron->VisibilityOff();
271 // ::ResetCamera(m_Renderer);
273 // m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
274 // ::ResetCamera(m_Renderer,true);
276 // if(aTriedronWasVisible) m_Triedron->VisibilityOn();
277 // else m_Triedron->VisibilityOff();
283 Reset the active view
285 void VTKViewer_ViewFrame::onViewReset(){
286 int aTriedronIsVisible = isTrihedronDisplayed();
287 m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
288 ::ResetCamera(m_Renderer,true);
289 vtkCamera* aCamera = m_Renderer->GetActiveCamera();
290 aCamera->SetPosition(1,-1,1);
291 aCamera->SetViewUp(0,0,1);
292 ::ResetCamera(m_Renderer,true);
293 if(aTriedronIsVisible) m_Triedron->VisibilityOn();
294 else m_Triedron->VisibilityOff();
295 static float aCoeff = 3.0;
296 aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
301 Rotates the active view
303 void VTKViewer_ViewFrame::onViewRotate(){
304 m_RWInteractor->GetInteractorStyleSALOME()->startRotate();
308 Sets a new center of the active view
310 void VTKViewer_ViewFrame::onViewGlobalPan(){
311 if(m_Triedron->GetVisibleActorCount(m_Renderer))
312 m_RWInteractor->GetInteractorStyleSALOME()->startGlobalPan();
316 Zooms the active view
318 void VTKViewer_ViewFrame::onViewZoom(){
319 m_RWInteractor->GetInteractorStyleSALOME()->startZoom();
323 Moves the active view
325 void VTKViewer_ViewFrame::onViewPan(){
326 m_RWInteractor->GetInteractorStyleSALOME()->startPan();
330 Fits all obejcts within a rectangular area of the active view
332 void VTKViewer_ViewFrame::onViewFitArea(){
333 m_RWInteractor->GetInteractorStyleSALOME()->startFitArea();
337 Set background of the viewport
339 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
342 m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
346 Returns background of the viewport
348 QColor VTKViewer_ViewFrame::backgroundColor() const
352 m_Renderer->GetBackground(backint);
353 return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
355 return QMainWindow::backgroundColor();
359 void VTKViewer_ViewFrame::SetSelectionMode( int mode )
361 m_RWInteractor->SetSelectionMode( mode );
364 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
366 m_RWInteractor->rename(IObject, newName);
369 void VTKViewer_ViewFrame::unHighlightAll()
371 m_RWInteractor->unHighlightAll();
374 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject,
378 QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
379 SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
380 if ( Sel->SelectionMode() == 4 )
381 m_RWInteractor->highlight(IObject, highlight, update);
382 else if ( Sel->SelectionMode() == 3 ) {
383 m_RWInteractor->highlight(IObject, highlight, update);
384 if ( Sel->HasIndex( IObject ) ) {
385 TColStd_MapOfInteger MapIndex;
386 Sel->GetIndex( IObject, MapIndex );
387 m_RWInteractor->highlightCell(IObject, highlight, MapIndex, update);
390 else if ( Sel->SelectionMode() == 2 ) {
391 m_RWInteractor->highlight(IObject, highlight, update);
392 if ( Sel->HasIndex( IObject ) ) {
393 TColStd_MapOfInteger MapIndex;
394 Sel->GetIndex( IObject, MapIndex );
395 m_RWInteractor->highlightEdge(IObject, highlight, MapIndex, update);
398 else if ( Sel->SelectionMode() == 1 ) {
399 m_RWInteractor->highlight(IObject, highlight, update);
400 if ( Sel->HasIndex( IObject ) ) {
401 TColStd_MapOfInteger MapIndex;
402 Sel->GetIndex( IObject, MapIndex );
403 m_RWInteractor->highlightPoint(IObject, highlight, MapIndex, update);
408 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject )
410 return m_RWInteractor->isInViewer( IObject );
413 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject )
415 return m_RWInteractor->isVisible( IObject );
418 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
420 m_RW->setPopupServer( App );
423 void VTKViewer_ViewFrame::undo(SALOMEDS::Study_var aStudy,
424 const char* StudyFrameEntry)
426 vtkActorCollection* theActors = m_Renderer->GetActors();
427 theActors->InitTraversal();
428 vtkActor *ac = theActors->GetNextActor();
430 if ( ac->IsA("SALOME_Actor") ) {
431 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
432 if ( anActor->hasIO() ) {
433 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
434 if ( IO->hasEntry() ) {
435 /*if (!QAD_ViewFrame::isInViewer(aStudy, IO->getEntry(), StudyFrameEntry)) {
436 m_RWInteractor->Erase(IO);
441 ac = theActors->GetNextActor();
445 void VTKViewer_ViewFrame::redo(SALOMEDS::Study_var aStudy,
446 const char* StudyFrameEntry)
448 SALOMEDS::SObject_var RefSO;
449 SALOMEDS::SObject_var SO = aStudy->FindObjectID( StudyFrameEntry );
450 SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
451 for (; it->More();it->Next()){
452 SALOMEDS::SObject_var CSO= it->Value();
453 if (CSO->ReferencedObject(RefSO)) {
454 vtkActorCollection* theActors = m_Renderer->GetActors();
455 theActors->InitTraversal();
456 vtkActor *ac = theActors->GetNextActor();
458 if ( ac->IsA("SALOME_Actor") ) {
459 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
460 if ( anActor->hasIO() ) {
461 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
462 if ( IO->hasEntry() ) {
463 /*if ( strcmp(IO->getEntry(),RefSO->GetID()) == 0 )
464 m_RWInteractor->Display(IO);*/
468 ac = theActors->GetNextActor();
476 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* Entry)
478 Handle(SALOME_InteractiveObject) IO;
479 vtkActorCollection* theActors = m_Renderer->GetActors();
480 theActors->InitTraversal();
481 vtkActor *ac = theActors->GetNextActor();
483 if ( ac->IsA("SALOME_Actor") ) {
484 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
485 if ( anActor->hasIO() ) {
486 IO = anActor->getIO();
487 if ( IO->hasEntry() ) {
488 if ( strcmp( IO->getEntry(), Entry ) == 0 ) {
494 ac = theActors->GetNextActor();
500 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& IObject, bool update)
502 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
503 SALOME_Selection* Sel
504 = SALOME_Selection::Selection( myStudy->getSelection() );
506 vtkActorCollection* theActors = m_Renderer->GetActors();
507 theActors->InitTraversal();
508 vtkActor *ac = theActors->GetNextActor();
511 if ( ac->IsA("SALOME_Actor") )
513 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
514 if ( anActor->hasIO() )
516 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
517 if ( IO->isSame(IObject) )
519 m_RWInteractor->Display(IO, false);
520 Sel->AddIObject(IO, false);
525 ac = theActors->GetNextActor();
532 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& IObject)
534 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
535 SALOME_Selection* Sel
536 = SALOME_Selection::Selection( myStudy->getSelection() );
538 vtkActorCollection* theActors = m_Renderer->GetActors();
539 theActors->InitTraversal();
540 vtkActor *ac = theActors->GetNextActor();
542 if ( ac->IsA("SALOME_Actor") ) {
543 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
544 if ( anActor->hasIO() ) {
545 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
546 if ( !IO->isSame(IObject) ) {
547 m_RWInteractor->Erase(IO, false);
548 Sel->RemoveIObject(IO, false);
550 anActor->SetVisibility(true);
551 Sel->AddIObject(IO, false);
555 ac = theActors->GetNextActor();
560 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& IObject, bool update)
562 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
563 SALOME_Selection* Sel
564 = SALOME_Selection::Selection( myStudy->getSelection() );
566 vtkActorCollection* theActors = m_Renderer->GetActors();
567 theActors->InitTraversal();
568 vtkActor *ac = theActors->GetNextActor();
571 if ( ac->IsA("SALOME_Actor") )
573 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
574 if ( anActor->hasIO() )
576 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
577 if ( IO->isSame( IObject ) ) {
578 m_RWInteractor->Erase(IO, false);
579 Sel->RemoveIObject(IO, false);
584 ac = theActors->GetNextActor();
591 void VTKViewer_ViewFrame::DisplayAll()
593 m_RWInteractor->DisplayAll();
597 void VTKViewer_ViewFrame::EraseAll()
599 m_RWInteractor->EraseAll();
603 void VTKViewer_ViewFrame::Repaint(bool theUpdateTrihedron)
605 if (theUpdateTrihedron) onAdjustTrihedron();
609 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
610 m_Transform->GetScale(theScale);
613 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
614 m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
615 m_RWInteractor->Render();
619 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool update /*=false*/ ){
620 theActor->SetVisibility(true);
621 theActor->AddToRender(m_Renderer);
622 theActor->SetTransform(m_Transform);
623 if(update) Repaint();
626 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool update /*=false*/ ){
627 theActor->RemoveFromRender(m_Renderer);
628 if(update) Repaint();