0024070: OpenGL capped object-level clipping planes
[occt.git] / src / Select3D / Select3D_Projector.cxx
CommitLineData
b311480e 1// Created on: 1992-03-13
2// Created by: Christophe MARION
3// Copyright (c) 1992-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
4952a30a 22#define IMP240100 //GG
7fd59977 23// Change RefToPix()/Convert() to Project() method.
24
25#include <Select3D_Projector.ixx>
26#include <Precision.hxx>
27#include <gp_Ax3.hxx>
28#include <gp_Vec.hxx>
29#include <gp_Vec2d.hxx>
30
31// formula for derivating a perspective, from Mathematica
32
4952a30a 33// X'[t] X[t] Z'[t]
34// D1 = -------- + -------------
35// Z[t] Z[t] 2
36// 1 - ---- f (1 - ----)
37// f f
7fd59977 38
39//=======================================================================
40//function : Select3D_Projector
4952a30a 41//purpose :
7fd59977 42//=======================================================================
43
4952a30a 44Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
45: myPersp(aViou->Type()==V3d_PERSPECTIVE),
46 myFocus(aViou->Focale()),
4269bd1b 47 myView(aViou)
7fd59977 48{
49 Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ;
50 //Standard_Boolean Pers=Standard_False;
4952a30a 51
7fd59977 52 aViou->At(Xat,Yat,Zat);
53 aViou->Up(XUp,YUp,ZUp);
54 aViou->Proj(DX,DY,DZ);
4952a30a 55 gp_Pnt At (Xat,Yat,Zat);
7fd59977 56 gp_Dir Zpers (DX,DY,DZ);
57 gp_Dir Ypers (XUp,YUp,ZUp);
58 gp_Dir Xpers = Ypers.Crossed(Zpers);
59 gp_Ax3 Axe (At, Zpers, Xpers);
60 myScaledTrsf.SetTransformation(Axe);
61 myGTrsf.SetTrsf(myScaledTrsf);
62 Scaled();
4952a30a 63
7fd59977 64}
65
4952a30a 66//=======================================================================
67//function : Select3D_Projector
68//purpose :
69//=======================================================================
70
71Select3D_Projector::Select3D_Projector()
72: myPersp(Standard_False),
4269bd1b 73 myFocus(0)
7fd59977 74{
75 Scaled();
4952a30a 76}
7fd59977 77
78//=======================================================================
79//function : Select3D_Projector
4952a30a 80//purpose :
7fd59977 81//=======================================================================
82
4952a30a 83Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
84: myPersp(Standard_False),
4269bd1b 85 myFocus(0)
7fd59977 86{
87 myScaledTrsf.SetTransformation(CS);
88 myGTrsf.SetTrsf(myScaledTrsf);
89 Scaled();
7fd59977 90}
91
92//=======================================================================
93//function : Select3D_Projector
4952a30a 94//purpose :
7fd59977 95//=======================================================================
96
4952a30a 97Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
98 const Standard_Real Focus)
99: myPersp(Standard_True),
4269bd1b 100 myFocus(Focus)
7fd59977 101{
102 myScaledTrsf.SetTransformation(CS);
103 myGTrsf.SetTrsf(myScaledTrsf);
104 Scaled();
7fd59977 105}
106
107//=======================================================================
108//function : Select3D_Projector
4952a30a 109//purpose :
7fd59977 110//=======================================================================
111
4952a30a 112Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
113 const Standard_Boolean Persp,
114 const Standard_Real Focus)
115: myPersp(Persp),
7fd59977 116 myFocus(Focus),
4269bd1b 117 myScaledTrsf(T)
7fd59977 118{
119 myGTrsf.SetTrsf(myScaledTrsf);
120 Scaled();
7fd59977 121}
122
123//=======================================================================
124//function : Select3D_Projector
4952a30a 125//purpose :
7fd59977 126//=======================================================================
127
4952a30a 128Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT,
129 const Standard_Boolean Persp,
130 const Standard_Real Focus)
131: myPersp(Persp),
7fd59977 132 myFocus(Focus),
4269bd1b 133 myGTrsf(GT)
7fd59977 134{
135 Scaled();
7fd59977 136}
137
7fd59977 138//=======================================================================
139//function : Set
4952a30a 140//purpose :
7fd59977 141//=======================================================================
142
143void Select3D_Projector::Set
4952a30a 144 (const gp_Trsf& T,
7fd59977 145 const Standard_Boolean Persp,
4952a30a 146 const Standard_Real Focus)
7fd59977 147{
148 myPersp = Persp;
149 myFocus = Focus;
150 myScaledTrsf = T;
151 Scaled();
7fd59977 152}
153
154//=======================================================================
155//function : Scaled
4952a30a 156//purpose :
7fd59977 157//=======================================================================
158
159#include <gp_Mat.hxx>
160
4952a30a 161static Standard_Integer TrsfType(const gp_GTrsf& Trsf) {
7fd59977 162 const gp_Mat& Mat = Trsf.VectorialPart();
4952a30a 163 if( (Abs(Mat.Value(1,1)-1.0) < 1e-15)
7fd59977 164 && (Abs(Mat.Value(2,2)-1.0) < 1e-15)
4952a30a 165 && (Abs(Mat.Value(3,3)-1.0) < 1e-15)) {
7fd59977 166 return(1); //-- top
167 }
168 else if( (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15)
169 && (Abs(Mat.Value(1,2)+0.5) < 1e-15)
170 && (Abs(Mat.Value(1,3)-0.5) < 1e-15)
4952a30a 171
7fd59977 172 && (Abs(Mat.Value(2,1)-0.7071067811865476) < 1e-15)
173 && (Abs(Mat.Value(2,2)-0.5) < 1e-15)
174 && (Abs(Mat.Value(2,3)+0.5) < 1e-15)
4952a30a 175
176 && (Abs(Mat.Value(3,1)) < 1e-15)
7fd59977 177 && (Abs(Mat.Value(3,2)-0.7071067811865476) < 1e-15)
4952a30a 178 && (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) {
179 return(0); //--
7fd59977 180 }
4952a30a 181 else if( (Abs(Mat.Value(1,1)-1.0) < 1e-15)
7fd59977 182 && (Abs(Mat.Value(2,3)-1.0) < 1e-15)
4952a30a 183 && (Abs(Mat.Value(3,2)+1.0) < 1e-15)) {
7fd59977 184 return(2); //-- front
185 }
186 else if( (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15)
187 && (Abs(Mat.Value(1,2)-0.7071067811865476) < 1e-15)
188 && (Abs(Mat.Value(1,3)) < 1e-15)
4952a30a 189
7fd59977 190 && (Abs(Mat.Value(2,1)+0.5) < 1e-15)
191 && (Abs(Mat.Value(2,2)-0.5) < 1e-15)
192 && (Abs(Mat.Value(2,3)-0.7071067811865476) < 1e-15)
4952a30a 193
194 && (Abs(Mat.Value(3,1)-0.5) < 1e-15)
7fd59977 195 && (Abs(Mat.Value(3,2)+0.5) < 1e-15)
4952a30a 196 && (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) {
7fd59977 197 return(3); //-- axo
198 }
199 return(-1);
200}
201
202void Select3D_Projector::Scaled (const Standard_Boolean On)
4952a30a 203{
7fd59977 204 myType=-1;
205 if (!On) {
4952a30a 206 if (!myPersp) {
7fd59977 207 //myGTrsf.SetTranslationPart(gp_XYZ(0.,0.,0.));
4952a30a 208 myType=TrsfType(myGTrsf);
7fd59977 209 }
210 }
211 myInvTrsf = myGTrsf;
212 myInvTrsf.Invert();
213}
214
215//=======================================================================
216//function : Project
4952a30a 217//purpose :
7fd59977 218//=======================================================================
219
220void Select3D_Projector::Project (const gp_Pnt& P, gp_Pnt2d& Pout) const
221{
222
223 if(!myView.IsNull()){
224 Standard_Real Xout,Yout;
225// V3d_View
226#ifdef IMP240100
227 myView->Project(P.X(),P.Y(),P.Z(),Xout,Yout);
228#else
229 Standard_Integer Xp,Yp;
230 myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp);
231 myView->Convert(Xp,Yp,Xout,Yout);
232#endif
233 Pout.SetCoord(Xout,Yout);
234 }
235 else{
4952a30a 236 if(myType!=-1) {
7fd59977 237 Standard_Real X,Y;
4952a30a 238 switch (myType) {
7fd59977 239 case 0: { //-- axono standard
240 Standard_Real x07 = P.X()*0.7071067811865475;
241 Standard_Real y05 = P.Y()*0.5;
242 Standard_Real z05 = P.Z()*0.5;
243 X=x07-y05+z05;
244 Y=x07+y05-z05;
245 //-- Z=0.7071067811865475*(P.Y()+P.Z());
246 break;
247 }
248 case 1: { //-- top
249 X=P.X(); Y=P.Y(); //-- Z=P.Z();
250 Pout.SetCoord(X,Y);
251 break;
252 }
4952a30a 253 case 2: {
7fd59977 254 X=P.X(); Y=P.Z(); //-- Z=-P.Y();
255 Pout.SetCoord(X,Y);
256 break;
257 }
4952a30a 258 case 3: {
7fd59977 259 Standard_Real xmy05 = (P.X()-P.Y())*0.5;
260 Standard_Real z07 = P.Z()*0.7071067811865476;
261 X=0.7071067811865476*(P.X()+P.Y());
262 Y=-xmy05+z07;
263 Pout.SetCoord(X,Y);
264 //-- Z= xmy05+z07;
265 break;
266 }
4952a30a 267 default: {
7fd59977 268 gp_Pnt P2 = P;
269 Transform(P2);
270 if (myPersp) {
271 Standard_Real R = 1.-P2.Z()/myFocus;
272 Pout.SetCoord(P2.X()/R,P2.Y()/R);
273 }
4952a30a 274 else
275 Pout.SetCoord(P2.X(),P2.Y());
7fd59977 276 break;
277 }
278 }
279 }
4952a30a 280 else {
7fd59977 281 gp_Pnt P2 = P;
282 Transform(P2);
283 if (myPersp) {
284 Standard_Real R = 1.-P2.Z()/myFocus;
285 Pout.SetCoord(P2.X()/R,P2.Y()/R);
286 }
4952a30a 287 else
288 Pout.SetCoord(P2.X(),P2.Y());
7fd59977 289 }
290 }
4952a30a 291
7fd59977 292
293}
294
295//=======================================================================
296//function : Project
4952a30a 297//purpose :
7fd59977 298//=======================================================================
299/* ====== TYPE 0 (??)
300 (0.7071067811865476, -0.5 , 0.4999999999999999)
301 (0.7071067811865475, 0.5000000000000001, -0.5 )
302 (0.0, 0.7071067811865475, 0.7071067811865476)
303
304 ====== TYPE 1 (top)
305(1.0, 0.0, 0.0)
306(0.0, 1.0, 0.0)
307(0.0, 0.0, 1.0)
308
309 ======= TYPE 2 (front)
310(1.0, 0.0 , 0.0)
311(0.0, 1.110223024625157e-16 , 1.0)
312(0.0, -1.0 , 1.110223024625157e-16)
313
4952a30a 314 ======= TYPE 3
7fd59977 315( 0.7071067811865476, 0.7071067811865475, 0.0)
316(-0.5 , 0.5000000000000001, 0.7071067811865475)
317( 0.4999999999999999, -0.5 , 0.7071067811865476)
318*/
319void Select3D_Projector::Project (const gp_Pnt& P,
320 Standard_Real& X,
321 Standard_Real& Y,
322 Standard_Real& Z) const
323{
324 if(!myView.IsNull()){
325// Standard_Real Xout,Yout;
326// V3d_View
327#ifdef IMP240100
328 myView->Project(P.X(),P.Y(),P.Z(),X,Y);
329#else
330 Standard_Integer Xp,Yp;
331 myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp);
332 myView->Convert(Xp,Yp,X,Y);
333#endif
334 }
335 else{
4952a30a 336 if(myType!=-1) {
337 switch (myType) {
7fd59977 338 case 0: { //-- axono standard
339 Standard_Real x07 = P.X()*0.7071067811865475;
340 Standard_Real y05 = P.Y()*0.5;
341 Standard_Real z05 = P.Z()*0.5;
342 X=x07-y05+z05;
343 Y=x07+y05-z05;
344 Z=0.7071067811865475*(P.Y()+P.Z());
345 break;
346 }
347 case 1: { //-- top
348 X=P.X(); Y=P.Y(); Z=P.Z();
349 break;
350 }
4952a30a 351 case 2: {
7fd59977 352 X=P.X(); Y=P.Z(); Z=-P.Y();
353 break;
354 }
4952a30a 355 case 3: {
7fd59977 356 Standard_Real xmy05 = (P.X()-P.Y())*0.5;
357 Standard_Real z07 = P.Z()*0.7071067811865476;
358 X=0.7071067811865476*(P.X()+P.Y());
359 Y=-xmy05+z07;
360 Z= xmy05+z07;
361 break;
362 }
4952a30a 363 default: {
7fd59977 364 gp_Pnt P2 = P;
365 Transform(P2);
366 P2.Coord(X,Y,Z);
367 break;
368 }
369 }
370 }
4952a30a 371 else {
7fd59977 372 gp_Pnt P2 = P;
373 Transform(P2);
374 P2.Coord(X,Y,Z);
375 if (myPersp) {
376 Standard_Real R = 1 - Z / myFocus;
377 X = X / R;
378 Y = Y / R;
379 }
380 }
381 }
382}
383//=======================================================================
384//function : Project
4952a30a 385//purpose :
7fd59977 386//=======================================================================
387
388void Select3D_Projector::Project (const gp_Pnt& P,
389 const gp_Vec& D1,
390 gp_Pnt2d& Pout,
391 gp_Vec2d& D1out) const
392{
393 gp_Pnt PP = P;
394 Transform(PP);
395 gp_Vec DD1 = D1;
396 Transform(DD1);
397 if (myPersp) {
398 Standard_Real R = 1. - PP.Z() / myFocus;
399 Pout .SetCoord(PP .X()/R , PP.Y()/R);
400 D1out.SetCoord(DD1.X()/R + PP.X()*DD1.Z()/(myFocus * R*R),
401 DD1.Y()/R + PP.Y()*DD1.Z()/(myFocus * R*R));
402 }
403 else {
404 Pout .SetCoord(PP .X(),PP .Y());
405 D1out.SetCoord(DD1.X(),DD1.Y());
406 }
407}
408
7fd59977 409
410//=======================================================================
411//function : Shoot
4952a30a 412//purpose :
7fd59977 413//=======================================================================
414
415gp_Lin Select3D_Projector::Shoot
416 (const Standard_Real X,
417 const Standard_Real Y) const
418{
419 gp_Lin L;
4952a30a 420
7fd59977 421 if (myPersp) {
422 L = gp_Lin(gp_Pnt(0,0, myFocus),
423 gp_Dir(X,Y,-myFocus));
424 }
425 else {
426 L = gp_Lin(gp_Pnt(X,Y,0),
427 gp_Dir(0,0,-1));
428 }
429 Transform(L, myInvTrsf);
430 return L;
431}
432
433
7fd59977 434void Select3D_Projector::SetView(const Handle(V3d_View)& aViou)
435{
436 myView = aViou;
437 myPersp = aViou->Type()==V3d_PERSPECTIVE;
438 myFocus= aViou->Focale();
439 Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ;
440 //Standard_Boolean Pers=Standard_False;
4952a30a 441
7fd59977 442 aViou->At(Xat,Yat,Zat);
443 aViou->Up(XUp,YUp,ZUp);
444 aViou->Proj(DX,DY,DZ);
4952a30a 445 gp_Pnt At (Xat,Yat,Zat);
7fd59977 446 gp_Dir Zpers (DX,DY,DZ);
447 gp_Dir Ypers (XUp,YUp,ZUp);
448 gp_Dir Xpers = Ypers.Crossed(Zpers);
449 gp_Ax3 Axe (At, Zpers, Xpers);
450 myScaledTrsf.SetTransformation(Axe);
451 Scaled();
4952a30a 452
453}