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_GeometryFilter.h"
39 #include "QAD_Settings.h"
40 #include "QAD_Config.h"
41 #include "QAD_Application.h"
42 #include "QAD_Desktop.h"
43 #include "SALOME_Selection.h"
44 #include "SALOME_InteractiveObject.hxx"
46 #include "utilities.h"
50 #include <qcolordialog.h>
51 #include <qfiledialog.h>
52 #include <qapplication.h>
56 #include <vtkRenderer.h>
57 #include <vtkTransform.h>
64 VTKViewer_ViewFrame::VTKViewer_ViewFrame(QWidget* parent, const char* name)
65 : QAD_ViewFrame(parent, name)
67 m_ViewUp[0] = 0; m_ViewUp[1] = 0; m_ViewUp[2] = -1;
68 m_ViewNormal[0] = 0; m_ViewNormal[1] = 0; m_ViewNormal[2] = 1;
69 m_Triedron = VTKViewer_Trihedron::New();
70 m_Transform = SALOME_Transform::New();
71 //m_Renderer = VTKViewer_Renderer::New() ;
72 m_Renderer = vtkRenderer::New() ;
74 m_Triedron->AddToRender(m_Renderer);
78 void VTKViewer_ViewFrame::InitialSetup() {
79 m_RW = new VTKViewer_RenderWindow(this, "RenderWindow");
80 m_RW->getRenderWindow()->AddRenderer(m_Renderer);
82 m_Renderer->GetActiveCamera()->ParallelProjectionOn();
83 m_Renderer->LightFollowCameraOn();
84 m_Renderer->TwoSidedLightingOn();
86 // Set BackgroundColor
87 QString BgrColorRed = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
88 QString BgrColorGreen = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
89 QString BgrColorBlue = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
91 if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() )
92 m_Renderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
94 m_Renderer->SetBackground( 0, 0, 0 );
96 // Create an interactor.
97 m_RWInteractor = VTKViewer_RenderWindowInteractor::New();
98 m_RWInteractor->setGUIWindow(m_RW);
99 m_RWInteractor->SetRenderWindow(m_RW->getRenderWindow());
101 VTKViewer_InteractorStyleSALOME* RWS = VTKViewer_InteractorStyleSALOME::New();
102 RWS->setGUIWindow(m_RW);
103 m_RWInteractor->SetInteractorStyle(RWS);
105 m_RWInteractor->Initialize();
106 RWS->setTriedron(m_Triedron);
107 //SRN: additional initialization, to init CurrentRenderer of vtkInteractorStyle
108 RWS->FindPokedRenderer(0, 0);
110 setCentralWidget( m_RW );
114 VTKViewer_ViewFrame::~VTKViewer_ViewFrame() {
115 m_Transform->Delete() ;
116 // In order to ensure that the interactor unregisters
117 // this RenderWindow, we assign a NULL RenderWindow to
118 // it before deleting it.
119 m_RWInteractor->SetRenderWindow(NULL) ;
120 m_RWInteractor->Delete() ;
123 m_Renderer->RemoveAllProps();
124 // NRI : BugID 1137: m_Renderer->Delete() ;
125 m_Triedron->Delete();
126 MESSAGE("VTKViewer_ViewFrame::~VTKViewer_ViewFrame()");
130 Returns widget containing 3D-Viewer
132 QWidget* VTKViewer_ViewFrame::getViewWidget(){
136 bool VTKViewer_ViewFrame::isTrihedronDisplayed(){
137 return m_Triedron->GetVisibility() == VTKViewer_Trihedron::eOn;
140 void VTKViewer_ViewFrame::onAdjustTrihedron(){
141 if(!isTrihedronDisplayed())
143 int aVisibleNum = m_Triedron->GetVisibleActorCount(m_Renderer);
145 // calculating diagonal of visible props of the renderer
147 m_Triedron->VisibilityOff();
148 ::ComputeVisiblePropBounds(m_Renderer,bnd);
149 m_Triedron->VisibilityOn();
151 static bool CalcByDiag = false;
153 aLength = sqrt((bnd[1]-bnd[0])*(bnd[1]-bnd[0])+
154 (bnd[3]-bnd[2])*(bnd[3]-bnd[2])+
155 (bnd[5]-bnd[4])*(bnd[5]-bnd[4]));
157 aLength = bnd[1]-bnd[0];
158 aLength = max((bnd[3]-bnd[2]),aLength);
159 aLength = max((bnd[5]-bnd[4]),aLength);
162 static float aSizeInPercents = 105;
163 QString aSetting = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
164 if(!aSetting.isEmpty()) aSizeInPercents = aSetting.toFloat();
166 static float EPS_SIZE = 5.0E-3;
167 float aSize = m_Triedron->GetSize();
168 float aNewSize = aLength*aSizeInPercents/100.0;
169 // if the new trihedron size have sufficient difference, then apply the value
170 if(fabs(aNewSize-aSize) > aSize*EPS_SIZE || fabs(aNewSize-aSize) > aNewSize*EPS_SIZE){
171 m_Triedron->SetSize(aNewSize);
174 ::ResetCameraClippingRange(m_Renderer);
178 Display/hide Trihedron
180 void VTKViewer_ViewFrame::onViewTrihedron(){
181 if(!m_Triedron) return;
182 if(isTrihedronDisplayed())
183 m_Triedron->VisibilityOff();
185 m_Triedron->VisibilityOn();
191 Provides top projection of the active view
193 void VTKViewer_ViewFrame::onViewTop(){
194 vtkCamera* camera = m_Renderer->GetActiveCamera();
195 camera->SetPosition(0,0,1);
196 camera->SetViewUp(0,1,0);
197 camera->SetFocalPoint(0,0,0);
202 Provides bottom projection of the active view
204 void VTKViewer_ViewFrame::onViewBottom(){
205 vtkCamera* camera = m_Renderer->GetActiveCamera();
206 camera->SetPosition(0,0,-1);
207 camera->SetViewUp(0,1,0);
208 camera->SetFocalPoint(0,0,0);
213 Provides left projection of the active view
215 void VTKViewer_ViewFrame::onViewLeft(){
216 vtkCamera* camera = m_Renderer->GetActiveCamera();
217 camera->SetPosition(0,1,0);
218 camera->SetViewUp(0,0,1);
219 camera->SetFocalPoint(0,0,0);
224 Provides right projection of the active view
226 void VTKViewer_ViewFrame::onViewRight(){
227 vtkCamera* camera = m_Renderer->GetActiveCamera();
228 camera->SetPosition(0,-1,0);
229 camera->SetViewUp(0,0,1);
230 camera->SetFocalPoint(0,0,0);
235 Provides back projection of the active view
237 void VTKViewer_ViewFrame::onViewBack(){
238 vtkCamera* camera = m_Renderer->GetActiveCamera();
239 camera->SetPosition(-1,0,0);
240 camera->SetViewUp(0,0,1);
241 camera->SetFocalPoint(0,0,0);
246 Provides front projection of the active view
248 void VTKViewer_ViewFrame::onViewFront(){
249 vtkCamera* camera = m_Renderer->GetActiveCamera();
250 camera->SetPosition(1,0,0);
251 camera->SetViewUp(0,0,1);
252 camera->SetFocalPoint(0,0,0);
257 Fits all objects in the active view
259 void VTKViewer_ViewFrame::onViewFitAll(){
260 m_RWInteractor->GetInteractorStyleSALOME()->ViewFitAll();
261 // int aTriedronWasVisible = isTrihedronDisplayed();
262 // if(m_Triedron->GetVisibleActorCount(m_Renderer)){
263 // m_Triedron->VisibilityOff();
264 // ::ResetCamera(m_Renderer);
266 // m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
267 // ::ResetCamera(m_Renderer,true);
269 // if(aTriedronWasVisible) m_Triedron->VisibilityOn();
270 // else m_Triedron->VisibilityOff();
276 Reset the active view
278 void VTKViewer_ViewFrame::onViewReset(){
279 int aTriedronIsVisible = isTrihedronDisplayed();
280 m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
281 ::ResetCamera(m_Renderer,true);
282 vtkCamera* aCamera = m_Renderer->GetActiveCamera();
283 aCamera->SetPosition(1,-1,1);
284 aCamera->SetViewUp(0,0,1);
285 ::ResetCamera(m_Renderer,true);
286 if(aTriedronIsVisible) m_Triedron->VisibilityOn();
287 else m_Triedron->VisibilityOff();
288 static float aCoeff = 3.0;
289 aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
294 Rotates the active view
296 void VTKViewer_ViewFrame::onViewRotate(){
297 m_RWInteractor->GetInteractorStyleSALOME()->startRotate();
301 Sets a new center of the active view
303 void VTKViewer_ViewFrame::onViewGlobalPan(){
304 if(m_Triedron->GetVisibleActorCount(m_Renderer))
305 m_RWInteractor->GetInteractorStyleSALOME()->startGlobalPan();
309 Zooms the active view
311 void VTKViewer_ViewFrame::onViewZoom(){
312 m_RWInteractor->GetInteractorStyleSALOME()->startZoom();
316 Moves the active view
318 void VTKViewer_ViewFrame::onViewPan(){
319 m_RWInteractor->GetInteractorStyleSALOME()->startPan();
323 Fits all obejcts within a rectangular area of the active view
325 void VTKViewer_ViewFrame::onViewFitArea(){
326 m_RWInteractor->GetInteractorStyleSALOME()->startFitArea();
330 Set background of the viewport
332 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
335 m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
339 Returns background of the viewport
341 QColor VTKViewer_ViewFrame::backgroundColor() const
345 m_Renderer->GetBackground(backint);
346 return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
348 return QMainWindow::backgroundColor();
352 void VTKViewer_ViewFrame::SetSelectionMode( Selection_Mode mode )
354 m_RWInteractor->SetSelectionMode( mode );
357 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
359 m_RWInteractor->rename(IObject, newName);
362 void VTKViewer_ViewFrame::unHighlightAll()
364 m_RWInteractor->unHighlightAll();
367 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject,
371 QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
372 SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
373 m_RWInteractor->highlight(IObject, highlight, update);
375 switch (Sel->SelectionMode()) {
377 if ( Sel->HasIndex( IObject ) ) {
378 TColStd_MapOfInteger MapIndex;
379 Sel->GetIndex( IObject, MapIndex );
380 m_RWInteractor->highlightPoint(IObject, highlight, MapIndex, update);
383 case EdgeOfCellSelection:
384 if ( Sel->HasIndex( IObject ) ) {
385 TColStd_MapOfInteger MapIndex;
386 Sel->GetIndex( IObject, MapIndex );
387 m_RWInteractor->highlightEdge(IObject, highlight, MapIndex, update);
393 case VolumeSelection:
394 if ( Sel->HasIndex( IObject ) ) {
395 TColStd_MapOfInteger MapIndex;
396 Sel->GetIndex( IObject, MapIndex );
397 m_RWInteractor->highlightCell(IObject, highlight, MapIndex, update);
403 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject )
405 return m_RWInteractor->isInViewer( IObject );
408 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject )
410 return m_RWInteractor->isVisible( IObject );
413 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
415 m_RW->setPopupServer( App );
418 void VTKViewer_ViewFrame::undo(SALOMEDS::Study_var aStudy,
419 const char* StudyFrameEntry)
421 vtkActorCollection* theActors = m_Renderer->GetActors();
422 theActors->InitTraversal();
423 vtkActor *ac = theActors->GetNextActor();
425 if ( ac->IsA("SALOME_Actor") ) {
426 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
427 if ( anActor->hasIO() ) {
428 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
429 if ( IO->hasEntry() ) {
430 /*if (!QAD_ViewFrame::isInViewer(aStudy, IO->getEntry(), StudyFrameEntry)) {
431 m_RWInteractor->Erase(IO);
436 ac = theActors->GetNextActor();
440 void VTKViewer_ViewFrame::redo(SALOMEDS::Study_var aStudy,
441 const char* StudyFrameEntry)
443 SALOMEDS::SObject_var RefSO;
444 SALOMEDS::SObject_var SO = aStudy->FindObjectID( StudyFrameEntry );
445 SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
446 for (; it->More();it->Next()){
447 SALOMEDS::SObject_var CSO= it->Value();
448 if (CSO->ReferencedObject(RefSO)) {
449 vtkActorCollection* theActors = m_Renderer->GetActors();
450 theActors->InitTraversal();
451 vtkActor *ac = theActors->GetNextActor();
453 if ( ac->IsA("SALOME_Actor") ) {
454 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
455 if ( anActor->hasIO() ) {
456 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
457 if ( IO->hasEntry() ) {
458 /*if ( strcmp(IO->getEntry(),RefSO->GetID()) == 0 )
459 m_RWInteractor->Display(IO);*/
463 ac = theActors->GetNextActor();
471 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* Entry)
473 Handle(SALOME_InteractiveObject) IO;
474 vtkActorCollection* theActors = m_Renderer->GetActors();
475 theActors->InitTraversal();
476 vtkActor *ac = theActors->GetNextActor();
478 if ( ac->IsA("SALOME_Actor") ) {
479 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
480 if ( anActor->hasIO() ) {
481 IO = anActor->getIO();
482 if ( IO->hasEntry() ) {
483 if ( strcmp( IO->getEntry(), Entry ) == 0 ) {
489 ac = theActors->GetNextActor();
495 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& IObject, bool update)
497 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
498 SALOME_Selection* Sel
499 = SALOME_Selection::Selection( myStudy->getSelection() );
501 vtkActorCollection* theActors = m_Renderer->GetActors();
502 theActors->InitTraversal();
503 vtkActor *ac = theActors->GetNextActor();
506 if ( ac->IsA("SALOME_Actor") )
508 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
509 if ( anActor->hasIO() )
511 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
512 if ( IO->isSame(IObject) )
514 m_RWInteractor->Display(IO, false);
515 Sel->AddIObject(IO, false);
520 ac = theActors->GetNextActor();
527 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& IObject)
529 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
530 SALOME_Selection* Sel
531 = SALOME_Selection::Selection( myStudy->getSelection() );
533 vtkActorCollection* theActors = m_Renderer->GetActors();
534 theActors->InitTraversal();
535 vtkActor *ac = theActors->GetNextActor();
537 if ( ac->IsA("SALOME_Actor") ) {
538 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
539 if ( anActor->hasIO() ) {
540 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
541 if ( !IO->isSame(IObject) ) {
542 m_RWInteractor->Erase(IO, false);
543 Sel->RemoveIObject(IO, false);
545 anActor->SetVisibility(true);
546 Sel->AddIObject(IO, false);
550 ac = theActors->GetNextActor();
555 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& IObject, bool update)
557 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
558 SALOME_Selection* Sel
559 = SALOME_Selection::Selection( myStudy->getSelection() );
561 vtkActorCollection* theActors = m_Renderer->GetActors();
562 theActors->InitTraversal();
563 vtkActor *ac = theActors->GetNextActor();
566 if ( ac->IsA("SALOME_Actor") )
568 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
569 if ( anActor->hasIO() )
571 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
572 if ( IO->isSame( IObject ) ) {
573 m_RWInteractor->Erase(IO, false);
574 Sel->RemoveIObject(IO, false);
579 ac = theActors->GetNextActor();
586 void VTKViewer_ViewFrame::DisplayAll()
588 m_RWInteractor->DisplayAll();
592 void VTKViewer_ViewFrame::EraseAll()
594 m_RWInteractor->EraseAll();
598 void VTKViewer_ViewFrame::Repaint(bool theUpdateTrihedron)
600 if (theUpdateTrihedron) onAdjustTrihedron();
604 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
605 m_Transform->GetScale(theScale);
608 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
609 m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
610 m_RWInteractor->Render();
614 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool update /*=false*/ ){
615 theActor->SetVisibility(true);
616 theActor->AddToRender(m_Renderer);
617 theActor->SetTransform(m_Transform);
618 if(update) Repaint();
621 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool update /*=false*/ ){
622 theActor->RemoveFromRender(m_Renderer);
623 if(update) Repaint();