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 |
44 | Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou) |
45 | : myPersp(aViou->Type()==V3d_PERSPECTIVE), |
46 | myFocus(aViou->Focale()), |
4952a30a |
47 | myView(aViou), |
48 | myDepthMin(-Precision::Infinite()), |
49 | myDepthMax( Precision::Infinite()) |
7fd59977 |
50 | { |
51 | Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ; |
52 | //Standard_Boolean Pers=Standard_False; |
4952a30a |
53 | |
7fd59977 |
54 | aViou->At(Xat,Yat,Zat); |
55 | aViou->Up(XUp,YUp,ZUp); |
56 | aViou->Proj(DX,DY,DZ); |
4952a30a |
57 | gp_Pnt At (Xat,Yat,Zat); |
7fd59977 |
58 | gp_Dir Zpers (DX,DY,DZ); |
59 | gp_Dir Ypers (XUp,YUp,ZUp); |
60 | gp_Dir Xpers = Ypers.Crossed(Zpers); |
61 | gp_Ax3 Axe (At, Zpers, Xpers); |
62 | myScaledTrsf.SetTransformation(Axe); |
63 | myGTrsf.SetTrsf(myScaledTrsf); |
64 | Scaled(); |
4952a30a |
65 | |
7fd59977 |
66 | } |
67 | |
4952a30a |
68 | //======================================================================= |
69 | //function : Select3D_Projector |
70 | //purpose : |
71 | //======================================================================= |
72 | |
73 | Select3D_Projector::Select3D_Projector() |
74 | : myPersp(Standard_False), |
75 | myFocus(0), |
4952a30a |
76 | myDepthMin(-Precision::Infinite()), |
77 | myDepthMax( Precision::Infinite()) |
7fd59977 |
78 | { |
79 | Scaled(); |
4952a30a |
80 | } |
7fd59977 |
81 | |
82 | //======================================================================= |
83 | //function : Select3D_Projector |
4952a30a |
84 | //purpose : |
7fd59977 |
85 | //======================================================================= |
86 | |
4952a30a |
87 | Select3D_Projector::Select3D_Projector (const gp_Ax2& CS) |
88 | : myPersp(Standard_False), |
89 | myFocus(0), |
90 | myDepthMin(-Precision::Infinite()), |
91 | myDepthMax( Precision::Infinite()) |
7fd59977 |
92 | { |
93 | myScaledTrsf.SetTransformation(CS); |
94 | myGTrsf.SetTrsf(myScaledTrsf); |
95 | Scaled(); |
7fd59977 |
96 | } |
97 | |
98 | //======================================================================= |
99 | //function : Select3D_Projector |
4952a30a |
100 | //purpose : |
7fd59977 |
101 | //======================================================================= |
102 | |
4952a30a |
103 | Select3D_Projector::Select3D_Projector (const gp_Ax2& CS, |
104 | const Standard_Real Focus) |
105 | : myPersp(Standard_True), |
106 | myFocus(Focus), |
107 | myDepthMin(-Precision::Infinite()), |
108 | myDepthMax( Precision::Infinite()) |
7fd59977 |
109 | { |
110 | myScaledTrsf.SetTransformation(CS); |
111 | myGTrsf.SetTrsf(myScaledTrsf); |
112 | Scaled(); |
7fd59977 |
113 | } |
114 | |
115 | //======================================================================= |
116 | //function : Select3D_Projector |
4952a30a |
117 | //purpose : |
7fd59977 |
118 | //======================================================================= |
119 | |
4952a30a |
120 | Select3D_Projector::Select3D_Projector (const gp_Trsf& T, |
121 | const Standard_Boolean Persp, |
122 | const Standard_Real Focus) |
123 | : myPersp(Persp), |
7fd59977 |
124 | myFocus(Focus), |
4952a30a |
125 | myScaledTrsf(T), |
126 | myDepthMin(-Precision::Infinite()), |
127 | myDepthMax( Precision::Infinite()) |
7fd59977 |
128 | { |
129 | myGTrsf.SetTrsf(myScaledTrsf); |
130 | Scaled(); |
131 | } |
132 | |
133 | //======================================================================= |
134 | //function : Select3D_Projector |
4952a30a |
135 | //purpose : |
7fd59977 |
136 | //======================================================================= |
137 | |
4952a30a |
138 | Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT, |
139 | const Standard_Boolean Persp, |
140 | const Standard_Real Focus) |
141 | : myPersp(Persp), |
7fd59977 |
142 | myFocus(Focus), |
4952a30a |
143 | myGTrsf(GT), |
144 | myDepthMin(-Precision::Infinite()), |
145 | myDepthMax( Precision::Infinite()) |
7fd59977 |
146 | { |
147 | Scaled(); |
7fd59977 |
148 | } |
149 | |
7fd59977 |
150 | //======================================================================= |
151 | //function : Set |
4952a30a |
152 | //purpose : |
7fd59977 |
153 | //======================================================================= |
154 | |
155 | void Select3D_Projector::Set |
4952a30a |
156 | (const gp_Trsf& T, |
7fd59977 |
157 | const Standard_Boolean Persp, |
4952a30a |
158 | const Standard_Real Focus) |
7fd59977 |
159 | { |
160 | myPersp = Persp; |
161 | myFocus = Focus; |
162 | myScaledTrsf = T; |
163 | Scaled(); |
7fd59977 |
164 | } |
165 | |
166 | //======================================================================= |
167 | //function : Scaled |
4952a30a |
168 | //purpose : |
7fd59977 |
169 | //======================================================================= |
170 | |
171 | #include <gp_Mat.hxx> |
172 | |
4952a30a |
173 | static Standard_Integer TrsfType(const gp_GTrsf& Trsf) { |
7fd59977 |
174 | const gp_Mat& Mat = Trsf.VectorialPart(); |
4952a30a |
175 | if( (Abs(Mat.Value(1,1)-1.0) < 1e-15) |
7fd59977 |
176 | && (Abs(Mat.Value(2,2)-1.0) < 1e-15) |
4952a30a |
177 | && (Abs(Mat.Value(3,3)-1.0) < 1e-15)) { |
7fd59977 |
178 | return(1); //-- top |
179 | } |
180 | else if( (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15) |
181 | && (Abs(Mat.Value(1,2)+0.5) < 1e-15) |
182 | && (Abs(Mat.Value(1,3)-0.5) < 1e-15) |
4952a30a |
183 | |
7fd59977 |
184 | && (Abs(Mat.Value(2,1)-0.7071067811865476) < 1e-15) |
185 | && (Abs(Mat.Value(2,2)-0.5) < 1e-15) |
186 | && (Abs(Mat.Value(2,3)+0.5) < 1e-15) |
4952a30a |
187 | |
188 | && (Abs(Mat.Value(3,1)) < 1e-15) |
7fd59977 |
189 | && (Abs(Mat.Value(3,2)-0.7071067811865476) < 1e-15) |
4952a30a |
190 | && (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) { |
191 | return(0); //-- |
7fd59977 |
192 | } |
4952a30a |
193 | else if( (Abs(Mat.Value(1,1)-1.0) < 1e-15) |
7fd59977 |
194 | && (Abs(Mat.Value(2,3)-1.0) < 1e-15) |
4952a30a |
195 | && (Abs(Mat.Value(3,2)+1.0) < 1e-15)) { |
7fd59977 |
196 | return(2); //-- front |
197 | } |
198 | else if( (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15) |
199 | && (Abs(Mat.Value(1,2)-0.7071067811865476) < 1e-15) |
200 | && (Abs(Mat.Value(1,3)) < 1e-15) |
4952a30a |
201 | |
7fd59977 |
202 | && (Abs(Mat.Value(2,1)+0.5) < 1e-15) |
203 | && (Abs(Mat.Value(2,2)-0.5) < 1e-15) |
204 | && (Abs(Mat.Value(2,3)-0.7071067811865476) < 1e-15) |
4952a30a |
205 | |
206 | && (Abs(Mat.Value(3,1)-0.5) < 1e-15) |
7fd59977 |
207 | && (Abs(Mat.Value(3,2)+0.5) < 1e-15) |
4952a30a |
208 | && (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) { |
7fd59977 |
209 | return(3); //-- axo |
210 | } |
211 | return(-1); |
212 | } |
213 | |
214 | void Select3D_Projector::Scaled (const Standard_Boolean On) |
4952a30a |
215 | { |
7fd59977 |
216 | myType=-1; |
217 | if (!On) { |
4952a30a |
218 | if (!myPersp) { |
7fd59977 |
219 | //myGTrsf.SetTranslationPart(gp_XYZ(0.,0.,0.)); |
4952a30a |
220 | myType=TrsfType(myGTrsf); |
7fd59977 |
221 | } |
222 | } |
223 | myInvTrsf = myGTrsf; |
224 | myInvTrsf.Invert(); |
225 | } |
226 | |
227 | //======================================================================= |
228 | //function : Project |
4952a30a |
229 | //purpose : |
7fd59977 |
230 | //======================================================================= |
231 | |
232 | void Select3D_Projector::Project (const gp_Pnt& P, gp_Pnt2d& Pout) const |
233 | { |
234 | |
235 | if(!myView.IsNull()){ |
236 | Standard_Real Xout,Yout; |
237 | // V3d_View |
238 | #ifdef IMP240100 |
239 | myView->Project(P.X(),P.Y(),P.Z(),Xout,Yout); |
240 | #else |
241 | Standard_Integer Xp,Yp; |
242 | myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp); |
243 | myView->Convert(Xp,Yp,Xout,Yout); |
244 | #endif |
245 | Pout.SetCoord(Xout,Yout); |
246 | } |
247 | else{ |
4952a30a |
248 | if(myType!=-1) { |
7fd59977 |
249 | Standard_Real X,Y; |
4952a30a |
250 | switch (myType) { |
7fd59977 |
251 | case 0: { //-- axono standard |
252 | Standard_Real x07 = P.X()*0.7071067811865475; |
253 | Standard_Real y05 = P.Y()*0.5; |
254 | Standard_Real z05 = P.Z()*0.5; |
255 | X=x07-y05+z05; |
256 | Y=x07+y05-z05; |
257 | //-- Z=0.7071067811865475*(P.Y()+P.Z()); |
258 | break; |
259 | } |
260 | case 1: { //-- top |
261 | X=P.X(); Y=P.Y(); //-- Z=P.Z(); |
262 | Pout.SetCoord(X,Y); |
263 | break; |
264 | } |
4952a30a |
265 | case 2: { |
7fd59977 |
266 | X=P.X(); Y=P.Z(); //-- Z=-P.Y(); |
267 | Pout.SetCoord(X,Y); |
268 | break; |
269 | } |
4952a30a |
270 | case 3: { |
7fd59977 |
271 | Standard_Real xmy05 = (P.X()-P.Y())*0.5; |
272 | Standard_Real z07 = P.Z()*0.7071067811865476; |
273 | X=0.7071067811865476*(P.X()+P.Y()); |
274 | Y=-xmy05+z07; |
275 | Pout.SetCoord(X,Y); |
276 | //-- Z= xmy05+z07; |
277 | break; |
278 | } |
4952a30a |
279 | default: { |
7fd59977 |
280 | gp_Pnt P2 = P; |
281 | Transform(P2); |
282 | if (myPersp) { |
283 | Standard_Real R = 1.-P2.Z()/myFocus; |
284 | Pout.SetCoord(P2.X()/R,P2.Y()/R); |
285 | } |
4952a30a |
286 | else |
287 | Pout.SetCoord(P2.X(),P2.Y()); |
7fd59977 |
288 | break; |
289 | } |
290 | } |
291 | } |
4952a30a |
292 | else { |
7fd59977 |
293 | gp_Pnt P2 = P; |
294 | Transform(P2); |
295 | if (myPersp) { |
296 | Standard_Real R = 1.-P2.Z()/myFocus; |
297 | Pout.SetCoord(P2.X()/R,P2.Y()/R); |
298 | } |
4952a30a |
299 | else |
300 | Pout.SetCoord(P2.X(),P2.Y()); |
7fd59977 |
301 | } |
302 | } |
4952a30a |
303 | |
7fd59977 |
304 | |
305 | } |
306 | |
307 | //======================================================================= |
308 | //function : Project |
4952a30a |
309 | //purpose : |
7fd59977 |
310 | //======================================================================= |
311 | /* ====== TYPE 0 (??) |
312 | (0.7071067811865476, -0.5 , 0.4999999999999999) |
313 | (0.7071067811865475, 0.5000000000000001, -0.5 ) |
314 | (0.0, 0.7071067811865475, 0.7071067811865476) |
315 | |
316 | ====== TYPE 1 (top) |
317 | (1.0, 0.0, 0.0) |
318 | (0.0, 1.0, 0.0) |
319 | (0.0, 0.0, 1.0) |
320 | |
321 | ======= TYPE 2 (front) |
322 | (1.0, 0.0 , 0.0) |
323 | (0.0, 1.110223024625157e-16 , 1.0) |
324 | (0.0, -1.0 , 1.110223024625157e-16) |
325 | |
4952a30a |
326 | ======= TYPE 3 |
7fd59977 |
327 | ( 0.7071067811865476, 0.7071067811865475, 0.0) |
328 | (-0.5 , 0.5000000000000001, 0.7071067811865475) |
329 | ( 0.4999999999999999, -0.5 , 0.7071067811865476) |
330 | */ |
331 | void Select3D_Projector::Project (const gp_Pnt& P, |
332 | Standard_Real& X, |
333 | Standard_Real& Y, |
334 | Standard_Real& Z) const |
335 | { |
336 | if(!myView.IsNull()){ |
337 | // Standard_Real Xout,Yout; |
338 | // V3d_View |
339 | #ifdef IMP240100 |
340 | myView->Project(P.X(),P.Y(),P.Z(),X,Y); |
341 | #else |
342 | Standard_Integer Xp,Yp; |
343 | myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp); |
344 | myView->Convert(Xp,Yp,X,Y); |
345 | #endif |
346 | } |
347 | else{ |
4952a30a |
348 | if(myType!=-1) { |
349 | switch (myType) { |
7fd59977 |
350 | case 0: { //-- axono standard |
351 | Standard_Real x07 = P.X()*0.7071067811865475; |
352 | Standard_Real y05 = P.Y()*0.5; |
353 | Standard_Real z05 = P.Z()*0.5; |
354 | X=x07-y05+z05; |
355 | Y=x07+y05-z05; |
356 | Z=0.7071067811865475*(P.Y()+P.Z()); |
357 | break; |
358 | } |
359 | case 1: { //-- top |
360 | X=P.X(); Y=P.Y(); Z=P.Z(); |
361 | break; |
362 | } |
4952a30a |
363 | case 2: { |
7fd59977 |
364 | X=P.X(); Y=P.Z(); Z=-P.Y(); |
365 | break; |
366 | } |
4952a30a |
367 | case 3: { |
7fd59977 |
368 | Standard_Real xmy05 = (P.X()-P.Y())*0.5; |
369 | Standard_Real z07 = P.Z()*0.7071067811865476; |
370 | X=0.7071067811865476*(P.X()+P.Y()); |
371 | Y=-xmy05+z07; |
372 | Z= xmy05+z07; |
373 | break; |
374 | } |
4952a30a |
375 | default: { |
7fd59977 |
376 | gp_Pnt P2 = P; |
377 | Transform(P2); |
378 | P2.Coord(X,Y,Z); |
379 | break; |
380 | } |
381 | } |
382 | } |
4952a30a |
383 | else { |
7fd59977 |
384 | gp_Pnt P2 = P; |
385 | Transform(P2); |
386 | P2.Coord(X,Y,Z); |
387 | if (myPersp) { |
388 | Standard_Real R = 1 - Z / myFocus; |
389 | X = X / R; |
390 | Y = Y / R; |
391 | } |
392 | } |
393 | } |
394 | } |
395 | //======================================================================= |
396 | //function : Project |
4952a30a |
397 | //purpose : |
7fd59977 |
398 | //======================================================================= |
399 | |
400 | void Select3D_Projector::Project (const gp_Pnt& P, |
401 | const gp_Vec& D1, |
402 | gp_Pnt2d& Pout, |
403 | gp_Vec2d& D1out) const |
404 | { |
405 | gp_Pnt PP = P; |
406 | Transform(PP); |
407 | gp_Vec DD1 = D1; |
408 | Transform(DD1); |
409 | if (myPersp) { |
410 | Standard_Real R = 1. - PP.Z() / myFocus; |
411 | Pout .SetCoord(PP .X()/R , PP.Y()/R); |
412 | D1out.SetCoord(DD1.X()/R + PP.X()*DD1.Z()/(myFocus * R*R), |
413 | DD1.Y()/R + PP.Y()*DD1.Z()/(myFocus * R*R)); |
414 | } |
415 | else { |
416 | Pout .SetCoord(PP .X(),PP .Y()); |
417 | D1out.SetCoord(DD1.X(),DD1.Y()); |
418 | } |
419 | } |
420 | |
7fd59977 |
421 | |
422 | //======================================================================= |
423 | //function : Shoot |
4952a30a |
424 | //purpose : |
7fd59977 |
425 | //======================================================================= |
426 | |
427 | gp_Lin Select3D_Projector::Shoot |
428 | (const Standard_Real X, |
429 | const Standard_Real Y) const |
430 | { |
431 | gp_Lin L; |
4952a30a |
432 | |
7fd59977 |
433 | if (myPersp) { |
434 | L = gp_Lin(gp_Pnt(0,0, myFocus), |
435 | gp_Dir(X,Y,-myFocus)); |
436 | } |
437 | else { |
438 | L = gp_Lin(gp_Pnt(X,Y,0), |
439 | gp_Dir(0,0,-1)); |
440 | } |
441 | Transform(L, myInvTrsf); |
442 | return L; |
443 | } |
444 | |
445 | |
7fd59977 |
446 | void Select3D_Projector::SetView(const Handle(V3d_View)& aViou) |
447 | { |
448 | myView = aViou; |
449 | myPersp = aViou->Type()==V3d_PERSPECTIVE; |
450 | myFocus= aViou->Focale(); |
451 | Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ; |
452 | //Standard_Boolean Pers=Standard_False; |
4952a30a |
453 | |
7fd59977 |
454 | aViou->At(Xat,Yat,Zat); |
455 | aViou->Up(XUp,YUp,ZUp); |
456 | aViou->Proj(DX,DY,DZ); |
4952a30a |
457 | gp_Pnt At (Xat,Yat,Zat); |
7fd59977 |
458 | gp_Dir Zpers (DX,DY,DZ); |
459 | gp_Dir Ypers (XUp,YUp,ZUp); |
460 | gp_Dir Xpers = Ypers.Crossed(Zpers); |
461 | gp_Ax3 Axe (At, Zpers, Xpers); |
462 | myScaledTrsf.SetTransformation(Axe); |
463 | Scaled(); |
4952a30a |
464 | |
465 | } |
466 | |
467 | void Select3D_Projector::DepthMinMax (const Standard_Real theDepthMin, |
468 | const Standard_Real theDepthMax) |
469 | { |
470 | myDepthMin = theDepthMin; |
471 | myDepthMax = theDepthMax; |
7fd59977 |
472 | } |