+ }
+ // if frame buffers are unsupported, use old functionality
+ unsigned char* data = new unsigned char[aWidth * aHeight * 4];
+
+ QPoint p;
+ if (theRect.isNull()) {
+ if (toUpdate)
+ view->Redraw();
+ p = mapFromParent(geometry().topLeft());
+ } else {
+ if (toUpdate)
+ view->Redraw(theRect.x(), theRect.y(), theRect.width(), theRect.height());
+ p = theRect.topLeft();
+ }
+ glReadPixels(p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ QImage anImage(data, aWidth, aHeight, QImage::Format_ARGB32);
+ anImage = anImage.mirrored();
+ anImage = anImage.rgbSwapped();
+ return anImage;
+}
+
+/*!
+ Inits 'rotation' transformation.
+ */
+void XGUI_ViewPort::startRotation(int x, int y, int theRotationPointType,
+ const gp_Pnt& theSelectedPoint)
+{
+ if (!activeView().IsNull()) {
+ switch(theRotationPointType) {
+ case XGUI::GRAVITY:
+ activeView()->StartRotation(x, y, 0.45);
+ break;
+ case XGUI::SELECTED:
+ sx = x;
+ sy = y;
+
+ double X, Y;
+ activeView()->Size(X, Y);
+ rx = Standard_Real(activeView()->Convert(X));
+ ry = Standard_Real(activeView()->Convert(Y));
+
+ activeView()->Rotate(0., 0., 0., theSelectedPoint.X(), theSelectedPoint.Y(),
+ theSelectedPoint.Z(),
+ Standard_True);
+
+ Quantity_Ratio zRotationThreshold;
+ zRotation = Standard_False;
+ zRotationThreshold = 0.45;
+ if (zRotationThreshold > 0.) {
+ Standard_Real dx = Abs(sx - rx / 2.);
+ Standard_Real dy = Abs(sy - ry / 2.);
+ Standard_Real dd = zRotationThreshold * (rx + ry) / 2.;
+ if (dx > dd || dy > dd)
+ zRotation = Standard_True;
+ }
+ break;
+ default:
+ break;
+ }
+ activeView()->DepthFitAll();
+ }
+}
+
+/*!
+ Rotates the viewport.
+ */
+void XGUI_ViewPort::rotate(int x, int y, int theRotationPointType, const gp_Pnt& theSelectedPoint)
+{
+ if (!activeView().IsNull()) {
+ switch(theRotationPointType) {
+ case XGUI::GRAVITY:
+ activeView()->Rotation(x, y);
+ break;
+ case XGUI::SELECTED:
+ double dx, dy, dz;
+ if (zRotation) {
+ dz = atan2(Standard_Real(x) - rx / 2., ry / 2. - Standard_Real(y))
+ - atan2(sx - rx / 2., ry / 2. - sy);
+ dx = dy = 0.;
+ } else {
+ dx = (Standard_Real(x) - sx) * M_PI / rx;
+ dy = (sy - Standard_Real(y)) * M_PI / ry;
+ dz = 0.;
+ }
+
+ activeView()->Rotate(dx, dy, dz, theSelectedPoint.X(), theSelectedPoint.Y(),
+ theSelectedPoint.Z(),
+ Standard_False);
+ break;
+ default:
+ break;
+ }
+ emit vpTransformed();
+ }
+ // setZSize( getZSize() );
+}
+
+/*!
+ Resets the viewport after 'rotation'.
+ */
+void XGUI_ViewPort::endRotation()
+{
+ if (!activeView().IsNull()) {
+ activeView()->ZFitAll(1.);
+ activeView()->SetZSize(0.);
+ activeView()->Update();
+ emit vpTransformed();
+ }
+}
+
+/*!
+ Inits 'zoom' transformation.
+ */
+void XGUI_ViewPort::startZoomAtPoint(int x, int y)
+{
+ if (!activeView().IsNull()/* && isAdvancedZoomingEnabled() */)
+ activeView()->StartZoomAtPoint(x, y);
+}
+
+/*!
+ Centers the viewport.
+ */
+void XGUI_ViewPort::setCenter(int x, int y)
+{
+ if (!activeView().IsNull()) {
+ activeView()->Place(x, y, myScale);
+ emit vpTransformed();
+ }
+}
+
+/*!
+ Called at 'pan' transformation.
+ */
+void XGUI_ViewPort::pan(int dx, int dy)
+{
+ if (!activeView().IsNull()) {
+ activeView()->Pan(dx, dy, 1.0);
+ emit vpTransformed();
+ }
+}
+
+/*!
+ Called at 'window fit' transformation.
+ */
+void XGUI_ViewPort::fitRect(const QRect& rect)
+{
+ if (!activeView().IsNull()) {
+ activeView()->WindowFit(rect.left(), rect.top(), rect.right(), rect.bottom());
+ emit vpTransformed();
+ }
+}
+
+/*!
+ Called at 'zoom' transformation.
+ */
+void XGUI_ViewPort::zoom(int x0, int y0, int x, int y)
+{
+ if (!activeView().IsNull()) {
+ if (isAdvancedZoomingEnabled())
+ activeView()->ZoomAtPoint(x0, y0, x, y);
+ else
+ activeView()->Zoom(x0 + y0, 0, x + y, 0);
+ emit vpTransformed();
+ }
+}
+
+/*!
+ Sets the background data
+ */
+void XGUI_ViewPort::setBackground(const XGUI_ViewBackground& bgData)
+{
+ if (bgData.isValid()) {
+ myBackground = bgData;
+ updateBackground();
+ emit vpChangeBackground(myBackground);
+ }
+}
+
+void XGUI_ViewPort::fitAll(bool theKeepScale, bool theWithZ, bool theUpd)
+{
+ if ( activeView().IsNull() )
+ return;
+
+ if ( theKeepScale )
+ myScale = activeView()->Scale();
+
+ Standard_Real aMargin = 0.01;
+ activeView()->FitAll( aMargin, theWithZ, theUpd );
+ activeView()->SetZSize(0.);
+ emit vpTransformed( );
+}
+
+void XGUI_ViewPort::syncronizeWith( const XGUI_ViewPort* ref )
+{
+ Handle(V3d_View) refView = ref->getView();
+ Handle(V3d_View) tgtView = getView();
+
+ /* The following params are copied:
+ - view type( ortho/persp )
+ - position of view point
+ - orientation of high point
+ - position of the eye
+ - projection vector
+ - view center ( 2D )
+ - view twist
+ - view scale
+ */
+
+ /* we'll update after setting all params */
+ tgtView->SetImmediateUpdate( Standard_False );
+
+ /* perspective */
+ if ( refView->Type() == V3d_PERSPECTIVE )
+ tgtView->SetFocale( refView->Focale() );
+
+ /* copy params */
+ Standard_Real x, y, z;
+ refView->At( x, y, z ); tgtView->SetAt( x, y, z );
+ refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
+ refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
+ refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
+ refView->Center( x, y ); tgtView->SetCenter( x, y );
+ tgtView->SetScale( refView->Scale() );
+ tgtView->SetTwist( refView->Twist() );
+
+ /* update */
+ tgtView->Update();
+ tgtView->SetImmediateUpdate( Standard_True );