mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0024413: Visualization - get rid of projection shift from orthographic camera definition
From now on, the panning behavior of V3d_View completely corresponds to equal operations with camera. There is no more confusing "Center" property and "ProjectionShift" which were used to introduce composite panning, while respecting view referential points: At, Eye unchanged. The V3d_View::FitAll approach has been rewritten to do "fit all" geometrically, operating with frustum, to make it working for both orthographic and perspective projections. 1) Getting rid of ProjectionShift and Center property: - Removed ProjectionShift property of Graphic3d_Camera. - Removed confusing Center property of V3d_View (related to projection shift). - Removed redundant code related to the Center property of V3d_View. - Removed WindowLimit method of Graphic3d_Camera - no more used. 2) Improvements of fit all and selector: - Improved FitAll operation of V3d_View and reused it in NIS_View - the perspective projection is now handled correctly. - Revised code of Select3D_Projector class - can be defined with any given projection and model-view matrices. - Modified StdSelect_ViewerSelector3d and ensured that panning, zooming and going into the view do not lead to unwanted re-projection of sensitives. The handling of perspective selection is revised. - Take into account graphical boundaries of infinite structure on ZFitAll. 3) Improvements of camera: - Introduced new z range scale parameter for V3d_View::AutoZFit. See, V3d_View::AutoZFitMode. - Allow negative ZNear, ZFar for orthographic camera to avoid clipping of viewed model. - Moved camera ZNear, ZFar validity checks to V3d_View level. - Use more meaningful Standard_ShortReal relative precision for ZNear, ZFar ranges computed by ZFitAll. - Use Standard_Real type for camera projection and orientation matrices. - Extended camera to generate both Standard_Real and Standard_ShortReal transformation matrices using the same matrix evaluation methods and converted input parameters. Correcting picking tests for perspective view Modify v3d face test cases for 1px changes in face picking Modified test cases for new arguments of vviewparams DRAWEXE command
This commit is contained in:
@@ -14,14 +14,83 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#define IMP240100 //GG
|
||||
// Change RefToPix()/Convert() to Project() method.
|
||||
|
||||
#include <Select3D_Projector.ixx>
|
||||
#include <Precision.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Mat.hxx>
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
//=======================================================================
|
||||
//function : TrsfType
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Integer TrsfType(const gp_GTrsf& theTrsf)
|
||||
{
|
||||
const gp_Mat& aMat = theTrsf.VectorialPart();
|
||||
if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 2) - 1.0) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 3) - 1.0) < 1e-15))
|
||||
{
|
||||
return 1; // top
|
||||
}
|
||||
else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
|
||||
&& (Abs (aMat.Value (1, 2) + 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (1, 3) - 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 1) - 0.7071067811865476) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 3) + 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 1)) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 2) - 0.7071067811865476) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
|
||||
{
|
||||
return 0; // inverse axo
|
||||
}
|
||||
else if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 3) - 1.0) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 2) + 1.0) < 1e-15))
|
||||
{
|
||||
return 2; // front
|
||||
}
|
||||
else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
|
||||
&& (Abs (aMat.Value (1, 2) - 0.7071067811865476) < 1e-15)
|
||||
&& (Abs (aMat.Value (1, 3)) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 1) + 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (2, 3) - 0.7071067811865476) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 1) - 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 2) + 0.5) < 1e-15)
|
||||
&& (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
|
||||
{
|
||||
return 3; // axo
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//====== TYPE 0 (inverse axonometric)
|
||||
// (0.7071067811865476, -0.5 , 0.4999999999999999)
|
||||
// (0.7071067811865475, 0.5000000000000001, -0.5 )
|
||||
// (0.0, 0.7071067811865475, 0.7071067811865476)
|
||||
|
||||
// ====== TYPE 1 (top)
|
||||
// (1.0, 0.0, 0.0)
|
||||
// (0.0, 1.0, 0.0)
|
||||
// (0.0, 0.0, 1.0)
|
||||
|
||||
// ======= TYPE 2 (front)
|
||||
// (1.0, 0.0 , 0.0)
|
||||
// (0.0, 1.110223024625157e-16 , 1.0)
|
||||
// (0.0, -1.0 , 1.110223024625157e-16)
|
||||
|
||||
// ======= TYPE 3 (axonometric)
|
||||
// ( 0.7071067811865476, 0.7071067811865475, 0.0)
|
||||
// (-0.5 , 0.5000000000000001, 0.7071067811865475)
|
||||
// ( 0.4999999999999999, -0.5 , 0.7071067811865476)
|
||||
}
|
||||
|
||||
// formula for derivating a perspective, from Mathematica
|
||||
|
||||
@@ -35,20 +104,22 @@
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
|
||||
: myView (aViou)
|
||||
Select3D_Projector::Select3D_Projector (const Handle(V3d_View)& theView)
|
||||
: myPersp (Standard_False),
|
||||
myFocus (0.0),
|
||||
myType (-1)
|
||||
{
|
||||
SetView (theView);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_Projector::Select3D_Projector()
|
||||
: myPersp(Standard_False),
|
||||
myFocus(0)
|
||||
: myPersp (Standard_False),
|
||||
myFocus (0.0),
|
||||
myType (-1)
|
||||
{
|
||||
Scaled();
|
||||
}
|
||||
@@ -57,13 +128,13 @@ Select3D_Projector::Select3D_Projector()
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
|
||||
: myPersp(Standard_False),
|
||||
myFocus(0)
|
||||
Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS)
|
||||
: myPersp (Standard_False),
|
||||
myFocus (0.0),
|
||||
myType (-1)
|
||||
{
|
||||
myScaledTrsf.SetTransformation(CS);
|
||||
myGTrsf.SetTrsf(myScaledTrsf);
|
||||
myScaledTrsf.SetTransformation (theCS);
|
||||
myGTrsf.SetTrsf (myScaledTrsf);
|
||||
Scaled();
|
||||
}
|
||||
|
||||
@@ -71,14 +142,13 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
|
||||
const Standard_Real Focus)
|
||||
: myPersp(Standard_True),
|
||||
myFocus(Focus)
|
||||
Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS, const Standard_Real theFocus)
|
||||
: myPersp (Standard_True),
|
||||
myFocus (theFocus),
|
||||
myType (-1)
|
||||
{
|
||||
myScaledTrsf.SetTransformation(CS);
|
||||
myGTrsf.SetTrsf(myScaledTrsf);
|
||||
myScaledTrsf.SetTransformation (theCS);
|
||||
myGTrsf.SetTrsf (myScaledTrsf);
|
||||
Scaled();
|
||||
}
|
||||
|
||||
@@ -86,15 +156,15 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
|
||||
const Standard_Boolean Persp,
|
||||
const Standard_Real Focus)
|
||||
: myPersp(Persp),
|
||||
myFocus(Focus),
|
||||
myScaledTrsf(T)
|
||||
Select3D_Projector::Select3D_Projector (const gp_Trsf& theViewTrsf,
|
||||
const Standard_Boolean theIsPersp,
|
||||
const Standard_Real theFocus)
|
||||
: myPersp (theIsPersp),
|
||||
myFocus (theFocus),
|
||||
myGTrsf (theViewTrsf),
|
||||
myScaledTrsf (theViewTrsf),
|
||||
myType (-1)
|
||||
{
|
||||
myGTrsf.SetTrsf(myScaledTrsf);
|
||||
Scaled();
|
||||
}
|
||||
|
||||
@@ -102,361 +172,300 @@ Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT,
|
||||
const Standard_Boolean Persp,
|
||||
const Standard_Real Focus)
|
||||
: myPersp(Persp),
|
||||
myFocus(Focus),
|
||||
myGTrsf(GT)
|
||||
Select3D_Projector::Select3D_Projector (const gp_GTrsf& theViewTrsf,
|
||||
const Standard_Boolean theIsPersp,
|
||||
const Standard_Real theFocus)
|
||||
: myPersp (theIsPersp),
|
||||
myFocus (theFocus),
|
||||
myGTrsf (theViewTrsf),
|
||||
myScaledTrsf (theViewTrsf.Trsf()),
|
||||
myType (-1)
|
||||
{
|
||||
Scaled();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select3D_Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Select3D_Projector::Select3D_Projector (const Graphic3d_Mat4d& theViewTrsf,
|
||||
const Graphic3d_Mat4d& theProjTrsf)
|
||||
: myPersp (Standard_False),
|
||||
myFocus (0.0),
|
||||
myType (-1)
|
||||
{
|
||||
Set (theViewTrsf, theProjTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Select3D_Projector::Set (const gp_Trsf& theViewTrsf,
|
||||
const Standard_Boolean theIsPersp,
|
||||
const Standard_Real theFocus)
|
||||
{
|
||||
myPersp = theIsPersp;
|
||||
myFocus = theFocus;
|
||||
myScaledTrsf = theViewTrsf;
|
||||
myProjTrsf.InitIdentity();
|
||||
Scaled();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Select3D_Projector::Set
|
||||
(const gp_Trsf& T,
|
||||
const Standard_Boolean Persp,
|
||||
const Standard_Real Focus)
|
||||
void Select3D_Projector::Set (const Graphic3d_Mat4d& theViewTrsf,
|
||||
const Graphic3d_Mat4d& theProjTrsf)
|
||||
{
|
||||
myPersp = Persp;
|
||||
myFocus = Focus;
|
||||
myScaledTrsf = T;
|
||||
// Copy elements corresponding to common view-transformation
|
||||
for (Standard_Integer aRowIt = 0; aRowIt < 3; ++aRowIt)
|
||||
{
|
||||
for (Standard_Integer aColIt = 0; aColIt < 4; ++aColIt)
|
||||
{
|
||||
myGTrsf.SetValue (aRowIt + 1, aColIt + 1, theViewTrsf.GetValue (aRowIt, aColIt));
|
||||
}
|
||||
}
|
||||
|
||||
// Adapt scaled transformation for compatibilty
|
||||
gp_Dir aViewY (theViewTrsf.GetValue (0, 1), theViewTrsf.GetValue (1, 1), theViewTrsf.GetValue (2, 1));
|
||||
gp_Dir aViewZ (theViewTrsf.GetValue (0, 2), theViewTrsf.GetValue (1, 2), theViewTrsf.GetValue (2, 2));
|
||||
gp_XYZ aViewT (theViewTrsf.GetValue (0, 3), theViewTrsf.GetValue (1, 3), theViewTrsf.GetValue (2, 3));
|
||||
gp_Dir aViewX = aViewY ^ aViewZ;
|
||||
gp_Ax3 aViewAx3 (gp_Pnt (aViewT), aViewZ, aViewX);
|
||||
myScaledTrsf.SetTransformation (aViewAx3);
|
||||
|
||||
myPersp = Standard_False;
|
||||
myFocus = 0.0;
|
||||
myProjTrsf = theProjTrsf;
|
||||
Scaled();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetView
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Select3D_Projector::SetView (const Handle(V3d_View)& theView)
|
||||
{
|
||||
const Graphic3d_Mat4d& aViewTrsf = theView->Camera()->OrientationMatrix();
|
||||
const Graphic3d_Mat4d& aProjTrsf = theView->Camera()->ProjectionMatrix();
|
||||
|
||||
gp_XYZ aFrameScale = theView->Camera()->ViewDimensions();
|
||||
Graphic3d_Mat4d aScale;
|
||||
aScale.ChangeValue (0, 0) = aFrameScale.X();
|
||||
aScale.ChangeValue (1, 1) = aFrameScale.Y();
|
||||
aScale.ChangeValue (2, 2) = aFrameScale.Z();
|
||||
Graphic3d_Mat4d aScaledProjTrsf = aScale * aProjTrsf;
|
||||
|
||||
Set (aViewTrsf, aScaledProjTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Scaled
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
#include <gp_Mat.hxx>
|
||||
|
||||
static Standard_Integer TrsfType(const gp_GTrsf& Trsf) {
|
||||
const gp_Mat& Mat = Trsf.VectorialPart();
|
||||
if( (Abs(Mat.Value(1,1)-1.0) < 1e-15)
|
||||
&& (Abs(Mat.Value(2,2)-1.0) < 1e-15)
|
||||
&& (Abs(Mat.Value(3,3)-1.0) < 1e-15)) {
|
||||
return(1); //-- top
|
||||
}
|
||||
else if( (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15)
|
||||
&& (Abs(Mat.Value(1,2)+0.5) < 1e-15)
|
||||
&& (Abs(Mat.Value(1,3)-0.5) < 1e-15)
|
||||
|
||||
&& (Abs(Mat.Value(2,1)-0.7071067811865476) < 1e-15)
|
||||
&& (Abs(Mat.Value(2,2)-0.5) < 1e-15)
|
||||
&& (Abs(Mat.Value(2,3)+0.5) < 1e-15)
|
||||
|
||||
&& (Abs(Mat.Value(3,1)) < 1e-15)
|
||||
&& (Abs(Mat.Value(3,2)-0.7071067811865476) < 1e-15)
|
||||
&& (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) {
|
||||
return(0); //--
|
||||
}
|
||||
else if( (Abs(Mat.Value(1,1)-1.0) < 1e-15)
|
||||
&& (Abs(Mat.Value(2,3)-1.0) < 1e-15)
|
||||
&& (Abs(Mat.Value(3,2)+1.0) < 1e-15)) {
|
||||
return(2); //-- front
|
||||
}
|
||||
else if( (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15)
|
||||
&& (Abs(Mat.Value(1,2)-0.7071067811865476) < 1e-15)
|
||||
&& (Abs(Mat.Value(1,3)) < 1e-15)
|
||||
|
||||
&& (Abs(Mat.Value(2,1)+0.5) < 1e-15)
|
||||
&& (Abs(Mat.Value(2,2)-0.5) < 1e-15)
|
||||
&& (Abs(Mat.Value(2,3)-0.7071067811865476) < 1e-15)
|
||||
|
||||
&& (Abs(Mat.Value(3,1)-0.5) < 1e-15)
|
||||
&& (Abs(Mat.Value(3,2)+0.5) < 1e-15)
|
||||
&& (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) {
|
||||
return(3); //-- axo
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void Select3D_Projector::Scaled (const Standard_Boolean On)
|
||||
void Select3D_Projector::Scaled (const Standard_Boolean theToCheckOptimized)
|
||||
{
|
||||
myType=-1;
|
||||
if (!On) {
|
||||
if (!myPersp) {
|
||||
//myGTrsf.SetTranslationPart(gp_XYZ(0.,0.,0.));
|
||||
myType=TrsfType(myGTrsf);
|
||||
}
|
||||
myType = -1;
|
||||
|
||||
if (!theToCheckOptimized && !myPersp && myProjTrsf.IsIdentity())
|
||||
{
|
||||
myType = TrsfType (myGTrsf);
|
||||
}
|
||||
myInvTrsf = myGTrsf;
|
||||
myInvTrsf.Invert();
|
||||
|
||||
myInvTrsf = myGTrsf.Inverted();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Project
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Select3D_Projector::Project (const gp_Pnt& P, gp_Pnt2d& Pout) const
|
||||
void Select3D_Projector::Project (const gp_Pnt& theP, gp_Pnt2d& thePout) const
|
||||
{
|
||||
|
||||
if(!myView.IsNull()){
|
||||
Standard_Real Xout,Yout;
|
||||
// V3d_View
|
||||
#ifdef IMP240100
|
||||
myView->Project(P.X(),P.Y(),P.Z(),Xout,Yout);
|
||||
#else
|
||||
Standard_Integer Xp,Yp;
|
||||
myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp);
|
||||
myView->Convert(Xp,Yp,Xout,Yout);
|
||||
#endif
|
||||
Pout.SetCoord(Xout,Yout);
|
||||
}
|
||||
else{
|
||||
if(myType!=-1) {
|
||||
Standard_Real X,Y;
|
||||
switch (myType) {
|
||||
case 0: { //-- axono standard
|
||||
Standard_Real x07 = P.X()*0.7071067811865475;
|
||||
Standard_Real y05 = P.Y()*0.5;
|
||||
Standard_Real z05 = P.Z()*0.5;
|
||||
X=x07-y05+z05;
|
||||
Y=x07+y05-z05;
|
||||
//-- Z=0.7071067811865475*(P.Y()+P.Z());
|
||||
break;
|
||||
}
|
||||
case 1: { //-- top
|
||||
X=P.X(); Y=P.Y(); //-- Z=P.Z();
|
||||
Pout.SetCoord(X,Y);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
X=P.X(); Y=P.Z(); //-- Z=-P.Y();
|
||||
Pout.SetCoord(X,Y);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
Standard_Real xmy05 = (P.X()-P.Y())*0.5;
|
||||
Standard_Real z07 = P.Z()*0.7071067811865476;
|
||||
X=0.7071067811865476*(P.X()+P.Y());
|
||||
Y=-xmy05+z07;
|
||||
Pout.SetCoord(X,Y);
|
||||
//-- Z= xmy05+z07;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
gp_Pnt P2 = P;
|
||||
Transform(P2);
|
||||
if (myPersp) {
|
||||
Standard_Real R = 1.-P2.Z()/myFocus;
|
||||
Pout.SetCoord(P2.X()/R,P2.Y()/R);
|
||||
}
|
||||
else
|
||||
Pout.SetCoord(P2.X(),P2.Y());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
gp_Pnt P2 = P;
|
||||
Transform(P2);
|
||||
if (myPersp) {
|
||||
Standard_Real R = 1.-P2.Z()/myFocus;
|
||||
Pout.SetCoord(P2.X()/R,P2.Y()/R);
|
||||
}
|
||||
else
|
||||
Pout.SetCoord(P2.X(),P2.Y());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Standard_Real aXout = 0.0;
|
||||
Standard_Real aYout = 0.0;
|
||||
Standard_Real aZout = 0.0;
|
||||
Project (theP, aXout, aYout, aZout);
|
||||
thePout.SetCoord (aXout, aYout);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Project
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
/* ====== TYPE 0 (??)
|
||||
(0.7071067811865476, -0.5 , 0.4999999999999999)
|
||||
(0.7071067811865475, 0.5000000000000001, -0.5 )
|
||||
(0.0, 0.7071067811865475, 0.7071067811865476)
|
||||
|
||||
====== TYPE 1 (top)
|
||||
(1.0, 0.0, 0.0)
|
||||
(0.0, 1.0, 0.0)
|
||||
(0.0, 0.0, 1.0)
|
||||
|
||||
======= TYPE 2 (front)
|
||||
(1.0, 0.0 , 0.0)
|
||||
(0.0, 1.110223024625157e-16 , 1.0)
|
||||
(0.0, -1.0 , 1.110223024625157e-16)
|
||||
|
||||
======= TYPE 3
|
||||
( 0.7071067811865476, 0.7071067811865475, 0.0)
|
||||
(-0.5 , 0.5000000000000001, 0.7071067811865475)
|
||||
( 0.4999999999999999, -0.5 , 0.7071067811865476)
|
||||
*/
|
||||
void Select3D_Projector::Project (const gp_Pnt& P,
|
||||
Standard_Real& X,
|
||||
Standard_Real& Y,
|
||||
Standard_Real& Z) const
|
||||
void Select3D_Projector::Project (const gp_Pnt& theP,
|
||||
Standard_Real& theX,
|
||||
Standard_Real& theY,
|
||||
Standard_Real& theZ) const
|
||||
{
|
||||
if(!myView.IsNull()){
|
||||
// Standard_Real Xout,Yout;
|
||||
// V3d_View
|
||||
#ifdef IMP240100
|
||||
myView->Project(P.X(),P.Y(),P.Z(),X,Y);
|
||||
#else
|
||||
Standard_Integer Xp,Yp;
|
||||
myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp);
|
||||
myView->Convert(Xp,Yp,X,Y);
|
||||
#endif
|
||||
}
|
||||
else{
|
||||
if(myType!=-1) {
|
||||
switch (myType) {
|
||||
case 0: { //-- axono standard
|
||||
Standard_Real x07 = P.X()*0.7071067811865475;
|
||||
Standard_Real y05 = P.Y()*0.5;
|
||||
Standard_Real z05 = P.Z()*0.5;
|
||||
X=x07-y05+z05;
|
||||
Y=x07+y05-z05;
|
||||
Z=0.7071067811865475*(P.Y()+P.Z());
|
||||
break;
|
||||
}
|
||||
case 1: { //-- top
|
||||
X=P.X(); Y=P.Y(); Z=P.Z();
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
X=P.X(); Y=P.Z(); Z=-P.Y();
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
Standard_Real xmy05 = (P.X()-P.Y())*0.5;
|
||||
Standard_Real z07 = P.Z()*0.7071067811865476;
|
||||
X=0.7071067811865476*(P.X()+P.Y());
|
||||
Y=-xmy05+z07;
|
||||
Z= xmy05+z07;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
gp_Pnt P2 = P;
|
||||
Transform(P2);
|
||||
P2.Coord(X,Y,Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Graphic3d_Vec4d aTransformed (0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// view transformation
|
||||
switch (myType)
|
||||
{
|
||||
case 0 : // inverse axo
|
||||
{
|
||||
Standard_Real aX07 = theP.X() * 0.7071067811865475;
|
||||
Standard_Real aY05 = theP.Y() * 0.5;
|
||||
Standard_Real aZ05 = theP.Z() * 0.5;
|
||||
aTransformed.x() = aX07 - aY05 + aZ05;
|
||||
aTransformed.y() = aX07 + aY05 - aZ05;
|
||||
aTransformed.z() = 0.7071067811865475 * (theP.Y() + theP.Z());
|
||||
break;
|
||||
}
|
||||
else {
|
||||
gp_Pnt P2 = P;
|
||||
Transform(P2);
|
||||
P2.Coord(X,Y,Z);
|
||||
if (myPersp) {
|
||||
Standard_Real R = 1 - Z / myFocus;
|
||||
X = X / R;
|
||||
Y = Y / R;
|
||||
}
|
||||
|
||||
case 1 : // top
|
||||
{
|
||||
aTransformed.x() = theP.X();
|
||||
aTransformed.y() = theP.Y();
|
||||
aTransformed.z() = theP.Z();
|
||||
break;
|
||||
}
|
||||
|
||||
case 2 : // front
|
||||
{
|
||||
aTransformed.x() = theP.X();
|
||||
aTransformed.y() = theP.Z();
|
||||
aTransformed.z() = -theP.Y();
|
||||
break;
|
||||
}
|
||||
|
||||
case 3 : // axo
|
||||
{
|
||||
Standard_Real aXmy05 = (theP.X() - theP.Y()) * 0.5;
|
||||
Standard_Real aZ07 = theP.Z() * 0.7071067811865476;
|
||||
aTransformed.x() = 0.7071067811865476 * (theP.X() + theP.Y());
|
||||
aTransformed.y() = -aXmy05 + aZ07;
|
||||
aTransformed.z() = aXmy05 + aZ07;
|
||||
break;
|
||||
}
|
||||
|
||||
default :
|
||||
{
|
||||
gp_Pnt aTransformPnt = theP;
|
||||
Transform (aTransformPnt);
|
||||
aTransformed.x() = aTransformPnt.X();
|
||||
aTransformed.y() = aTransformPnt.Y();
|
||||
aTransformed.z() = aTransformPnt.Z();
|
||||
}
|
||||
}
|
||||
|
||||
// projection transformation
|
||||
if (myPersp)
|
||||
{
|
||||
// simplified perspective
|
||||
Standard_Real aDistortion = 1.0 - aTransformed.z() / myFocus;
|
||||
theX = aTransformed.x() / aDistortion;
|
||||
theY = aTransformed.y() / aDistortion;
|
||||
theZ = aTransformed.z();
|
||||
return;
|
||||
}
|
||||
|
||||
if (myProjTrsf.IsIdentity())
|
||||
{
|
||||
// no projection transformation
|
||||
theX = aTransformed.x();
|
||||
theY = aTransformed.y();
|
||||
theZ = aTransformed.z();
|
||||
return;
|
||||
}
|
||||
|
||||
Graphic3d_Vec4d aProjected = myProjTrsf * aTransformed;
|
||||
|
||||
theX = aProjected.x() / aProjected.w();
|
||||
theY = aProjected.y() / aProjected.w();
|
||||
theZ = aProjected.z() / aProjected.w();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Project
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Select3D_Projector::Project (const gp_Pnt& P,
|
||||
const gp_Vec& D1,
|
||||
gp_Pnt2d& Pout,
|
||||
gp_Vec2d& D1out) const
|
||||
void Select3D_Projector::Project (const gp_Pnt& theP,
|
||||
const gp_Vec& theD1,
|
||||
gp_Pnt2d& thePout,
|
||||
gp_Vec2d& theD1out) const
|
||||
{
|
||||
gp_Pnt PP = P;
|
||||
Transform(PP);
|
||||
gp_Vec DD1 = D1;
|
||||
Transform(DD1);
|
||||
if (myPersp) {
|
||||
Standard_Real R = 1. - PP.Z() / myFocus;
|
||||
Pout .SetCoord(PP .X()/R , PP.Y()/R);
|
||||
D1out.SetCoord(DD1.X()/R + PP.X()*DD1.Z()/(myFocus * R*R),
|
||||
DD1.Y()/R + PP.Y()*DD1.Z()/(myFocus * R*R));
|
||||
}
|
||||
else {
|
||||
Pout .SetCoord(PP .X(),PP .Y());
|
||||
D1out.SetCoord(DD1.X(),DD1.Y());
|
||||
}
|
||||
}
|
||||
// view transformation
|
||||
gp_Pnt aTP = theP;
|
||||
Transform (aTP);
|
||||
|
||||
gp_Vec aTD1 = theD1;
|
||||
Transform (aTD1);
|
||||
|
||||
// projection transformation
|
||||
if (myPersp)
|
||||
{
|
||||
// simplified perspective
|
||||
Standard_Real aDist = 1.0 - aTP.Z() / myFocus;
|
||||
thePout.SetCoord (aTP.X() / aDist, aTP.Y() / aDist);
|
||||
theD1out.SetCoord (aTD1.X() / aDist + aTP.X() * aTD1.Z() / (myFocus * aDist * aDist),
|
||||
aTD1.Y() / aDist + aTP.Y() * aTD1.Z() / (myFocus * aDist * aDist));
|
||||
return;
|
||||
}
|
||||
|
||||
if (myProjTrsf.IsIdentity())
|
||||
{
|
||||
// no projection transformation
|
||||
thePout.SetCoord (aTP.X(), aTP.Y());
|
||||
theD1out.SetCoord (aTD1.X(), aTD1.Y());
|
||||
}
|
||||
|
||||
Graphic3d_Vec4d aTransformedPnt1 (aTP.X(), aTP.Y(), aTP.Z(), 1.0);
|
||||
Graphic3d_Vec4d aTransformedPnt2 (aTP.X() + aTD1.X(), aTP.Y() + aTD1.Y(), aTP.Z() + aTD1.Z(), 1.0);
|
||||
|
||||
Graphic3d_Vec4d aProjectedPnt1 = myProjTrsf * aTransformedPnt1;
|
||||
Graphic3d_Vec4d aProjectedPnt2 = myProjTrsf * aTransformedPnt2;
|
||||
|
||||
aProjectedPnt1 /= aProjectedPnt1.w();
|
||||
aProjectedPnt2 /= aProjectedPnt2.w();
|
||||
|
||||
Graphic3d_Vec4d aProjectedD1 = aProjectedPnt2 - aProjectedPnt1;
|
||||
|
||||
thePout.SetCoord (aProjectedPnt1.x(), aProjectedPnt1.y());
|
||||
theD1out.SetCoord (aProjectedD1.x(), aProjectedD1.y());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Shoot
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
gp_Lin Select3D_Projector::Shoot
|
||||
(const Standard_Real X,
|
||||
const Standard_Real Y) const
|
||||
gp_Lin Select3D_Projector::Shoot (const Standard_Real theX, const Standard_Real theY) const
|
||||
{
|
||||
gp_Lin L;
|
||||
gp_Lin aViewLin;
|
||||
|
||||
if (!myView.IsNull())
|
||||
if (myPersp)
|
||||
{
|
||||
Handle(Graphic3d_Camera) aCamera = myView->Camera();
|
||||
|
||||
Standard_Real aUMin, aVMin, aUMax, aVMax;
|
||||
aCamera->WindowLimit (aUMin, aVMin, aUMax, aVMax);
|
||||
|
||||
gp_Pnt aPos = aCamera->ConvertView2World (gp_Pnt (X, Y, 1.0));
|
||||
gp_Pnt aEyePos = aCamera->Eye();
|
||||
|
||||
gp_Dir aDir;
|
||||
|
||||
if (aCamera->IsOrthographic())
|
||||
{
|
||||
aDir = aCamera->Direction();
|
||||
}
|
||||
else
|
||||
{
|
||||
aDir = gp_Dir (aPos.X() - aEyePos.X(),
|
||||
aPos.Y() - aEyePos.Y(),
|
||||
aPos.Z() - aEyePos.Z());
|
||||
}
|
||||
|
||||
L = gp_Lin (aPos, aDir);
|
||||
// simplified perspective
|
||||
aViewLin = gp_Lin (gp_Pnt (0.0, 0.0, myFocus), gp_Dir (theX, theY, -myFocus));
|
||||
}
|
||||
else if (myProjTrsf.IsIdentity())
|
||||
{
|
||||
// no projection transformation
|
||||
aViewLin = gp_Lin (gp_Pnt (theX, theY, 0.0), gp_Dir (0.0, 0.0, -1.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (myPersp) {
|
||||
L = gp_Lin(gp_Pnt(0,0, myFocus),
|
||||
gp_Dir(X,Y,-myFocus));
|
||||
}
|
||||
else {
|
||||
L = gp_Lin(gp_Pnt(X,Y,0),
|
||||
gp_Dir(0,0,-1));
|
||||
}
|
||||
// get direction of projection over the point in view space
|
||||
Graphic3d_Mat4d aProjInv;
|
||||
if (!myProjTrsf.Inverted (aProjInv))
|
||||
{
|
||||
return gp_Lin();
|
||||
}
|
||||
|
||||
Transform(L, myInvTrsf);
|
||||
Graphic3d_Vec4d aVPnt1 = aProjInv * Graphic3d_Vec4d (theX, theY, 0.0, 1.0);
|
||||
Graphic3d_Vec4d aVPnt2 = aProjInv * Graphic3d_Vec4d (theX, theY, 10.0, 1.0);
|
||||
aVPnt1 /= aVPnt1.w();
|
||||
aVPnt2 /= aVPnt1.w();
|
||||
|
||||
gp_Vec aViewDir (aVPnt2.x() - aVPnt1.x(), aVPnt2.y() - aVPnt1.y(), aVPnt2.z() - aVPnt1.z());
|
||||
|
||||
aViewLin = gp_Lin (gp_Pnt (aVPnt1.x(), aVPnt1.y(), aVPnt1.z()), gp_Dir (aViewDir));
|
||||
}
|
||||
|
||||
// view transformation
|
||||
Transform (aViewLin, myInvTrsf);
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
void Select3D_Projector::SetView(const Handle(V3d_View)& aViou)
|
||||
{
|
||||
myView = aViou;
|
||||
myPersp = aViou->Type()==V3d_PERSPECTIVE;
|
||||
myFocus= aViou->Focale();
|
||||
Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ;
|
||||
//Standard_Boolean Pers=Standard_False;
|
||||
|
||||
aViou->At(Xat,Yat,Zat);
|
||||
aViou->Up(XUp,YUp,ZUp);
|
||||
aViou->Proj(DX,DY,DZ);
|
||||
gp_Pnt At (Xat,Yat,Zat);
|
||||
gp_Dir Zpers (DX,DY,DZ);
|
||||
gp_Dir Ypers (XUp,YUp,ZUp);
|
||||
gp_Dir Xpers = Ypers.Crossed(Zpers);
|
||||
gp_Ax3 Axe (At, Zpers, Xpers);
|
||||
myScaledTrsf.SetTransformation(Axe);
|
||||
Scaled();
|
||||
|
||||
return aViewLin;
|
||||
}
|
||||
|
Reference in New Issue
Block a user