1 // Created on: 1992-03-13
2 // Created by: Christophe MARION
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Select3D_Projector.ixx>
18 #include <Precision.hxx>
21 #include <gp_Vec2d.hxx>
23 #include <Graphic3d_Vec4.hxx>
27 //=======================================================================
30 //=======================================================================
31 static Standard_Integer TrsfType(const gp_GTrsf& theTrsf)
33 const gp_Mat& aMat = theTrsf.VectorialPart();
34 if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
35 && (Abs (aMat.Value (2, 2) - 1.0) < 1e-15)
36 && (Abs (aMat.Value (3, 3) - 1.0) < 1e-15))
40 else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
41 && (Abs (aMat.Value (1, 2) + 0.5) < 1e-15)
42 && (Abs (aMat.Value (1, 3) - 0.5) < 1e-15)
43 && (Abs (aMat.Value (2, 1) - 0.7071067811865476) < 1e-15)
44 && (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
45 && (Abs (aMat.Value (2, 3) + 0.5) < 1e-15)
46 && (Abs (aMat.Value (3, 1)) < 1e-15)
47 && (Abs (aMat.Value (3, 2) - 0.7071067811865476) < 1e-15)
48 && (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
50 return 0; // inverse axo
52 else if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
53 && (Abs (aMat.Value (2, 3) - 1.0) < 1e-15)
54 && (Abs (aMat.Value (3, 2) + 1.0) < 1e-15))
58 else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
59 && (Abs (aMat.Value (1, 2) - 0.7071067811865476) < 1e-15)
60 && (Abs (aMat.Value (1, 3)) < 1e-15)
61 && (Abs (aMat.Value (2, 1) + 0.5) < 1e-15)
62 && (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
63 && (Abs (aMat.Value (2, 3) - 0.7071067811865476) < 1e-15)
64 && (Abs (aMat.Value (3, 1) - 0.5) < 1e-15)
65 && (Abs (aMat.Value (3, 2) + 0.5) < 1e-15)
66 && (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
74 //====== TYPE 0 (inverse axonometric)
75 // (0.7071067811865476, -0.5 , 0.4999999999999999)
76 // (0.7071067811865475, 0.5000000000000001, -0.5 )
77 // (0.0, 0.7071067811865475, 0.7071067811865476)
79 // ====== TYPE 1 (top)
84 // ======= TYPE 2 (front)
86 // (0.0, 1.110223024625157e-16 , 1.0)
87 // (0.0, -1.0 , 1.110223024625157e-16)
89 // ======= TYPE 3 (axonometric)
90 // ( 0.7071067811865476, 0.7071067811865475, 0.0)
91 // (-0.5 , 0.5000000000000001, 0.7071067811865475)
92 // ( 0.4999999999999999, -0.5 , 0.7071067811865476)
95 // formula for derivating a perspective, from Mathematica
98 // D1 = -------- + -------------
100 // 1 - ---- f (1 - ----)
103 //=======================================================================
104 //function : Select3D_Projector
106 //=======================================================================
107 Select3D_Projector::Select3D_Projector (const Handle(V3d_View)& theView)
108 : myPersp (Standard_False),
115 //=======================================================================
116 //function : Select3D_Projector
118 //=======================================================================
119 Select3D_Projector::Select3D_Projector()
120 : myPersp (Standard_False),
127 //=======================================================================
128 //function : Select3D_Projector
130 //=======================================================================
131 Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS)
132 : myPersp (Standard_False),
136 myScaledTrsf.SetTransformation (theCS);
137 myGTrsf.SetTrsf (myScaledTrsf);
141 //=======================================================================
142 //function : Select3D_Projector
144 //=======================================================================
145 Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS, const Standard_Real theFocus)
146 : myPersp (Standard_True),
150 myScaledTrsf.SetTransformation (theCS);
151 myGTrsf.SetTrsf (myScaledTrsf);
155 //=======================================================================
156 //function : Select3D_Projector
158 //=======================================================================
159 Select3D_Projector::Select3D_Projector (const gp_Trsf& theViewTrsf,
160 const Standard_Boolean theIsPersp,
161 const Standard_Real theFocus)
162 : myPersp (theIsPersp),
164 myGTrsf (theViewTrsf),
165 myScaledTrsf (theViewTrsf),
171 //=======================================================================
172 //function : Select3D_Projector
174 //=======================================================================
175 Select3D_Projector::Select3D_Projector (const gp_GTrsf& theViewTrsf,
176 const Standard_Boolean theIsPersp,
177 const Standard_Real theFocus)
178 : myPersp (theIsPersp),
180 myGTrsf (theViewTrsf),
181 myScaledTrsf (theViewTrsf.Trsf()),
187 //=======================================================================
188 //function : Select3D_Projector
190 //=======================================================================
191 Select3D_Projector::Select3D_Projector (const Graphic3d_Mat4d& theViewTrsf,
192 const Graphic3d_Mat4d& theProjTrsf)
193 : myPersp (Standard_False),
197 Set (theViewTrsf, theProjTrsf);
200 //=======================================================================
203 //=======================================================================
204 void Select3D_Projector::Set (const gp_Trsf& theViewTrsf,
205 const Standard_Boolean theIsPersp,
206 const Standard_Real theFocus)
208 myPersp = theIsPersp;
210 myScaledTrsf = theViewTrsf;
211 myProjTrsf.InitIdentity();
215 //=======================================================================
218 //=======================================================================
219 void Select3D_Projector::Set (const Graphic3d_Mat4d& theViewTrsf,
220 const Graphic3d_Mat4d& theProjTrsf)
222 // Copy elements corresponding to common view-transformation
223 for (Standard_Integer aRowIt = 0; aRowIt < 3; ++aRowIt)
225 for (Standard_Integer aColIt = 0; aColIt < 4; ++aColIt)
227 myGTrsf.SetValue (aRowIt + 1, aColIt + 1, theViewTrsf.GetValue (aRowIt, aColIt));
231 // Adapt scaled transformation for compatibilty
232 gp_Dir aViewY (theViewTrsf.GetValue (0, 1), theViewTrsf.GetValue (1, 1), theViewTrsf.GetValue (2, 1));
233 gp_Dir aViewZ (theViewTrsf.GetValue (0, 2), theViewTrsf.GetValue (1, 2), theViewTrsf.GetValue (2, 2));
234 gp_XYZ aViewT (theViewTrsf.GetValue (0, 3), theViewTrsf.GetValue (1, 3), theViewTrsf.GetValue (2, 3));
235 gp_Dir aViewX = aViewY ^ aViewZ;
236 gp_Ax3 aViewAx3 (gp_Pnt (aViewT), aViewZ, aViewX);
237 myScaledTrsf.SetTransformation (aViewAx3);
239 myPersp = Standard_False;
241 myProjTrsf = theProjTrsf;
245 //=======================================================================
248 //=======================================================================
249 void Select3D_Projector::SetView (const Handle(V3d_View)& theView)
251 const Graphic3d_Mat4d& aViewTrsf = theView->Camera()->OrientationMatrix();
252 const Graphic3d_Mat4d& aProjTrsf = theView->Camera()->ProjectionMatrix();
254 gp_XYZ aFrameScale = theView->Camera()->ViewDimensions();
255 Graphic3d_Mat4d aScale;
256 aScale.ChangeValue (0, 0) = aFrameScale.X();
257 aScale.ChangeValue (1, 1) = aFrameScale.Y();
258 aScale.ChangeValue (2, 2) = aFrameScale.Z();
259 Graphic3d_Mat4d aScaledProjTrsf = aScale * aProjTrsf;
261 Set (aViewTrsf, aScaledProjTrsf);
264 //=======================================================================
267 //=======================================================================
268 void Select3D_Projector::Scaled (const Standard_Boolean theToCheckOptimized)
272 if (!theToCheckOptimized && !myPersp && myProjTrsf.IsIdentity())
274 myType = TrsfType (myGTrsf);
277 myInvTrsf = myGTrsf.Inverted();
280 //=======================================================================
283 //=======================================================================
284 void Select3D_Projector::Project (const gp_Pnt& theP, gp_Pnt2d& thePout) const
286 Standard_Real aXout = 0.0;
287 Standard_Real aYout = 0.0;
288 Standard_Real aZout = 0.0;
289 Project (theP, aXout, aYout, aZout);
290 thePout.SetCoord (aXout, aYout);
293 //=======================================================================
296 //=======================================================================
297 void Select3D_Projector::Project (const gp_Pnt& theP,
300 Standard_Real& theZ) const
302 Graphic3d_Vec4d aTransformed (0.0, 0.0, 0.0, 1.0);
304 // view transformation
307 case 0 : // inverse axo
309 Standard_Real aX07 = theP.X() * 0.7071067811865475;
310 Standard_Real aY05 = theP.Y() * 0.5;
311 Standard_Real aZ05 = theP.Z() * 0.5;
312 aTransformed.x() = aX07 - aY05 + aZ05;
313 aTransformed.y() = aX07 + aY05 - aZ05;
314 aTransformed.z() = 0.7071067811865475 * (theP.Y() + theP.Z());
320 aTransformed.x() = theP.X();
321 aTransformed.y() = theP.Y();
322 aTransformed.z() = theP.Z();
328 aTransformed.x() = theP.X();
329 aTransformed.y() = theP.Z();
330 aTransformed.z() = -theP.Y();
336 Standard_Real aXmy05 = (theP.X() - theP.Y()) * 0.5;
337 Standard_Real aZ07 = theP.Z() * 0.7071067811865476;
338 aTransformed.x() = 0.7071067811865476 * (theP.X() + theP.Y());
339 aTransformed.y() = -aXmy05 + aZ07;
340 aTransformed.z() = aXmy05 + aZ07;
346 gp_Pnt aTransformPnt = theP;
347 Transform (aTransformPnt);
348 aTransformed.x() = aTransformPnt.X();
349 aTransformed.y() = aTransformPnt.Y();
350 aTransformed.z() = aTransformPnt.Z();
354 // projection transformation
357 // simplified perspective
358 Standard_Real aDistortion = 1.0 - aTransformed.z() / myFocus;
359 theX = aTransformed.x() / aDistortion;
360 theY = aTransformed.y() / aDistortion;
361 theZ = aTransformed.z();
365 if (myProjTrsf.IsIdentity())
367 // no projection transformation
368 theX = aTransformed.x();
369 theY = aTransformed.y();
370 theZ = aTransformed.z();
374 Graphic3d_Vec4d aProjected = myProjTrsf * aTransformed;
376 theX = aProjected.x() / aProjected.w();
377 theY = aProjected.y() / aProjected.w();
378 theZ = aProjected.z() / aProjected.w();
381 //=======================================================================
384 //=======================================================================
385 void Select3D_Projector::Project (const gp_Pnt& theP,
388 gp_Vec2d& theD1out) const
390 // view transformation
397 // projection transformation
400 // simplified perspective
401 Standard_Real aDist = 1.0 - aTP.Z() / myFocus;
402 thePout.SetCoord (aTP.X() / aDist, aTP.Y() / aDist);
403 theD1out.SetCoord (aTD1.X() / aDist + aTP.X() * aTD1.Z() / (myFocus * aDist * aDist),
404 aTD1.Y() / aDist + aTP.Y() * aTD1.Z() / (myFocus * aDist * aDist));
408 if (myProjTrsf.IsIdentity())
410 // no projection transformation
411 thePout.SetCoord (aTP.X(), aTP.Y());
412 theD1out.SetCoord (aTD1.X(), aTD1.Y());
415 Graphic3d_Vec4d aTransformedPnt1 (aTP.X(), aTP.Y(), aTP.Z(), 1.0);
416 Graphic3d_Vec4d aTransformedPnt2 (aTP.X() + aTD1.X(), aTP.Y() + aTD1.Y(), aTP.Z() + aTD1.Z(), 1.0);
418 Graphic3d_Vec4d aProjectedPnt1 = myProjTrsf * aTransformedPnt1;
419 Graphic3d_Vec4d aProjectedPnt2 = myProjTrsf * aTransformedPnt2;
421 aProjectedPnt1 /= aProjectedPnt1.w();
422 aProjectedPnt2 /= aProjectedPnt2.w();
424 Graphic3d_Vec4d aProjectedD1 = aProjectedPnt2 - aProjectedPnt1;
426 thePout.SetCoord (aProjectedPnt1.x(), aProjectedPnt1.y());
427 theD1out.SetCoord (aProjectedD1.x(), aProjectedD1.y());
430 //=======================================================================
433 //=======================================================================
434 gp_Lin Select3D_Projector::Shoot (const Standard_Real theX, const Standard_Real theY) const
440 // simplified perspective
441 aViewLin = gp_Lin (gp_Pnt (0.0, 0.0, myFocus), gp_Dir (theX, theY, -myFocus));
443 else if (myProjTrsf.IsIdentity())
445 // no projection transformation
446 aViewLin = gp_Lin (gp_Pnt (theX, theY, 0.0), gp_Dir (0.0, 0.0, -1.0));
450 // get direction of projection over the point in view space
451 Graphic3d_Mat4d aProjInv;
452 if (!myProjTrsf.Inverted (aProjInv))
457 Graphic3d_Vec4d aVPnt1 = aProjInv * Graphic3d_Vec4d (theX, theY, 0.0, 1.0);
458 Graphic3d_Vec4d aVPnt2 = aProjInv * Graphic3d_Vec4d (theX, theY, 10.0, 1.0);
459 aVPnt1 /= aVPnt1.w();
460 aVPnt2 /= aVPnt1.w();
462 gp_Vec aViewDir (aVPnt2.x() - aVPnt1.x(), aVPnt2.y() - aVPnt1.y(), aVPnt2.z() - aVPnt1.z());
464 aViewLin = gp_Lin (gp_Pnt (aVPnt1.x(), aVPnt1.y(), aVPnt1.z()), gp_Dir (aViewDir));
467 // view transformation
468 Transform (aViewLin, myInvTrsf);