X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FOCCViewer%2FOCCViewer_ViewWindow.cxx;h=98ae2107b3d762f9126aefb8a6cfdf96aaf6061a;hb=259ecb356eb789678497db6b655cc3e377a67cce;hp=2b2d6d866b4f9d28e58667cb31635c2739676dad;hpb=bb8609caf7881d966fbb88dec0a7822736da93f5;p=modules%2Fgui.git diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 2b2d6d866..98ae2107b 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -29,10 +29,11 @@ #include "OCCViewer_ViewManager.h" #include "OCCViewer_ViewSketcher.h" #include "OCCViewer_CreateRestoreViewDlg.h" -#include "OCCViewer_ClippingDlg.h" +#include "OCCViewer_ClipPlane.h" #include "OCCViewer_SetRotationPointDlg.h" #include "OCCViewer_AxialScaleDlg.h" #include "OCCViewer_CubeAxesDlg.h" +#include "OCCViewer_ClippingDlg.h" #include @@ -64,6 +65,8 @@ #include #include +#include +#include #include #include @@ -77,8 +80,14 @@ #include #include +#include #include +#include +#include + +#include + #include #include "utilities.h" @@ -224,18 +233,21 @@ OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop* theDesktop, myEnableDrawMode = false; myDrawRect=false; updateEnabledDrawMode(); - myClippingDlg = 0; myScalingDlg = 0; mySetRotationPointDlg = 0; myRectBand = 0; IsSketcherStyle = false; + myIsKeyFree = false; mypSketcher = 0; myCurSketch = -1; my2dMode = No2dMode; myInteractionStyle = SUIT_ViewModel::STANDARD; + myPreselectionEnabled = true; + mySelectionEnabled = true; + clearViewAspects(); @@ -351,13 +363,26 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e ) case QEvent::Wheel: { QWheelEvent* aEvent = (QWheelEvent*) e; - myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() ); - double delta = (double)( aEvent->delta() ) / ( 15 * 8 ); - int x = aEvent->x(); - int y = aEvent->y(); - int x1 = (int)( aEvent->x() + width()*delta/100 ); - int y1 = (int)( aEvent->y() + height()*delta/100 ); - myViewPort->zoom( x, y, x1, y1 ); + + if ( aEvent->modifiers().testFlag(Qt::ControlModifier) ) { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + if ( isPreselectionEnabled() && ic->HasOpenedContext() ) { + if ( aEvent->delta() > 0 ) { + ic->HilightNextDetected( myViewPort->getView() ); + } else { + ic->HilightPreviousDetected( myViewPort->getView() ); + } + } + } else { + myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() ); + double delta = (double)( aEvent->delta() ) / ( 15 * 8 ); + int x = aEvent->x(); + int y = aEvent->y(); + int x1 = (int)( aEvent->x() + width()*delta/100 ); + int y1 = (int)( aEvent->y() + height()*delta/100 ); + myViewPort->zoom( x, y, x1, y1 ); + myViewPort->getView()->ZFitAll(); + } } return true; @@ -448,17 +473,24 @@ void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent ) default: /* Try to activate a transformation */ - switch ( getButtonState(theEvent, anInteractionStyle) ) { + OperationType aState; + if ( interactionStyle() == SUIT_ViewModel::STANDARD ) + aState = getButtonState(theEvent, anInteractionStyle); + else { + aState = OCCViewer_ViewWindow::NOTHING; + myIsKeyFree = true; + } + switch ( aState ) { case ZOOMVIEW: myViewPort->startZoomAtPoint( myStartX, myStartY ); activateZoom(); break; case PANVIEW: - activatePanning(); + activatePanning(); break; case ROTATE: - activateRotation(); - myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + activateRotation(); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); break; default: if ( myRotationPointSelection ) @@ -470,20 +502,38 @@ void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent ) for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() ) { TopoDS_Shape aShape = ic->SelectedShape(); + GProp_GProps aSystem; + gp_Pnt aPnt; if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) { - gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) ); - if ( mySetRotationPointDlg ) - { - myRotationPointSelection = false; - mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z()); - } + aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) ); + } + else if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_EDGE ) + { + BRepGProp::LinearProperties( aShape, aSystem ); + aPnt = aSystem.CentreOfMass(); + } + else if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_FACE ) + { + BRepGProp::SurfaceProperties( aShape, aSystem ); + aPnt = aSystem.CentreOfMass(); + } + else if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_SOLID ) + { + BRepGProp::VolumeProperties( aShape, aSystem ); + aPnt = aSystem.CentreOfMass(); } else { myCurrPointType = myPrevPointType; break; } + + if ( mySetRotationPointDlg ) + { + myRotationPointSelection = false; + mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z()); + } } if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType; if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange(); @@ -575,65 +625,102 @@ void OCCViewer_ViewWindow::activateRotation() */ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ ) { - Handle(Visual3d_View) aView = myViewPort->getView()->View(); + Handle(V3d_View) aView3d = myViewPort->getView(); - Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ; - Standard_Real Umin,Vmin,Umax,Vmax ; - Standard_Integer Nstruct,Npoint ; - Graphic3d_MapOfStructure MySetOfStructures; + // Project boundaries points and add to avergae gravity + // the ones which lie within the screen limits + Standard_Real aScreenLimits[4] = { 0.0, 0.0, 0.0, 0.0 }; - aView->DisplayedStructures (MySetOfStructures); - Nstruct = MySetOfStructures.Extent() ; +#if OCC_VERSION_LARGE > 0x06070100 + // NDC space screen limits + aScreenLimits[0] = -1.0; + aScreenLimits[1] = 1.0; + aScreenLimits[2] = -1.0; + aScreenLimits[3] = 1.0; +#else + aView3d->View()->ViewMapping().WindowLimit( aScreenLimits[0], + aScreenLimits[1], + aScreenLimits[2], + aScreenLimits[3] ); +#endif - Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ; - aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax) ; - Npoint = 0 ; theX = theY = theZ = 0. ; - for( ; MyIterator.More(); MyIterator.Next()) { - if (!(MyIterator.Key())->IsEmpty()) { - (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin, - Xmax,Ymax,Zmax) ; + Standard_Integer aPointsNb = 0; - Standard_Real LIM = ShortRealLast() -1.; - if (! (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM - || fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) { + Standard_Real aXmin = 0.0; + Standard_Real aYmin = 0.0; + Standard_Real aZmin = 0.0; + Standard_Real aXmax = 0.0; + Standard_Real aYmax = 0.0; + Standard_Real aZmax = 0.0; - aView->Projects(Xmin,Ymin,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ; - } - aView->Projects(Xmax,Ymin,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ; - } - aView->Projects(Xmin,Ymax,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ; - } - aView->Projects(Xmax,Ymax,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ; - } - aView->Projects(Xmin,Ymin,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ; - } - aView->Projects(Xmax,Ymin,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ; - } - aView->Projects(Xmin,Ymax,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ; - } - aView->Projects(Xmax,Ymax,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ; - } + Graphic3d_MapOfStructure aSetOfStructures; + aView3d->View()->DisplayedStructures( aSetOfStructures ); + Graphic3d_MapIteratorOfMapOfStructure aStructureIt( aSetOfStructures ); + + for( ; aStructureIt.More(); aStructureIt.Next() ) { + const Handle(Graphic3d_Structure)& aStructure = aStructureIt.Key(); + if ( aStructure->IsEmpty() ) { + continue; + } + +#if OCC_VERSION_LARGE > 0x06070100 + Bnd_Box aBox = aStructure->MinMaxValues(); + aXmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X(); + aYmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y(); + aZmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z(); + aXmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X(); + aYmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y(); + aZmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z(); +#else + aStructure->MinMaxValues( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); +#endif + + // Infinite structures are skipped + Standard_Real aLIM = ShortRealLast() - 1.0; + if ( Abs( aXmin ) > aLIM || Abs( aYmin ) > aLIM || Abs( aZmin ) > aLIM + || Abs( aXmax ) > aLIM || Abs( aYmax ) > aLIM || Abs( aZmax ) > aLIM ) { + continue; + } + + gp_Pnt aPoints[8] = { + gp_Pnt( aXmin, aYmin, aZmin ), gp_Pnt( aXmin, aYmin, aZmax ), + gp_Pnt( aXmin, aYmax, aZmin ), gp_Pnt( aXmin, aYmax, aZmax ), + gp_Pnt( aXmax, aYmin, aZmin ), gp_Pnt( aXmax, aYmin, aZmax ), + gp_Pnt( aXmax, aYmax, aZmin ), gp_Pnt( aXmax, aYmax, aZmax ) + }; + + for ( Standard_Integer aPointIt = 0; aPointIt < 8; ++aPointIt ) { + const gp_Pnt& aBBPoint = aPoints[aPointIt]; + +#if OCC_VERSION_LARGE > 0x06070100 + gp_Pnt aProjected = aView3d->Camera()->Project( aBBPoint ); + const Standard_Real& U = aProjected.X(); + const Standard_Real& V = aProjected.Y(); +#else + Standard_Real U = 0.0; + Standard_Real V = 0.0; + Standard_Real W = 0.0; + aView3d->View()->Projects( aBBPoint.X(), aBBPoint.Y(), aBBPoint.Z(), U, V, W ); +#endif + + if (U >= aScreenLimits[0] + && U <= aScreenLimits[1] + && V >= aScreenLimits[2] + && V <= aScreenLimits[3]) + { + aPointsNb++; + theX += aBBPoint.X(); + theY += aBBPoint.Y(); + theZ += aBBPoint.Z(); } } } - if( Npoint > 0 ) { - theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ; + + if ( aPointsNb > 0 ) + { + theX /= aPointsNb; + theY /= aPointsNb; + theZ /= aPointsNb; } return true; } @@ -699,9 +786,9 @@ void OCCViewer_ViewWindow::activateSetRotationSelected( double theX, double theY } /*! - \brief Start the point selection process. + \brief Start the shape selection process. */ -void OCCViewer_ViewWindow::activateStartPointSelection() +void OCCViewer_ViewWindow::activateStartPointSelection( TopAbs_ShapeEnum theShapeType ) { myPrevPointType = myCurrPointType; myCurrPointType = SELECTED; @@ -720,7 +807,7 @@ void OCCViewer_ViewWindow::activateStartPointSelection() anObj->IsKind( STANDARD_TYPE(AIS_Shape) ) ) { ic->Load(anObj,-1); - ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX)); + ic->Activate(anObj,AIS_Shape::SelectionMode(theShapeType)); } } // activate selection <------ @@ -792,6 +879,25 @@ bool OCCViewer_ViewWindow::setTransformRequested( OperationType op ) */ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) { + if ( myIsKeyFree && interactionStyle() == SUIT_ViewModel::KEY_FREE ) { + myIsKeyFree = false; + switch ( getButtonState( theEvent, interactionStyle() ) ) { + case ZOOMVIEW: + myViewPort->startZoomAtPoint( myStartX, myStartY ); + activateZoom(); + break; + case PANVIEW: + activatePanning(); + break; + case ROTATE: + activateRotation(); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + break; + default: + break; + } + } + myCurrX = theEvent->x(); myCurrY = theEvent->y(); switch (myOperation) { @@ -829,8 +935,10 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) int aState = theEvent->modifiers(); int aButton = theEvent->buttons(); int anInteractionStyle = interactionStyle(); - if ( anInteractionStyle == SUIT_ViewModel::STANDARD && - aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) { + if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && + aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || + ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + aButton == Qt::LeftButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { myDrawRect = myEnableDrawMode; if ( myDrawRect ) { drawRect(); @@ -843,8 +951,10 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) } emit mouseMoving( this, theEvent ); } - else if ( anInteractionStyle == SUIT_ViewModel::STANDARD && - aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) { + else if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && + aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || + ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + aButton == Qt::RightButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { OCCViewer_ViewSketcher* sketcher = 0; QList::Iterator it; for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) @@ -913,6 +1023,7 @@ void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent) case PANVIEW: case ZOOMVIEW: + myViewPort->getView()->ZFitAll(); resetState(); break; @@ -1171,12 +1282,12 @@ void OCCViewer_ViewWindow::createActions() connect(aAction, SIGNAL(triggered()), this, SLOT(onCloneView())); toolMgr()->registerAction( aAction, CloneId ); - myClippingAction = new QtxAction(tr("MNU_CLIPPING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ) ), - tr( "MNU_CLIPPING" ), 0, this); - myClippingAction->setStatusTip(tr("DSC_CLIPPING")); - myClippingAction->setCheckable( true ); - connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool ))); - toolMgr()->registerAction( myClippingAction, ClippingId ); + aAction = new QtxAction (tr("MNU_CLIPPING"), aResMgr->loadPixmap ("OCCViewer", tr("ICON_OCCVIEWER_CLIPPING")), + tr("MNU_CLIPPING"), 0, this); + aAction->setStatusTip (tr("DSC_CLIPPING")); + aAction->setCheckable (true); + connect (aAction, SIGNAL (toggled (bool)), this, SLOT (onClipping (bool))); + toolMgr()->registerAction (aAction, ClippingId); aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ), tr( "MNU_SHOOT_VIEW" ), 0, this); @@ -1193,8 +1304,10 @@ void OCCViewer_ViewWindow::createActions() if (myModel->trihedronActivated()) { aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ), tr( "MNU_SHOW_TRIHEDRE" ), 0, this); + aAction->setCheckable( true ); + aAction->setChecked( true ); aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow())); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onTrihedronShow(bool))); toolMgr()->registerAction( aAction, TrihedronShowId ); } @@ -1205,6 +1318,22 @@ void OCCViewer_ViewWindow::createActions() connect(aAction, SIGNAL(triggered()), this, SLOT(onAxialScale())); toolMgr()->registerAction( aAction, AxialScaleId ); + // Enable/disable preselection + aAction = new QtxAction(tr("MNU_ENABLE_PRESELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESELECTION" ) ), + tr( "MNU_ENABLE_PRESELECTION" ), 0, this); + aAction->setStatusTip(tr("DSC_ENABLE_PRESELECTION")); + aAction->setCheckable(true); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchPreselection(bool))); + toolMgr()->registerAction( aAction, SwitchPreselectionId ); + + // Enable/disable selection + aAction = new QtxAction(tr("MNU_ENABLE_SELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SELECTION" ) ), + tr( "MNU_ENABLE_SELECTION" ), 0, this); + aAction->setStatusTip(tr("DSC_ENABLE_SELECTION")); + aAction->setCheckable(true); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchSelection(bool))); + toolMgr()->registerAction( aAction, SwitchSelectionId ); + // Graduated axes aAction = new QtxAction(tr("MNU_GRADUATED_AXES"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_GRADUATED_AXES" ) ), tr( "MNU_GRADUATED_AXES" ), 0, this); @@ -1242,6 +1371,15 @@ void OCCViewer_ViewWindow::createActions() connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView())); toolMgr()->registerAction( aAction, MaximizedId ); + // Return to 3d view + if (my2dMode!=No2dMode){ + aAction = new QtxAction(tr("MNU_RETURN_3D_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RETURN_3D_VIEW" ) ), + tr( "MNU_RETURN_3D_VIEW" ), 0, this ); + aAction->setStatusTip(tr("DSC_RETURN_3D_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(returnTo3dView())); + toolMgr()->registerAction( aAction, ReturnTo3dViewId ); + } + // Synchronize View toolMgr()->registerAction( synchronizeAction(), SynchronizeId ); } @@ -1251,28 +1389,30 @@ void OCCViewer_ViewWindow::createActions() */ void OCCViewer_ViewWindow::createToolBar() { - QString aToolbarName; - switch (my2dMode) { - case XYPlane: - aToolbarName = tr( "LBL_XYTOOLBAR_LABEL" ); - break; - case XZPlane: - aToolbarName = tr( "LBL_XZTOOLBAR_LABEL" ); - break; - case YZPlane: - aToolbarName = tr( "LBL_YZTOOLBAR_LABEL" ); - break; - default: - aToolbarName = tr( "LBL_3DTOOLBAR_LABEL" ); + static const char* titles[] = { + "LBL_3DTOOLBAR_LABEL", + "LBL_XYTOOLBAR_LABEL", + "LBL_XZTOOLBAR_LABEL", + "LBL_YZTOOLBAR_LABEL", + }; + static const char* names[] = { + "OCCViewer3DViewOperations", + "OCCViewerXYViewOperations", + "OCCViewerXZViewOperations", + "OCCViewerYZViewOperations", + }; + int tid = toolMgr()->createToolBar( tr( titles[my2dMode] ), // title (language-dependant) + QString( names[my2dMode] ), // name (language-independant) + false ); // disable floatable toolbar + if ( my2dMode != No2dMode ){ + toolMgr()->append( ReturnTo3dViewId, tid ); + toolMgr()->append( toolMgr()->separator(), tid ); } - - int tid = toolMgr()->createToolBar( aToolbarName, false ); - toolMgr()->append( DumpId, tid ); toolMgr()->append( SwitchInteractionStyleId, tid ); -#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version toolMgr()->append( SwitchZoomingStyleId, tid ); -#endif + toolMgr()->append( SwitchPreselectionId, tid ); + toolMgr()->append( SwitchSelectionId, tid ); if( myModel->trihedronActivated() ) toolMgr()->append( TrihedronShowId, tid ); @@ -1317,9 +1457,7 @@ void OCCViewer_ViewWindow::createToolBar() toolMgr()->append( toolMgr()->separator(), tid ); toolMgr()->append( ClippingId, tid ); toolMgr()->append( AxialScaleId, tid ); -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version toolMgr()->append( GraduatedAxesId, tid ); -#endif toolMgr()->append( AmbientId, tid ); toolMgr()->append( MaximizedId, tid ); @@ -1495,44 +1633,6 @@ void OCCViewer_ViewWindow::onCloneView() emit viewCloned( vw ); } -/*! - \brief called if clipping operation is activated. - - Enables/disables clipping plane displaying. - - \parma on action state -*/ -void OCCViewer_ViewWindow::onClipping( bool on ) -{ - /* - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - if ( on ) - myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING_PRESSED" ))); - else - myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ))); - */ - OCCViewer_ViewWindow* aParent = dynamic_cast(parent()->parent()); - if (!aParent) - aParent = this; - if ( on ) - { - if ( !myClippingDlg ) - { - myClippingDlg = new OCCViewer_ClippingDlg( aParent ); - myClippingDlg->SetAction( myClippingAction ); - } - - if ( !myClippingDlg->isVisible() ) - myClippingDlg->show(); - } - else - { - if ( myClippingDlg->isVisible() ) - myClippingDlg->hide(); - aParent->setCuttingPlane(false); - } -} - /*! Creates one more window with same content */ @@ -1606,7 +1706,6 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False ); aView3d->SetScale( anItem.scale ); - aView3d->SetCenter( anItem.centerX, anItem.centerY ); aView3d->SetTwist( anItem.twist ); aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ ); aView3d->SetImmediateUpdate( prev ); @@ -1614,12 +1713,37 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ ); aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ ); +#if OCC_VERSION_LARGE > 0x06070100 + if ( anItem.centerX != 0.0 || anItem.centerY != 0.0 ) + { + double anUpX = 0.0, anUpY = 0.0, anUpZ = 0.0; + + // "eye" and "at" require conversion to represent center panning + // up direction is only available after setting angle of twist and + // other view parameters + aView3d->Up( anUpX, anUpY, anUpZ ); + + gp_Dir aProj( -anItem.projX, -anItem.projY, -anItem.projZ ); + gp_Dir anUp( anUpX, anUpY, anUpZ ); + gp_Pnt anAt( anItem.atX, anItem.atY, anItem.atZ ); + gp_Pnt anEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ ); + gp_Dir aSide = aProj ^ anUp; + + anAt.Translate( gp_Vec( aSide ) * anItem.centerX ); + anAt.Translate( gp_Vec( anUp ) * anItem.centerY ); + + aView3d->SetAt( anAt.X(), anAt.Y(), anAt.Z() ); + aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ ); + } +#else + aView3d->SetCenter( anItem.centerX, anItem.centerY ); +#endif + if ( !baseParamsOnly ) { myModel->setTrihedronShown( anItem.isVisible ); myModel->setTrihedronSize( anItem.size ); -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version // graduated trihedron bool anIsVisible = anItem.gtIsVisible; OCCViewer_AxisWidget::AxisData anAxisData[3]; @@ -1630,14 +1754,14 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base anAxisData[1].Name = anItem.gtNameZ; anAxisData[2].Name = anItem.gtNameZ; anAxisData[0].NameColor = QColor( anItem.gtNameColorRX, - anItem.gtNameColorGX, - anItem.gtNameColorBX ); + anItem.gtNameColorGX, + anItem.gtNameColorBX ); anAxisData[1].NameColor = QColor( anItem.gtNameColorRY, - anItem.gtNameColorGY, - anItem.gtNameColorBY ); + anItem.gtNameColorGY, + anItem.gtNameColorBY ); anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ, - anItem.gtNameColorGZ, - anItem.gtNameColorBZ ); + anItem.gtNameColorGZ, + anItem.gtNameColorBZ ); anAxisData[0].DrawValues = anItem.gtDrawValuesX; anAxisData[1].DrawValues = anItem.gtDrawValuesY; anAxisData[2].DrawValues = anItem.gtDrawValuesZ; @@ -1648,14 +1772,14 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base anAxisData[1].Offset = anItem.gtOffsetY; anAxisData[2].Offset = anItem.gtOffsetZ; anAxisData[0].Color = QColor( anItem.gtColorRX, - anItem.gtColorGX, - anItem.gtColorBX ); + anItem.gtColorGX, + anItem.gtColorBX ); anAxisData[1].Color = QColor( anItem.gtColorRY, - anItem.gtColorGY, - anItem.gtColorBY ); + anItem.gtColorGY, + anItem.gtColorBY ); anAxisData[2].Color = QColor( anItem.gtColorRZ, - anItem.gtColorGZ, - anItem.gtColorBZ ); + anItem.gtColorGZ, + anItem.gtColorBZ ); anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX; anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY; anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ; @@ -1665,7 +1789,6 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base myCubeAxesDlg->SetData( anIsVisible, anAxisData ); myCubeAxesDlg->ApplyData( aView3d ); -#endif } // if ( !baseParamsOnly ) @@ -1683,9 +1806,52 @@ void OCCViewer_ViewWindow::setRestoreFlag() /*! \brief Called when action "show/hide trihedron" is activated. */ -void OCCViewer_ViewWindow::onTrihedronShow() +void OCCViewer_ViewWindow::onTrihedronShow(bool show) { - myModel->toggleTrihedron(); + myModel->setTrihedronShown(show); +} + +/*! + \brief Toggles preselection (highlighting) on/off +*/ +void OCCViewer_ViewWindow::onSwitchPreselection( bool on ) +{ + myPreselectionEnabled = on; + myModel->setSelectionOptions( isPreselectionEnabled(), myModel->isSelectionEnabled() ); + + // unhighlight all highlighted objects + /*if ( !on ) { + myModel->unHighlightAll( true, false ); + }*/ + + // update action state if method is called outside + QtxAction* a = dynamic_cast( toolMgr()->action( SwitchPreselectionId ) ); + if ( a && a->isChecked() != on ) { + a->setChecked( on ); + } +} + +/*! + \brief Toggles selection on/off +*/ +void OCCViewer_ViewWindow::onSwitchSelection( bool on ) +{ + mySelectionEnabled = on; + myModel->setSelectionOptions( myModel->isPreselectionEnabled(), isSelectionEnabled() ); + + // update action state if method is called outside + + // preselection + QtxAction* a = dynamic_cast( toolMgr()->action( SwitchPreselectionId ) ); + if ( a ) { + a->setEnabled( on ); + } + + // selection + a = dynamic_cast( toolMgr()->action( SwitchSelectionId ) ); + if ( a && a->isChecked() != on ) { + a->setChecked( on ); + } } /*! @@ -1762,6 +1928,10 @@ QImage OCCViewer_ViewWindow::dumpView() int aWidth = myViewPort->width(); int aHeight = myViewPort->height(); + + // rnv: An old approach to dump the OCCViewer content + // Now used OCCT built-in procedure. + /* QApplication::syncX(); view->Redraw(); // In order to reactivate GL context //view->Update(); @@ -1798,10 +1968,13 @@ QImage OCCViewer_ViewWindow::dumpView() glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, data); + */ + + Image_PixMap aPix; + view->ToPixMap(aPix,aWidth, aHeight,Graphic3d_BT_RGBA); - QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 ); + QImage anImage( aPix.Data(), aWidth, aHeight, QImage::Format_ARGB32 ); anImage = anImage.mirrored(); - anImage = anImage.rgbSwapped(); return anImage; } @@ -1851,33 +2024,30 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const doub // try to use already existing plane or create a new one Handle(V3d_Plane) clipPlane; - view->InitActivePlanes(); // calculate new a,b,c,d values for the plane gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz)); double a, b, c, d; pln.Coefficients(a, b, c, d); - -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 - if (view->MoreActivePlanes()) { - clipPlane = view->ActivePlane(); - clipPlane->SetPlane(a, b, c, d); + + Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); + if(aPlanes.Size() > 0 ) { + Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); + Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); + aClipPlane->SetEquation(pln); + aClipPlane->SetOn(Standard_True); + } else { + view->AddClipPlane( myModel->createClipPlane( pln, Standard_True ) ); + } + } + else { + Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); + Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); + for( ;anIter.More();anIter.Next() ){ + Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); + aClipPlane->SetOn(Standard_False); } - else - clipPlane = new V3d_Plane (a, b, c, d); -#else - if (view->MoreActivePlanes()) - clipPlane = view->ActivePlane(); - else - clipPlane = new V3d_Plane (viewer); - - clipPlane->SetPlane(a, b, c, d); -#endif - - view->SetPlaneOn(clipPlane); } - else - view->SetPlaneOff(); view->Update(); view->Redraw(); @@ -1898,8 +2068,17 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const gp_Pln pln ) bool OCCViewer_ViewWindow::isCuttingPlane() { Handle(V3d_View) view = myViewPort->getView(); - view->InitActivePlanes(); - return (view->MoreActivePlanes()); + bool res = false; + Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); + Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); + for( ;anIter.More();anIter.Next() ) { + Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); + if(aClipPlane->IsOn()) { + res = true; + break; + } + } + return res; } /*! @@ -1908,13 +2087,12 @@ bool OCCViewer_ViewWindow::isCuttingPlane() */ viewAspect OCCViewer_ViewWindow::getViewParams() const { - double centerX, centerY, projX, projY, projZ, twist; + double projX, projY, projZ, twist; double atX, atY, atZ, eyeX, eyeY, eyeZ; double aScaleX, aScaleY, aScaleZ; Handle(V3d_View) aView3d = myViewPort->getView(); - aView3d->Center( centerX, centerY ); aView3d->Proj( projX, projY, projZ ); aView3d->At( atX, atY, atZ ); aView3d->Eye( eyeX, eyeY, eyeZ ); @@ -1929,8 +2107,6 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const viewAspect params; params.scale = aView3d->Scale(); - params.centerX = centerX; - params.centerY = centerY; params.projX = projX; params.projY = projY; params.projZ = projZ; @@ -1948,7 +2124,10 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const params.isVisible= isShown; params.size = size; -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version +#if OCC_VERSION_LARGE <= 0x06070100 // the property is deprecated after OCCT 6.7.1 + aView3d->Center( params.centerX, params.centerY ); +#endif + // graduated trihedron bool anIsVisible = false; OCCViewer_AxisWidget::AxisData anAxisData[3]; @@ -1994,12 +2173,10 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const params.gtTickmarkLengthX = anAxisData[0].TickmarkLength; params.gtTickmarkLengthY = anAxisData[1].TickmarkLength; params.gtTickmarkLengthZ = anAxisData[2].TickmarkLength; -#endif return params; } - /*! \brief Get visual parameters of this view window. \return visual parameters of view window @@ -2011,8 +2188,10 @@ QString OCCViewer_ViewWindow::getVisualParameters() QStringList data; data << QString( "scale=%1" ) .arg( params.scale, 0, 'e', 12 ); +#if OCC_VERSION_LARGE <= 0x06070100 // the property is deprecated after OCCT 6.7.1 data << QString( "centerX=%1" ) .arg( params.centerX, 0, 'e', 12 ); data << QString( "centerY=%1" ) .arg( params.centerY, 0, 'e', 12 ); +#endif data << QString( "projX=%1" ) .arg( params.projX, 0, 'e', 12 ); data << QString( "projY=%1" ) .arg( params.projY, 0, 'e', 12 ); data << QString( "projZ=%1" ) .arg( params.projZ, 0, 'e', 12 ); @@ -2029,7 +2208,47 @@ QString OCCViewer_ViewWindow::getVisualParameters() data << QString( "isVisible=%1" ).arg( params.isVisible ); data << QString( "size=%1" ) .arg( params.size, 0, 'f', 2 ); -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 or newer version + ClipPlanesList aPlanes = myModel->getClipPlanes(); + for ( int i=0; i < aPlanes.size(); i++ ) + { + OCCViewer_ClipPlane& aPlane = aPlanes[i]; + QString ClippingPlane = QString( "ClippingPlane%1=").arg( i+1 ); + ClippingPlane += QString( "Mode~%1;").arg( (int)aPlane.Mode ); + ClippingPlane += QString( "IsActive~%1;").arg( aPlane.IsOn ); + switch ( aPlane.Mode ) + { + case OCCViewer_ClipPlane::Absolute : + { + ClippingPlane += QString( "AbsoluteOrientation~%1;" ).arg( aPlane.OrientationType ); + + if ( aPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom ) + { + ClippingPlane += QString( "Dx~%1;" ).arg( aPlane.AbsoluteOrientation.Dx ); + ClippingPlane += QString( "Dy~%1;" ).arg( aPlane.AbsoluteOrientation.Dy ); + ClippingPlane += QString( "Dz~%1;" ).arg( aPlane.AbsoluteOrientation.Dz ); + } + else + { + ClippingPlane += QString( "IsInvert~%1;" ).arg( aPlane.AbsoluteOrientation.IsInvert ); + } + } + break; + + case OCCViewer_ClipPlane::Relative : + { + ClippingPlane += QString( "RelativeOrientation~%1;" ).arg( aPlane.OrientationType ); + ClippingPlane += QString( "Rotation1~%1;" ).arg( aPlane.RelativeOrientation.Rotation1 ); + ClippingPlane += QString( "Rotation2~%1" ).arg( aPlane.RelativeOrientation.Rotation2 ); + } + break; + } + + ClippingPlane += QString( "X~%1;" ).arg( aPlane.X ); + ClippingPlane += QString( "Y~%1;" ).arg( aPlane.Y ); + ClippingPlane += QString( "Z~%1;" ).arg( aPlane.Z ); + data << ClippingPlane; + } + // graduated trihedron data << QString( "gtIsVisible=%1" ) .arg( params.gtIsVisible ); data << QString( "gtDrawNameX=%1" ) .arg( params.gtDrawNameX ); @@ -2071,7 +2290,6 @@ QString OCCViewer_ViewWindow::getVisualParameters() data << QString( "gtTickmarkLengthX=%1" ).arg( params.gtTickmarkLengthX ); data << QString( "gtTickmarkLengthY=%1" ).arg( params.gtTickmarkLengthY ); data << QString( "gtTickmarkLengthZ=%1" ).arg( params.gtTickmarkLengthZ ); -#endif QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" ); data << QString( "background=%1" ).arg( bg ); @@ -2085,7 +2303,7 @@ QString OCCViewer_ViewWindow::getVisualParameters() void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) { viewAspect params; - + ClipPlanesList aClipPlanes; QStringList data = parameters.split( '*' ); Qtx::BackgroundData bgData; if ( parameters.contains( '=' ) ) // new format - "scale=1.000e+00*centerX=0.000e+00..." @@ -2111,6 +2329,44 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) else if ( paramName == "scaleZ" ) params.scaleZ = paramValue.toDouble(); else if ( paramName == "isVisible" ) params.isVisible = paramValue.toInt(); else if ( paramName == "size" ) params.size = paramValue.toDouble(); + else if ( paramName.contains( "ClippingPlane" ) ) + { + QStringList ClipPlaneData = paramValue.split( ';' ); + OCCViewer_ClipPlane aPlane; + foreach( QString ClipPlaneParam, ClipPlaneData ) + { + QString ClipPlane_paramName = ClipPlaneParam.section( '~', 0, 0 ).trimmed(); + QString ClipPlane_paramValue = ClipPlaneParam.section( '~', 1, 1 ).trimmed(); + if ( ClipPlane_paramName == "Mode" ) + { + aPlane.Mode = ( OCCViewer_ClipPlane::PlaneMode ) ClipPlane_paramValue.toInt(); + } + else if ( ClipPlane_paramName == "IsActive" ) aPlane.IsOn = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "X" ) aPlane.X = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Y" ) aPlane.Y = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Z" ) aPlane.Z = ClipPlane_paramValue.toDouble(); + else + { + switch ( aPlane.Mode ) + { + case OCCViewer_ClipPlane::Absolute : + if ( ClipPlane_paramName == "Dx" ) aPlane.AbsoluteOrientation.Dx = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dy" ) aPlane.AbsoluteOrientation.Dy = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dz" ) aPlane.AbsoluteOrientation.Dz = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "IsInvert" ) aPlane.AbsoluteOrientation.IsInvert = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "AbsoluteOrientation" ) aPlane.OrientationType = ClipPlane_paramValue.toInt(); + break; + + case OCCViewer_ClipPlane::Relative : + if ( ClipPlane_paramName == "RelativeOrientation" ) aPlane.OrientationType = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "Rotation1" ) aPlane.RelativeOrientation.Rotation1 = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Rotation2" ) aPlane.RelativeOrientation.Rotation2 = ClipPlane_paramValue.toDouble(); + break; + } + } + } + aClipPlanes.push_back(aPlane); + } // graduated trihedron else if ( paramName == "gtIsVisible" ) params.gtIsVisible = paramValue.toInt(); else if ( paramName == "gtDrawNameX" ) params.gtDrawNameX = paramValue.toInt(); @@ -2153,8 +2409,8 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt(); else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt(); else if ( paramName == "background" ) { - QString bg = paramValue.replace( "$", "=" ); - bgData = Qtx::stringToBackground( bg ); + QString bg = paramValue.replace( "$", "=" ); + bgData = Qtx::stringToBackground( bg ); } } } @@ -2180,8 +2436,9 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) params.isVisible = data.count() > idx ? data[idx++].toInt() : 1; params.size = data.count() > idx ? data[idx++].toDouble() : 100.0; } - performRestoring( params ); + performRestoring( params ); setBackground( bgData ); + myModel->setClipPlanes(aClipPlanes); } /*! @@ -2294,7 +2551,7 @@ void OCCViewer_ViewWindow::onSketchingFinished() if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept ) { Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - bool append = bool( mypSketcher->buttonState() & Qt::ShiftModifier ); + bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() ); switch( mypSketcher->type() ) { case Rect: @@ -2388,16 +2645,34 @@ void OCCViewer_ViewWindow::onMaximizedView() setMaximized(!isMaximized()); } +void OCCViewer_ViewWindow::returnTo3dView() +{ + setReturnedTo3dView( true ); +} + +void OCCViewer_ViewWindow::setReturnedTo3dView(bool isVisible3dView) +{ + if ( !toolMgr()->action( ReturnTo3dViewId ) || + toolMgr()->isShown(ReturnTo3dViewId) != isVisible3dView ) return; + if ( !isVisible3dView ) + toolMgr()->show( ReturnTo3dViewId ); + else + toolMgr()->hide( ReturnTo3dViewId ); + if ( isVisible3dView ) emit returnedTo3d( ); +} + void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal) { QAction* anAction = toolMgr()->action( MaximizedId ); + QAction* anAction2 = toolMgr()->action( ReturnTo3dViewId ); SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); if ( toMaximize ) { anAction->setText( tr( "MNU_MINIMIZE_VIEW" ) ); anAction->setToolTip( tr( "MNU_MINIMIZE_VIEW" ) ); anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ) ); anAction->setStatusTip( tr( "DSC_MINIMIZE_VIEW" ) ); + if ( anAction2 && my2dMode != No2dMode ) toolMgr()->show( ReturnTo3dViewId ); if (toSendSignal) { emit maximized( this, true ); } @@ -2407,13 +2682,13 @@ void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal) anAction->setToolTip( tr( "MNU_MAXIMIZE_VIEW" ) ); anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MAXIMIZE" ) ) ); anAction->setStatusTip( tr( "DSC_MAXIMIZE_VIEW" ) ); + if ( anAction2 && my2dMode != No2dMode ) toolMgr()->hide( ReturnTo3dViewId ); if (toSendSignal) { emit maximized( this, false ); } } } - bool OCCViewer_ViewWindow::isMaximized() const { return !(toolMgr()->action( MaximizedId )->text() == tr( "MNU_MAXIMIZE_VIEW" )); @@ -2457,6 +2732,11 @@ void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackgrou if ( myViewPort ) myViewPort->setBackground( theBackground ); } +void OCCViewer_ViewWindow::showStaticTrihedron( bool on ) +{ + if ( myViewPort ) myViewPort->showStaticTrihedron( on ); +} + /*! Clears view aspects */ @@ -2510,59 +2790,85 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() aProps.setDimension( SUIT_CameraProperties::Dim2D ); aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() ); } - + // read common properites of the view - Standard_Real anUpDir[3]; - Standard_Real aPrjDir[3]; - Standard_Real aMapScale[2]; - Standard_Real aTranslation[3]; + Standard_Real anUp[3]; + Standard_Real anAt[3]; + Standard_Real anEye[3]; + Standard_Real aProj[3]; Standard_Real anAxialScale[3]; - - aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]); - aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]); - aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]); - aSourceView->Size(aMapScale[0], aMapScale[1]); - getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + aSourceView->Up( anUp[0], anUp[1], anUp[2] ); + aSourceView->At( anAt[0], anAt[1], anAt[2] ); + aSourceView->Proj( aProj[0], aProj[1], aProj[2] ); + getViewPort()->getAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); + + aProps.setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); + aProps.setViewUp( anUp[0], anUp[1], anUp[2] ); - // we use similar depth to the one used in perspective projection - // to proivde a convinience synchronization with other camera views that - // can switch between orthogonal & perspective projection. otherwise, - // the camera will get to close when switching from orthogonal to perspective. +#if OCC_VERSION_LARGE > 0x06070100 + aSourceView->Eye( anEye[0], anEye[1], anEye[2] ); + + // store camera properties "as is": it is up to synchronized + // view classes to provide necessary property conversion. + aProps.setPosition( anEye[0], anEye[1], anEye[2] ); + aProps.setFocalPoint( anAt[0], anAt[1], anAt[2] ); + + if ( aSourceView->Camera()->IsOrthographic() ) + { + aProps.setProjection( SUIT_CameraProperties::PrjOrthogonal ); + aProps.setViewAngle( 0.0 ); + } + else + { + aProps.setProjection( SUIT_CameraProperties::PrjPerspective ); + aProps.setViewAngle( aSourceView->Camera()->FOVy() ); + } + aProps.setMappingScale( aSourceView->Camera()->Scale() ); +#else Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5; - // store common props - aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); - aProps.setMappingScale(aMapScale[1] / 2.0); - aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - // generate view orientation matrix for transforming OCC projection reference point // into a camera (eye) position. - gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( - gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2])); + gp_Dir aLeftDir = gp_Dir( anUp[0], anUp[1], anUp[2] ) ^ gp_Dir( aProj[0], aProj[1], aProj[2] ); - gp_Trsf aTrsf; - aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0], - aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1], - aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2], - Precision::Confusion(), - Precision::Confusion() ); + gp_GTrsf aTrsf; + aTrsf.SetValue( 1, 1, aLeftDir.X() ); + aTrsf.SetValue( 2, 1, aLeftDir.Y() ); + aTrsf.SetValue( 3, 1, aLeftDir.Z() ); + + aTrsf.SetValue( 1, 2, anUp[0] ); + aTrsf.SetValue( 2, 2, anUp[1] ); + aTrsf.SetValue( 3, 2, anUp[2] ); + + aTrsf.SetValue( 1, 3, aProj[0] ); + aTrsf.SetValue( 2, 3, aProj[1] ); + aTrsf.SetValue( 3, 3, aProj[2] ); + + aTrsf.SetValue( 1, 4, anAt[0] ); + aTrsf.SetValue( 2, 4, anAt[1] ); + aTrsf.SetValue( 3, 4, anAt[2] ); - // get projection reference point in view coordinates Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint(); - + // transform to world-space coordinate system - gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf); - + gp_XYZ aPosition( aProjRef.X(), aProjRef.Y(), aCameraDepth ); + aTrsf.Transforms( aPosition ); + // compute focal point double aFocalPoint[3]; - aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth; - aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth; - aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth; + aFocalPoint[0] = aPosition.X() - aProj[0] * aCameraDepth; + aFocalPoint[1] = aPosition.Y() - aProj[1] * aCameraDepth; + aFocalPoint[2] = aPosition.Z() - aProj[2] * aCameraDepth; + + aProps.setFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] ); + aProps.setPosition( aPosition.X(), aPosition.Y(), aPosition.Z() ); - aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); - aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z()); + Standard_Real aViewScale[2]; + aSourceView->Size( aViewScale[0], aViewScale[1] ); + aProps.setMappingScale( aViewScale[1] ); +#endif return aProps; } @@ -2590,39 +2896,52 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) double anUpDir[3]; double aPosition[3]; double aFocalPoint[3]; - double aMapScaling; double anAxialScale[3]; // get common properties - aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); - aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]); - aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); - aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - aMapScaling = aProps.getMappingScale() * 2.0; - - gp_Dir aProjDir(aPosition[0] - aFocalPoint[0], - aPosition[1] - aFocalPoint[1], - aPosition[2] - aFocalPoint[2]); - + aProps.getFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] ); + aProps.getPosition( aPosition[0], aPosition[1], aPosition[2] ); + aProps.getViewUp( anUpDir[0], anUpDir[1], anUpDir[2] ); + aProps.getAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); + +#if OCC_VERSION_LARGE > 0x06070100 + aDestView->SetAt( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] ); + aDestView->SetEye( aPosition[0], aPosition[1], aPosition[2] ); + aDestView->SetUp( anUpDir[0], anUpDir[1], anUpDir[2] ); + aDestView->Camera()->SetScale( aProps.getMappingScale() ); +#else + gp_Dir aProjDir( aPosition[0] - aFocalPoint[0], + aPosition[1] - aFocalPoint[1], + aPosition[2] - aFocalPoint[2] ); + // get custom view translation Standard_Real aTranslation[3]; - aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]); - - gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( - gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z())); - - // convert camera position into a view reference point - gp_Trsf aTrsf; - aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0], - aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1], - aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], - Precision::Confusion(), - Precision::Confusion() ); + aDestView->At( aTranslation[0], aTranslation[1], aTranslation[2] ); + + gp_Dir aLeftDir = gp_Dir( anUpDir[0], anUpDir[1], anUpDir[2] ) + ^ gp_Dir( aProjDir.X(), aProjDir.Y(), aProjDir.Z() ); + + gp_GTrsf aTrsf; + aTrsf.SetValue( 1, 1, aLeftDir.X() ); + aTrsf.SetValue( 2, 1, aLeftDir.Y() ); + aTrsf.SetValue( 3, 1, aLeftDir.Z() ); + + aTrsf.SetValue( 1, 2, anUpDir[0] ); + aTrsf.SetValue( 2, 2, anUpDir[1] ); + aTrsf.SetValue( 3, 2, anUpDir[2] ); + + aTrsf.SetValue( 1, 3, aProjDir.X() ); + aTrsf.SetValue( 2, 3, aProjDir.Y() ); + aTrsf.SetValue( 3, 3, aProjDir.Z() ); + + aTrsf.SetValue( 1, 4, aTranslation[0] ); + aTrsf.SetValue( 2, 4, aTranslation[1] ); + aTrsf.SetValue( 3, 4, aTranslation[2] ); aTrsf.Invert(); // transform to view-space coordinate system - gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]); - aProjRef.Transform(aTrsf); + gp_XYZ aProjRef( aPosition[0], aPosition[1], aPosition[2] ); + aTrsf.Transforms( aProjRef ); // set view camera properties using low-level approach. this is done // in order to avoid interference with static variables in v3d view used @@ -2630,31 +2949,29 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping(); Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation(); - Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z()); - Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]); + Graphic3d_Vector aMappingProj( aProjDir.X(), aProjDir.Y(), aProjDir.Z() ); + Graphic3d_Vector aMappingUp( anUpDir[0], anUpDir[1], anUpDir[2] ); aMappingProj.Normalize(); aMappingUp.Normalize(); - anOrientation.SetViewReferencePlane(aMappingProj); - anOrientation.SetViewReferenceUp(aMappingUp); + anOrientation.SetViewReferencePlane( aMappingProj ); + anOrientation.SetViewReferenceUp( aMappingUp ); - aDestView->SetViewMapping(aMapping); - aDestView->SetViewOrientation(anOrientation); + aDestView->SetViewMapping( aMapping ); + aDestView->SetViewOrientation( anOrientation ); // set panning - aDestView->SetCenter(aProjRef.X(), aProjRef.Y()); + aDestView->SetCenter( aProjRef.X(), aProjRef.Y() ); // set mapping scale + double aMapScaling = aProps.getMappingScale(); Standard_Real aWidth, aHeight; - aDestView->Size(aWidth, aHeight); - - if ( aWidth > aHeight ) - aDestView->SetSize (aMapScaling * (aWidth / aHeight)); - else - aDestView->SetSize (aMapScaling); + aDestView->Size( aWidth, aHeight ); + aDestView->SetSize ( aWidth > aHeight ? aMapScaling * (aWidth / aHeight) : aMapScaling ); +#endif - getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + getViewPort()->setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); aDestView->ZFitAll(); aDestView->SetImmediateUpdate( Standard_True ); @@ -2662,3 +2979,85 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) blockSignals( blocked ); } + +/*! + \brief Indicates whether preselection is enabled + \return true if preselection is enabled +*/ +bool OCCViewer_ViewWindow::isPreselectionEnabled() const +{ + return myPreselectionEnabled; +} + +/*! + \brief Enables/disables preselection + \param theIsToEnable if true - preselection will be enabled +*/ +void OCCViewer_ViewWindow::enablePreselection( bool theIsToEnable ) +{ + onSwitchPreselection( theIsToEnable ); +} + +/*! + \brief Indicates whether selection is enabled + \return true if selection is enabled +*/ +bool OCCViewer_ViewWindow::isSelectionEnabled() const +{ + return mySelectionEnabled; +} + +/*! + \brief Enables/disables selection + \param theIsToEnable if true - selection will be enabled +*/ +void OCCViewer_ViewWindow::enableSelection( bool theIsToEnable ) +{ + onSwitchSelection( theIsToEnable ); +} + + +/*! + \brief called if clipping operation is activated / deactivated. + + Enables/disables clipping plane displaying. + + \parma on action state +*/ +void OCCViewer_ViewWindow::onClipping (bool theIsOn) +{ + if(!myModel) return; + OCCViewer_ClippingDlg* aClippingDlg = myModel->getClippingDlg(); + + if (theIsOn) { + if (!aClippingDlg) { + aClippingDlg = new OCCViewer_ClippingDlg (this, myModel); + myModel->setClippingDlg(aClippingDlg); + } + if (!aClippingDlg->isVisible()) + aClippingDlg->show(); + } else { + if ( aClippingDlg ) { + aClippingDlg->close(); + myModel->setClippingDlg(0); + } + } + + SUIT_ViewManager* mgr = getViewManager(); + if( mgr ) { + QVector aViews = mgr->getViews(); + for(int i = 0, iEnd = aViews.size(); i < iEnd; i++) { + if(SUIT_ViewWindow* aViewWindow = aViews.at(i)) { + QtxActionToolMgr* mgr = aViewWindow->toolMgr(); + if(!mgr) continue; + QAction* a = toolMgr()->action( ClippingId ); + if(!a) continue; + if(theIsOn != a->isChecked()){ + disconnect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool))); + a->setChecked(theIsOn); + connect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool))); + } + } + } + } +}