]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
View synchronization issues fixed:
authorapl <apl@opencascade.com>
Thu, 1 Nov 2012 12:29:35 +0000 (12:29 +0000)
committerapl <apl@opencascade.com>
Thu, 1 Nov 2012 12:29:35 +0000 (12:29 +0000)
1) camera clipping range
2) OCC <-> OCC with rotation
3) axial scale
4) perspective projection synchronization

src/OCCViewer/OCCViewer_ViewWindow.cxx
src/SUIT/SUIT_CameraProperties.cxx
src/SUIT/SUIT_CameraProperties.h
src/SVTK/SVTK_ViewWindow.cxx

index 595257cf835bf7e903958b8a7ae16dfd88c9cb5a..8866d7c1b8b56d9abfd33754ee7b876ca372dd3b 100755 (executable)
@@ -1542,7 +1542,10 @@ void OCCViewer_ViewWindow::onAxialScale()
     myScalingDlg = new OCCViewer_AxialScaleDlg( this );
   
   if ( !myScalingDlg->isVisible() )
+  {
+    myScalingDlg->Update();
     myScalingDlg->show();
+  }
 }
 
 /*!
@@ -2513,15 +2516,25 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
   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.
@@ -2539,14 +2552,14 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
   Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint();
   
   // transform to world-space coordinate system
-  gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aProjRef.Z()).Transformed(aTrsf);
+  gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf);
   
   // compute focal point
   double aFocalPoint[3];
 
-  aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aProjRef.Z();
-  aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aProjRef.Z();
-  aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aProjRef.Z();
+  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());
@@ -2564,19 +2577,21 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
 
   SUIT_CameraProperties aProps = theView->cameraProperties();
 
-  Handle(V3d_View) aSourceView = getViewPort()->getView();
+  Handle(V3d_View) aDestView = getViewPort()->getView();
 
-  aSourceView->SetImmediateUpdate( Standard_False );
+  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],
@@ -2585,7 +2600,7 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
   
   // get custom view translation
   Standard_Real aTranslation[3];
-  aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
+  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()));
@@ -2603,26 +2618,41 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
   gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]);
   aProjRef.Transform(aTrsf);
 
-  aSourceView->SetProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z());
+  // 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]);
 
-  aSourceView->SetUp((Standard_Real)anUpDir[0],
-                     (Standard_Real)anUpDir[1],
-                     (Standard_Real)anUpDir[2]);
+  aMappingProj.Normalize();
+  aMappingUp.Normalize();
+
+  anOrientation.SetViewReferencePlane(aMappingProj);
+  anOrientation.SetViewReferenceUp(aMappingUp);
+
+  aDestView->SetViewMapping(aMapping);
+  aDestView->SetViewOrientation(anOrientation);
 
   // set panning
-  aSourceView->SetCenter(aProjRef.X(), aProjRef.Y());
+  aDestView->SetCenter(aProjRef.X(), aProjRef.Y());
 
   // set mapping scale
   Standard_Real aWidth, aHeight;
-  aSourceView->Size(aWidth, aHeight);
+  aDestView->Size(aWidth, aHeight);
   
   if ( aWidth > aHeight )
-    aSourceView->SetSize (aMapScaling * (aWidth / aHeight));
+    aDestView->SetSize (aMapScaling * (aWidth / aHeight));
   else
-    aSourceView->SetSize (aMapScaling);
+    aDestView->SetSize (aMapScaling);
+
+  getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
 
-  aSourceView->Update();
-  aSourceView->SetImmediateUpdate( Standard_True );
+  aDestView->ZFitAll();
+  aDestView->SetImmediateUpdate( Standard_True );
+  aDestView->Redraw();
 
   blockSignals( blocked );
 }
index 0eb7d921252b8a2f3ad9b81f4608b8526555f144..2c88fc6e1a5596f9131c7d2140dc61f4827ec1db 100644 (file)
@@ -64,6 +64,8 @@ SUIT_CameraProperties::SUIT_CameraProperties()
   myDimension   = DimNone;        // none dimension by default
   myProjection  = PrjOrthogonal;  // orthogonal projection by default
   myViewSide    = ViewNone;       // no side view by default
+  
+  myViewAngle = 45.0;
 }
 
 /*!
@@ -372,3 +374,23 @@ void SUIT_CameraProperties::setAxialScale(const double theScaleX, const double t
   myAxialScale[1] = theScaleY;
   myAxialScale[2] = theScaleZ;
 }
+
+/*!
+  \brief get angle (typically in degrees) of view for perpective projection mode.
+  \return the angle of view.
+  \sa setViewAngle()
+*/
+double SUIT_CameraProperties::getViewAngle() const
+{
+  return myViewAngle;
+}
+
+/*!
+  \brief set angle (typically in degrees) of view for perpective projection mode.
+  \param theViewAngle [in] the angle of view.
+  \sa getViewAngle()
+*/
+void SUIT_CameraProperties::setViewAngle(const double theViewAngle)
+{
+  myViewAngle = theViewAngle;
+}
index 532c39f0688c8630de5055b5e8f2fc7ca902c801..30cfbbe09fe92ea61f165bb2ca9283e8a1e879fe 100644 (file)
@@ -65,6 +65,9 @@ public:
   void       getAxialScale(double& theScaleX, double& theScaleY, double& theScaleZ);
   void       setAxialScale(const double theScaleX, const double theScaleY, const double theScaleZ);
 
