1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00
Files
occt/tools/View/View_CameraPositionPrs.cxx
nds cafd762c93 0030268: Inspectors - improvements in VInspector plugin,
0029451: Information Message Alert to debug an algorithm or object functionality
2019-06-14 10:39:35 +03:00

339 lines
13 KiB
C++

// Created on: 2018-12-11
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <inspector/View_CameraPositionPrs.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_ArrayOfPoints.hxx>
#include <Prs3d_Root.hxx>
#include <TColgp_SequenceOfPnt.hxx>
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
// =======================================================================
// function : StartTransformation
// purpose :
// =======================================================================
void View_CameraPositionPrs::StartTransformation (const int theX, const int theY)
{
myIsTransformationStarted = Standard_True;
myStartPosition = gp_Pnt2d (theX, theY);
}
// =======================================================================
// function : StopTransformation
// purpose :
// =======================================================================
void View_CameraPositionPrs::StopTransformation (const int theX, const int theY)
{
myIsTransformationStarted = Standard_False;
myStartPosition = gp_Pnt2d (0, 0);
int aValue = 9;
}
// =======================================================================
// function : Transform
// purpose :
// =======================================================================
void View_CameraPositionPrs::Transform (const int theX, const int theY, const Handle(V3d_View) theView)
{
// scale camera symmetry according to the center
if (!myIsTransformationStarted)
return;
Standard_Integer aXDiff = theX - myStartPosition.X();
Standard_Integer anYDiff = theY - myStartPosition.Y();
Handle(V3d_View) aTargetView = GetView();
if (aTargetView.IsNull())
return;
TColgp_SequenceOfPnt aPoints = getCameraPoints(aTargetView->Camera());
TColgp_SequenceOfPnt2d aPixelPoints = projectToView (aPoints, theView);
Standard_Real aWidthInPixels = aPixelPoints.Value(2).Distance (aPixelPoints.Value(1));
Standard_Real aHeightInPixels = aPixelPoints.Value(3).Distance (aPixelPoints.Value(2));
if (aWidthInPixels < Precision::Confusion() ||
aHeightInPixels < Precision::Confusion())
return;
Standard_Real aXScaleToMove = aXDiff / aWidthInPixels;
Standard_Real anYScaleToMove = anYDiff / aHeightInPixels;
TColgp_SequenceOfPnt2d aTargetPixelPoints = projectToView (aPoints, aTargetView);
Standard_Real aTargetWidthInPixels = aTargetPixelPoints.Value(2).Distance (aTargetPixelPoints.Value(1));
Standard_Real aTargetHeightInPixels = aTargetPixelPoints.Value(3).Distance (aTargetPixelPoints.Value(2));
if (aTargetWidthInPixels < Precision::Confusion() ||
aTargetHeightInPixels < Precision::Confusion())
return;
gp_XYZ aTargetCameraDimensions = aTargetView->Camera()->ViewDimensions();
Standard_Real aTargetXDiff = aXScaleToMove * aTargetWidthInPixels;
Standard_Real aTargetYDiff = anYScaleToMove * aTargetHeightInPixels;
double aRatio = aHeightInPixels / aWidthInPixels;
bool isXScale = true;
if (aTargetXDiff == 0 && aTargetYDiff == 0)
return;
else if (aTargetXDiff == 0)
isXScale = false;
else if (aTargetYDiff == 0)
isXScale = true;
else // both X, Y are not zero
{
double aDiffRatio = aTargetYDiff / aTargetXDiff;
isXScale = aDiffRatio > aRatio;
}
Standard_Real aNewScale = 1;
if (isXScale)
{
bool isIncrease = true;
double aScaleSign = isIncrease ? 1.0 : -1.0;
double aScale = aTargetView->Camera()->Scale();
Standard_Real aTargetWidthInPixelsNew = aScale + aTargetXDiff * aScaleSign;
aNewScale = aTargetWidthInPixelsNew;
}
else
{
std::cout << "Nothing to do" << std::endl;
myStartPosition = gp_Pnt2d (theX, theY);
return;
}
aTargetView->Camera()->SetScale (aNewScale);
aTargetView->AutoZFit();
//aTargetView->ImmediateUpdate();
//aTargetView->Pan (aTargetXDiff, aTargetYDiff);
myStartPosition = gp_Pnt2d (theX, theY);
// move camera center
//if (!myIsTransformationStarted)
// return;
//Standard_Integer aXDiff = theX - myStartPosition.X();
//Standard_Integer anYDiff = theY - myStartPosition.Y();
//aXDiff = -aXDiff;
//Handle(V3d_View) aTargetView = GetView();
//if (aTargetView.IsNull())
// return;
//TColgp_SequenceOfPnt aPoints = getCameraPoints(aTargetView->Camera());
//TColgp_SequenceOfPnt2d aPixelPoints = projectToView (aPoints, theView);
//Standard_Real aWidthInPixels = aPixelPoints.Value(2).Distance (aPixelPoints.Value(1));
//Standard_Real aHeightInPixels = aPixelPoints.Value(3).Distance (aPixelPoints.Value(2));
//if (aWidthInPixels < Precision::Confusion() ||
// aHeightInPixels < Precision::Confusion())
// return;
//Standard_Real aXScaleToMove = aXDiff / aWidthInPixels;
//Standard_Real anYScaleToMove = anYDiff / aHeightInPixels;
//TColgp_SequenceOfPnt2d aTargetPixelPoints = projectToView (aPoints, aTargetView);
//Standard_Real aTargetWidthInPixels = aTargetPixelPoints.Value(2).Distance (aTargetPixelPoints.Value(1));
//Standard_Real aTargetHeightInPixels = aTargetPixelPoints.Value(3).Distance (aTargetPixelPoints.Value(2));
//if (aTargetWidthInPixels < Precision::Confusion() ||
// aTargetHeightInPixels < Precision::Confusion())
// return;
//gp_XYZ aTargetCameraDimensions = aTargetView->Camera()->ViewDimensions();
//Standard_Real aTargetXDiff = aXScaleToMove * aTargetWidthInPixels;
//Standard_Real aTargetYDiff = anYScaleToMove * aTargetHeightInPixels;
//aTargetView->Pan (aTargetXDiff, aTargetYDiff);
//myStartPosition = gp_Pnt2d (theX, theY);
}
// =======================================================================
// function : CreateView
// purpose :
// =======================================================================
void View_CameraPositionPrs::Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
const Handle(Prs3d_Presentation)& thePresentation,
const Standard_Integer theMode)
{
thePresentation->Clear();
if (GetView().IsNull())
return;
Handle (Graphic3d_Camera) aCamera = GetView()->Camera();
Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d (Quantity_NOC_RED, Aspect_TOL_SOLID, 5);
aGroup->SetGroupPrimitivesAspect (aLineAspect);
gp_Pnt aCameraCenter = aCamera->Center();
gp_XYZ aCameraDims = aCamera->ViewDimensions();
gp_XYZ aCameraHalfDims = 0.5 * aCameraDims;
gp_Dir anEyeDir (gp_Vec (aCameraCenter, aCamera->Eye()));
gp_Dir anUpVec = aCamera->Up();
gp_Dir aZAxis = anEyeDir;
gp_Dir anYAxis = anUpVec;
gp_Dir aXAxis = aZAxis ^ anYAxis;
aZAxis = gp_Dir ((gp_Vec (aCamera->Eye(), aCameraCenter)));
aZAxis.Reverse();
double aZValue = 0;//aCamera->Scale();
TColgp_SequenceOfPnt aPoints = getCameraPoints (aCamera);
{
//aZValue = aZAxis.Z() * aCamera->Scale();
Handle(Graphic3d_ArrayOfPolylines) aSegments = new Graphic3d_ArrayOfPolylines (aPoints.Size());
for (Standard_Integer aPointIndex = 1, aPointCount = aPoints.Length(); aPointIndex <= aPointCount; aPointIndex++)
{
aSegments->SetVertice (aPointIndex, aPoints (aPointIndex));
////aSegments->SetVertice (aPointIndex, gp_Pnt (aPoints (aPointIndex).X(), aPoints (aPointIndex).Y(), aZValue));
//gp_Pnt aPoint = aPoints (aPointIndex);
//aPoint.Translate(gp_Vec(aCamera->Eye(), gp::Origin()));
//aSegments->SetVertice (aPointIndex, gp_Pnt (aPoint.X(), aPoint.Y(), aPoint.Z()));
}
aGroup->AddPrimitiveArray (aSegments);
}
{
aGroup = Prs3d_Root::NewGroup (thePresentation);
aLineAspect = new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 3);
aGroup->SetGroupPrimitivesAspect (aLineAspect);
//aZValue = aZAxis.Z() * aCamera->Scale();
aZValue = 20;//aCamera->ZFar() / aCamera->Scale();
double aDistance = aCameraCenter.Distance (aCamera->Eye());
Handle (Graphic3d_Camera) aDefCamera = GetView()->DefaultCamera();
double aDefCameraScale = aDefCamera->Scale();
double aScale = aCamera->Scale();
double aMoveDistance = -aDistance + aDistance * (1 - aScale / aDefCameraScale);
//std::cout << "aDistance = " << aDistance << "aScale = " << aScale << "1 - aScale / aDefCameraScale = " << 1 - aScale / aDefCameraScale
// << "aMoveDistance = " << aMoveDistance << std::endl;
Handle(Graphic3d_ArrayOfPolylines) aSegments = new Graphic3d_ArrayOfPolylines (aPoints.Size());
for (Standard_Integer aPointIndex = 1, aPointCount = aPoints.Length(); aPointIndex <= aPointCount; aPointIndex++)
{
//aSegments->SetVertice (aPointIndex, aPoints (aPointIndex));
//aSegments->SetVertice (aPointIndex, gp_Pnt (aPoints (aPointIndex).X(), aPoints (aPointIndex).Y(), aZValue));
gp_Pnt aPoint = aPoints (aPointIndex);
gp_Dir aDir = gp_Dir (gp_Vec(aCamera->Eye(), aCameraCenter));
gp_Pnt aNewPoint = gp_Pnt(aPoint.XYZ() + aDir.XYZ() * aMoveDistance);
gp_Vec aVec (aPoint, aNewPoint);
aPoint.Translate(aVec);
aSegments->SetVertice (aPointIndex, gp_Pnt (aPoint.X(), aPoint.Y(), aPoint.Z()));
}
aGroup->AddPrimitiveArray (aSegments);
}
Handle(Graphic3d_ArrayOfPoints) aVertices = new Graphic3d_ArrayOfPoints(1);
aVertices->SetVertice (1, aCameraCenter);
Handle(Graphic3d_AspectMarker3d) aMarkerAspect = new Graphic3d_AspectMarker3d (Aspect_TOM_PLUS, Quantity_NOC_GREEN, 3);
aGroup->SetGroupPrimitivesAspect (aMarkerAspect);
aGroup->AddPrimitiveArray(aVertices);
}
// =======================================================================
// function : ComputeSelection
// purpose :
// =======================================================================
void View_CameraPositionPrs::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode)
{
}
// =======================================================================
// function : GetCamera
// purpose :
// =======================================================================
Handle(V3d_View) View_CameraPositionPrs::GetView() const
{
Handle(V3d_Viewer) aViewer = myContext->CurrentViewer();
int aViewId = 0;
for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
{
Handle(V3d_View) aView = anActiveViewIter.Value();
if (aView->View().IsNull())
continue;
if (myViewId == aViewId)
return aView;
aViewId++;
}
return Handle(V3d_View)();
}
// =======================================================================
// function : getCameraPoints
// purpose :
// =======================================================================
TColgp_SequenceOfPnt View_CameraPositionPrs::getCameraPoints (const Handle (Graphic3d_Camera)& theCamera)
{
gp_Pnt aCameraCenter = theCamera->Center();
gp_XYZ aCameraDims = theCamera->ViewDimensions();
gp_XYZ aCameraHalfDims = 0.5 * aCameraDims;
gp_Dir anEyeDir (gp_Vec (aCameraCenter, theCamera->Eye()));
gp_Dir anUpVec = theCamera->Up();
gp_Dir aZAxis = anEyeDir;
gp_Dir anYAxis = anUpVec;
gp_Dir aXAxis = aZAxis ^ anYAxis;
aZAxis = gp_Dir ((gp_Vec (theCamera->Eye(), aCameraCenter)));
aZAxis.Reverse();
double aZValue = 0;//aCamera->Scale();
TColgp_SequenceOfPnt aPoints;
aPoints.Append (gp_Pnt (aCameraCenter.XYZ() - aXAxis.XYZ() * aCameraHalfDims.X() + anYAxis.XYZ() * aCameraHalfDims.Y()));
aPoints.Append (gp_Pnt (aCameraCenter.XYZ() + aXAxis.XYZ() * aCameraHalfDims.X() + anYAxis.XYZ() * aCameraHalfDims.Y()));
aPoints.Append (gp_Pnt (aCameraCenter.XYZ() + aXAxis.XYZ() * aCameraHalfDims.X() - anYAxis.XYZ() * aCameraHalfDims.Y()));
aPoints.Append (gp_Pnt (aCameraCenter.XYZ() - aXAxis.XYZ() * aCameraHalfDims.X() - anYAxis.XYZ() * aCameraHalfDims.Y()));
aPoints.Append (gp_Pnt (aCameraCenter.XYZ() - aXAxis.XYZ() * aCameraHalfDims.X() + anYAxis.XYZ() * aCameraHalfDims.Y()));
return aPoints;
}
// =======================================================================
// function : projectToView
// purpose :
// =======================================================================
TColgp_SequenceOfPnt2d View_CameraPositionPrs::projectToView (const TColgp_SequenceOfPnt& thePoints,
const Handle(V3d_View)& theView)
{
TColgp_SequenceOfPnt2d aPoints;
Standard_Integer aX, anY;
for (Standard_Integer aPointIndex = 1, aPointCount = thePoints.Length(); aPointIndex <= aPointCount; aPointIndex++)
{
gp_Pnt aPoint = thePoints (aPointIndex);
theView->Convert (aPoint.X(), aPoint.Y(), aPoint.Z(), aX, anY);
aPoints.Append (gp_Pnt2d (aX, anY));
}
return aPoints;
}