+OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ )
+{
+ OCCViewer_ViewSketcher* sketcher = 0;
+ QList<OCCViewer_ViewSketcher*>::Iterator it;
+ for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
+ {
+ OCCViewer_ViewSketcher* sk = (*it);
+ if ( sk->type() == typ )
+ sketcher = sk;
+ }
+ return sketcher;
+}
+
+/*!
+ Handles requests for sketching in the active view. [ virtual public ]
+*/
+void OCCViewer_ViewWindow::activateSketching( int type )
+{
+ OCCViewer_ViewPort3d* vp = getViewPort();
+ if ( !vp )
+ return;
+
+ if ( !vp->isSketchingEnabled() )
+ return;
+
+ /* Finish current sketching */
+ if ( type == NoSketching )
+ {
+ if ( mypSketcher )
+ {
+ onSketchingFinished();
+ mypSketcher->deactivate();
+ mypSketcher = 0;
+ }
+ }
+ /* Activate new sketching */
+ else
+ {
+ activateSketching( NoSketching ); /* concurrency not suported */
+ mypSketcher = getSketcher( type );
+ if ( mypSketcher )
+ {
+ mypSketcher->activate();
+ onSketchingStarted();
+ }
+ }
+}
+
+/*!
+ Unhilights detected entities. [ virtual protected ]
+*/
+void OCCViewer_ViewWindow::onSketchingStarted()
+{
+}
+
+/*!
+ Selection by rectangle or polygon. [ virtual protected ]
+*/
+void OCCViewer_ViewWindow::onSketchingFinished()
+{
+ MESSAGE("OCCViewer_ViewWindow::onSketchingFinished()")
+ if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept )
+ {
+ Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+ bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() );
+ switch( mypSketcher->type() )
+ {
+ case Rect:
+ {
+ QRect* aRect = (QRect*)mypSketcher->data();
+ if( aRect )
+ {
+ int aLeft = aRect->left();
+ int aRight = aRect->right();
+ int aTop = aRect->top();
+ int aBottom = aRect->bottom();
+// myRect = aRect;
+
+ if( append )
+ ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
+ else
+ ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
+ }
+ }
+ break;
+ case Polygon:
+ {
+ QPolygon* aPolygon = (QPolygon*)mypSketcher->data();
+ if( aPolygon )
+ {
+ int size = aPolygon->size();
+ TColgp_Array1OfPnt2d anArray( 1, size );
+
+ QPolygon::Iterator it = aPolygon->begin();
+ QPolygon::Iterator itEnd = aPolygon->end();
+ for( int index = 1; it != itEnd; ++it, index++ )
+ {
+ QPoint aPoint = *it;
+ anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) );
+ }
+
+ if( append )
+ ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False );
+ else
+ ic->Select( anArray, getViewPort()->getView(), Standard_False );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager();
+ aViewMgr->getOCCViewer()->performSelectionChanged();
+ }
+}
+
+OCCViewer_ViewPort3d* OCCViewer_ViewWindow::getViewPort()
+{
+ return myViewPort;
+}
+
+bool OCCViewer_ViewWindow::transformRequested() const
+{
+ return ( myOperation != NOTHING );
+}
+
+bool OCCViewer_ViewWindow::transformInProcess() const
+{
+ return myEventStarted;
+}
+
+void OCCViewer_ViewWindow::setTransformInProcess( bool bOn )
+{
+ myEventStarted = bOn;
+}
+
+/*!
+ Set enabled state of transformation (rotate, zoom, etc)
+*/
+void OCCViewer_ViewWindow::setTransformEnabled( const OperationType id, const bool on )
+{
+ if ( id != NOTHING ) myStatus.insert( id, on );
+}
+
+/*!
+ \return enabled state of transformation (rotate, zoom, etc)
+*/
+bool OCCViewer_ViewWindow::transformEnabled( const OperationType id ) const
+{
+ return myStatus.contains( id ) ? myStatus[ id ] : true;
+}
+
+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 );
+ }
+ }
+ else {
+ anAction->setText( tr( "MNU_MAXIMIZE_VIEW" ) );
+ 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" ));
+}
+
+void OCCViewer_ViewWindow::setSketcherStyle( bool enable )
+{
+ IsSketcherStyle = enable;
+}
+
+bool OCCViewer_ViewWindow::isSketcherStyle() const
+{
+ return IsSketcherStyle;
+}
+
+
+void OCCViewer_ViewWindow::set2dMode(Mode2dType theType)
+{
+ my2dMode = theType;
+}
+
+// obsolete
+QColor OCCViewer_ViewWindow::backgroundColor() const
+{
+ return myViewPort ? myViewPort->backgroundColor() : Qt::black;
+}
+
+// obsolete
+void OCCViewer_ViewWindow::setBackgroundColor( const QColor& theColor )
+{
+ if ( myViewPort ) myViewPort->setBackgroundColor( theColor );
+}
+
+Qtx::BackgroundData OCCViewer_ViewWindow::background() const
+{
+ return myViewPort ? myViewPort->background() : Qtx::BackgroundData();
+}
+
+void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackground )
+{
+ if ( myViewPort ) myViewPort->setBackground( theBackground );
+}
+
+/*!
+ Clears view aspects
+*/
+void OCCViewer_ViewWindow::clearViewAspects()
+{
+ myViewAspects.clear();
+}
+
+/*!
+ \return const reference to list of view aspects
+*/
+const viewAspectList& OCCViewer_ViewWindow::getViewAspects()
+{
+ return myViewAspects;
+}
+
+/*!
+ Appends new view aspect
+ \param aParams - new view aspects
+*/
+void OCCViewer_ViewWindow::appendViewAspect( const viewAspect& aParams )
+{
+ myViewAspects.append( aParams );
+}
+
+/*!
+ Replaces old view aspects by new ones
+ \param aViewList - list of new view aspects
+*/
+void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList )
+{
+ myViewAspects = aViewList;
+}
+
+/*!
+ Get camera properties for the OCC view window.
+ \return shared pointer on camera properties.
+*/
+SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
+{
+ SUIT_CameraProperties aProps;
+
+ Handle(V3d_View) aSourceView = getViewPort()->getView();
+ if ( aSourceView.IsNull() )
+ return aProps;
+
+ if ( get2dMode() == No2dMode ) {
+ aProps.setDimension( SUIT_CameraProperties::Dim3D );
+ }
+ else {
+ 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 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]);
+
+ // 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.
+ 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_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() );
+
+ // 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);
+
+ // 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;
+
+ aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
+ aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z());
+
+ return aProps;
+}
+
+/*!
+ Synchronize views.
+ This implementation synchronizes OCC view's camera propreties.
+*/
+void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
+{
+ bool blocked = blockSignals( true );
+
+ SUIT_CameraProperties aProps = theView->cameraProperties();
+ if ( !cameraProperties().isCompatible( aProps ) ) {
+ // other view, this one is being currently synchronized to, seems has become incompatible
+ // we have to break synchronization
+ updateSyncViews();
+ return;
+ }
+
+ Handle(V3d_View) aDestView = getViewPort()->getView();
+
+ aDestView->SetImmediateUpdate( Standard_False );
+
+ 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]);
+
+ // 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() );
+ aTrsf.Invert();
+
+ // transform to view-space coordinate system
+ gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]);
+ aProjRef.Transform(aTrsf);
+
+ // set view camera properties using low-level approach. this is done
+ // in order to avoid interference with static variables in v3d view used
+ // when rotation is in process in another view.
+ 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]);
+
+ aMappingProj.Normalize();
+ aMappingUp.Normalize();
+
+ anOrientation.SetViewReferencePlane(aMappingProj);
+ anOrientation.SetViewReferenceUp(aMappingUp);
+
+ aDestView->SetViewMapping(aMapping);
+ aDestView->SetViewOrientation(anOrientation);
+
+ // set panning
+ aDestView->SetCenter(aProjRef.X(), aProjRef.Y());
+
+ // set mapping scale
+ Standard_Real aWidth, aHeight;
+ aDestView->Size(aWidth, aHeight);
+
+ if ( aWidth > aHeight )
+ aDestView->SetSize (aMapScaling * (aWidth / aHeight));
+ else
+ aDestView->SetSize (aMapScaling);
+
+ getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+
+ aDestView->ZFitAll();
+ aDestView->SetImmediateUpdate( Standard_True );
+ aDestView->Redraw();
+
+ 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<SUIT_ViewWindow*> 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)));
+ }
+ }
+ }
+ }
+}