+  double     getViewAngle() const;
+  void       setViewAngle(const double theViewAngle);
+  
 // common properties for all viewers
 private:
   Dimension  myDimension;        //!< dimension
@@ -76,6 +79,7 @@ private:
   double     myClippingRange[2]; //!< distance to front and back clipping planes
   double     myMappingScale;     //!< window mapping scale (parallel projection scale)
   double     myAxialScale[3];    //!< scaling factors for world axes
+  double     myViewAngle;        //!< perspective view angle in degrees
 };
 
 #endif // SUIT_CAMERAPROPERITES_H
index 908fce24d3789705ebca37b173432ac60c4b393b..73ebce10143fb1f05e29e4153e50f3470c53cdd7 100755 (executable)
@@ -2398,6 +2398,7 @@ SUIT_CameraProperties SVTK_ViewWindow::cameraProperties()
   double aFocalPoint[3];
   double aPosition[3];
   double aViewUp[3];
+  double anAxialScale[3];
 
   aCamera->OrthogonalizeViewUp();
   aCamera->GetFocalPoint(aFocalPoint);
@@ -2408,6 +2409,14 @@ SUIT_CameraProperties SVTK_ViewWindow::cameraProperties()
   aProps.setPosition(aPosition[0], aPosition[1], aPosition[2]);
   aProps.setViewUp(aViewUp[0], aViewUp[1], aViewUp[2]);
   aProps.setMappingScale(aCamera->GetParallelScale());
+
+  if (aProps.getProjection() == SUIT_CameraProperties::PrjPerspective)
+  {
+    aProps.setViewAngle(aCamera->GetViewAngle());
+  }
+
+  GetRenderer()->GetScale(anAxialScale);
+  aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
   
   return aProps;
 }
@@ -2428,11 +2437,13 @@ void SVTK_ViewWindow::synchronize( SUIT_ViewWindow* theView )
   double aFocalPoint[3];
   double aPosition[3];
   double aViewUp[3];
+  double anAxialScale[3];
 
   // get common properties
   aProps.getViewUp(aViewUp[0], aViewUp[1], aViewUp[2]);
   aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]);
   aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
+  aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
   
   // restore properties to the camera
   aCamera->SetViewUp(aViewUp);
@@ -2440,7 +2451,15 @@ void SVTK_ViewWindow::synchronize( SUIT_ViewWindow* theView )
   aCamera->SetFocalPoint(aFocalPoint);
   aCamera->SetParallelScale(aProps.getMappingScale());
 
-  Repaint();
+  if (aProps.getProjection() == SUIT_CameraProperties::PrjPerspective)
+  {
+    aCamera->SetViewAngle(aProps.getViewAngle());
+  }
+
+  GetRenderer()->SetScale(anAxialScale);
+
+  getRenderer()->ResetCameraClippingRange();
+  Repaint(false);
 
   blockSignals( blocked );
 }