0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / ApproxInt / ApproxInt_PrmPrmSvSurfaces.gxx
1 // Created on: 1993-03-17
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #define TOLTANGENCY 0.0000000001
18
19
20 #include <TColStd_Array1OfReal.hxx>
21 #include <math_FunctionSetRoot.hxx>
22 #include <Precision.hxx>
23
24 #define Debug(expr)  cout<<" expr :"<<expr;
25 #define MySurf1 MyIntersectionOn2S.Function().AuxillarSurface1()
26 #define MySurf2 MyIntersectionOn2S.Function().AuxillarSurface2()
27
28
29 //--------------------------------------------------------------------------------
30 ApproxInt_PrmPrmSvSurfaces::ApproxInt_PrmPrmSvSurfaces( const ThePSurface& Surf1
31                                                        ,const ThePSurface& Surf2):
32        MyHasBeenComputed(Standard_False),
33        MyHasBeenComputedbis(Standard_False),
34        MyIntersectionOn2S(Surf1,Surf2,TOLTANGENCY)
35
36 }
37
38 //=======================================================================
39 //function : Compute
40 //purpose  :    Computes point on curve, 3D and 2D-tangents of a curve and
41 //            parameters on the surfaces.
42 //=======================================================================
43 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Compute( Standard_Real& u1
44                                                      ,Standard_Real& v1
45                                                      ,Standard_Real& u2
46                                                      ,Standard_Real& v2
47                                                      ,gp_Pnt& P
48                                                      ,gp_Vec& Tg
49                                                      ,gp_Vec2d& Tguv1
50                                                      ,gp_Vec2d& Tguv2) { 
51   
52   Standard_Real tu1=u1;
53   Standard_Real tu2=u2;
54   Standard_Real tv1=v1;
55   Standard_Real tv2=v2;
56   
57   if(MyHasBeenComputed) { 
58     if(  (MyParOnS1.X()==u1)&&(MyParOnS1.Y()==v1)
59        &&(MyParOnS2.X()==u2)&&(MyParOnS2.Y()==v2)) {
60       return(MyIsTangent);
61     }
62     else if(MyHasBeenComputedbis == Standard_False) { 
63       MyTgbis         = MyTg;
64       MyTguv1bis      = MyTguv1;
65       MyTguv2bis      = MyTguv2;
66       MyPntbis        = MyPnt;
67       MyParOnS1bis    = MyParOnS1;
68       MyParOnS2bis    = MyParOnS2;
69       MyIsTangentbis  = MyIsTangent;
70       MyHasBeenComputedbis = MyHasBeenComputed; 
71     }
72   }
73   if(MyHasBeenComputedbis) { 
74     if(  (MyParOnS1bis.X()==u1)&&(MyParOnS1bis.Y()==v1)
75        &&(MyParOnS2bis.X()==u2)&&(MyParOnS2bis.Y()==v2)) {
76
77       gp_Vec            TV(MyTg);
78       gp_Vec2d          TV1(MyTguv1);
79       gp_Vec2d          TV2(MyTguv2);
80       gp_Pnt            TP(MyPnt);
81       gp_Pnt2d          TP1(MyParOnS1);
82       gp_Pnt2d          TP2(MyParOnS2);
83       Standard_Boolean  TB=MyIsTangent;
84
85       MyTg        = MyTgbis;
86       MyTguv1     = MyTguv1bis;
87       MyTguv2     = MyTguv2bis;
88       MyPnt       = MyPntbis;
89       MyParOnS1   = MyParOnS1bis;
90       MyParOnS2   = MyParOnS2bis;
91       MyIsTangent = MyIsTangentbis;
92
93       MyTgbis         = TV;
94       MyTguv1bis      = TV1;
95       MyTguv2bis      = TV2;
96       MyPntbis        = TP;
97       MyParOnS1bis    = TP1;
98       MyParOnS2bis    = TP2;
99       MyIsTangentbis  = TB;
100
101       return(MyIsTangent);
102     }
103   }
104
105
106   MyIsTangent = Standard_True;
107
108   Standard_Real aParam[4];//stack vs heap allocation
109   TColStd_Array1OfReal Param (aParam[0],1,4);
110   Param(1) = u1; Param(2) = v1;
111   Param(3) = u2; Param(4) = v2;
112   math_FunctionSetRoot  Rsnld(MyIntersectionOn2S.Function());
113   MyIntersectionOn2S.Perform(Param,Rsnld);
114   if (!MyIntersectionOn2S.IsDone())  { 
115     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
116     return(Standard_False);
117   }
118   if (MyIntersectionOn2S.IsEmpty()) {
119     MyIsTangent=Standard_False;
120     //cout<<"\n----- Parametree Parametree : IsEmpty ds Compute "<<endl;
121     //Debug(u1); Debug(u2); Debug(v1); Debug(v2);   cout<<endl;
122     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
123     return(Standard_False);
124   }
125   MyHasBeenComputed = Standard_True;
126   MyPnt = P = MyIntersectionOn2S.Point().Value();
127   
128   MyIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
129   MyParOnS1.SetCoord(tu1,tv1);
130   MyParOnS2.SetCoord(tu2,tv2);
131   
132   if(MyIntersectionOn2S.IsTangent()) { 
133     MyIsTangent=Standard_False;
134     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
135     return(Standard_False); 
136   }
137   MyTg    = Tg    = MyIntersectionOn2S.Direction();
138   MyTguv1 = Tguv1 = MyIntersectionOn2S.DirectionOnS1();
139   MyTguv2 = Tguv2 = MyIntersectionOn2S.DirectionOnS2();
140
141   //----------------------------------------------------------------------
142   //-- Si ( Tg )    TU et TV sont normes 
143   //-- 
144   //-- On a    Tg   =  DeltaU  *  TU    +   DeltaV  *  TV
145   //-- 
146   //-- soit :  Tg.TU  =  DeltaU  TU.TU  +   DeltaV  TU.TV
147   //--         Tg.TV  =  DeltaU  TV.TU  +   DeltaV  TV.TV 
148   //-- 
149   //-- Donc : 
150   //--
151   //--               Tg.TU TV.TV  - Tg.TV * TU.TV
152   //--   DeltaU = -------------------------------
153   //--               TU.TU TV.TV  - (TU.TV)**2
154   //-- 
155   //--               Tg.TV TU.TU  - Tg.TU * TU.TV
156   //--   DeltaV = -------------------------------
157   //--               TU.TU TV.TV  - (TU.TV)**2
158   //--
159   //--
160
161   Tg.Normalize();    MyTg = Tg; 
162
163   Standard_Real DeltaU,DeltaV;
164   gp_Vec TU,TV;
165   gp_Pnt Pbid;
166   Standard_Real TUTV,TgTU,TgTV,TUTU,TVTV,DIS;
167   //------------------------------------------------------------
168   //-- Calcul de Tguv1
169   //--
170   ThePSurfaceTool::D1(MySurf1,u1,v1,Pbid,TU,TV);
171   
172   TUTU = TU.Dot(TU);
173   TVTV = TV.Dot(TV);
174   TUTV = TU.Dot(TV);
175   TgTU = Tg.Dot(TU);
176   TgTV = Tg.Dot(TV);
177   DIS  = TUTU * TVTV - TUTV * TUTV;
178   if(fabs(DIS)<Precision::Angular()) { 
179     MyIsTangent=Standard_False;
180     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
181     return(Standard_False); 
182   }
183   
184   DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ; 
185   DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ;
186
187   Tguv1.SetCoord(DeltaU,DeltaV);  MyTguv1 = Tguv1;
188
189   //------------------------------------------------------------
190   //-- Calcul de Tguv2
191   //--  
192   ThePSurfaceTool::D1(MySurf2,u2,v2,Pbid,TU,TV);
193
194   TUTU = TU.Dot(TU);
195   TVTV = TV.Dot(TV);
196   TUTV = TU.Dot(TV);
197   TgTU = Tg.Dot(TU);
198   TgTV = Tg.Dot(TV);
199   DIS  = TUTU * TVTV - TUTV * TUTV;
200   if(fabs(DIS)<Precision::Angular()) { 
201     MyIsTangent=Standard_False;
202     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
203     return(Standard_False); 
204   }
205
206   DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ; 
207   DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ;
208   
209   Tguv2.SetCoord(DeltaU,DeltaV);  MyTguv2 = Tguv2;
210
211   return(Standard_True);
212 }
213 //--------------------------------------------------------------------------------
214 void ApproxInt_PrmPrmSvSurfaces::Pnt(const Standard_Real u1,
215                                      const Standard_Real v1,
216                                      const Standard_Real u2,
217                                      const Standard_Real v2,
218                                      gp_Pnt& P) { 
219   gp_Pnt aP;
220   gp_Vec aT;
221   gp_Vec2d aTS1,aTS2;
222   Standard_Real tu1=u1;
223   Standard_Real tu2=u2;
224   Standard_Real tv1=v1;
225   Standard_Real tv2=v2;
226   this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
227   P=MyPnt;
228 }
229
230 //=======================================================================
231 //function : SeekPoint
232 //purpose  :    Computes point on curve and
233 //            parameters on the surfaces.
234 //=======================================================================
235 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::SeekPoint(const Standard_Real u1,
236                                                        const Standard_Real v1,
237                                                        const Standard_Real u2,
238                                                        const Standard_Real v2,
239                                                        IntSurf_PntOn2S& Point)
240 {
241   gp_Pnt aP;
242   gp_Vec aT;
243   gp_Vec2d aTS1,aTS2;
244   Standard_Real tu1=u1;
245   Standard_Real tu2=u2;
246   Standard_Real tv1=v1;
247   Standard_Real tv2=v2;
248   if (!Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2))
249     return Standard_False;
250   
251   Point.SetValue(aP, tu1,tv1,tu2,tv2);
252   return Standard_True;
253 }
254 //--------------------------------------------------------------------------------
255 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Tangency(const Standard_Real u1,
256                                                       const Standard_Real v1,
257                                                       const Standard_Real u2,
258                                                       const Standard_Real v2,
259                                                       gp_Vec& T) { 
260   gp_Pnt aP;
261   gp_Vec aT;
262   gp_Vec2d aTS1,aTS2;
263   Standard_Real tu1=u1;
264   Standard_Real tu2=u2;
265   Standard_Real tv1=v1;
266   Standard_Real tv2=v2;
267   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
268   T=MyTg;
269   return(t);
270 }
271 //--------------------------------------------------------------------------------
272 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::TangencyOnSurf1(const Standard_Real u1,
273                                                              const Standard_Real v1,
274                                                              const Standard_Real u2,
275                                                              const Standard_Real v2,
276                                                              gp_Vec2d& T) { 
277   gp_Pnt aP;
278   gp_Vec aT;
279   gp_Vec2d aTS1,aTS2;
280   Standard_Real tu1=u1;
281   Standard_Real tu2=u2;
282   Standard_Real tv1=v1;
283   Standard_Real tv2=v2;
284   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
285   T=MyTguv1;
286   return(t);
287 }
288 //--------------------------------------------------------------------------------
289 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::TangencyOnSurf2(const Standard_Real u1,
290                                                              const Standard_Real v1,
291                                                              const Standard_Real u2,
292                                                              const Standard_Real v2,
293                                                              gp_Vec2d& T) { 
294   gp_Pnt aP;
295   gp_Vec aT;
296   gp_Vec2d aTS1,aTS2;
297   Standard_Real tu1=u1;
298   Standard_Real tu2=u2;
299   Standard_Real tv1=v1;
300   Standard_Real tv2=v2;
301   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
302   T=MyTguv2;
303   return(t);
304 }
305 //--------------------------------------------------------------------------------
306
307
308
309
310 #if 0 
311   //------------------------------------------------------------
312   //-- Calcul de Tguv1
313   //--
314   ThePSurfaceTool::D1(MySurf1,u1,v1,P,TU,TV);
315   
316   TUTV = TU.Dot(TV);
317   TgTU = Tg.Dot(TU);
318   TgTV = Tg.Dot(TV);
319   UmTUTV2 = 1.0 - TUTV * TUTV;
320   
321   DeltaU = (TgTU - TgTV * TUTV ) / UmTUTV2 ; 
322   DeltaV = (TgTV - TgTU * TUTV ) / UmTUTV2 ;
323
324   Delta = 1.0 / Sqrt(DeltaU * DeltaU + DeltaV * DeltaV);
325   
326   Tguv1.Multiplied(Delta);  MyTguv1 = Tguv1;
327
328   //------------------------------------------------------------
329   //-- Calcul de Tguv2
330   //--  
331   ThePSurfaceTool::D1(MySurf2,u2,v2,P,TU,TV);
332
333   TUTV = TU.Dot(TV);
334   TgTU = Tg.Dot(TU);
335   TgTV = Tg.Dot(TV);
336   UmTUTV2 = 1.0 - TUTV * TUTV;
337   
338   DeltaU = (TgTU - TgTV * TUTV ) / UmTUTV2 ; 
339   DeltaV = (TgTV - TgTU * TUTV ) / UmTUTV2 ;
340   
341   Delta = 1.0 / Sqrt(DeltaU * DeltaU + DeltaV * DeltaV);
342   
343   Tguv2.Multiplied(Delta);  MyTguv2 = Tguv2;
344
345   return(Standard_True);
346 }
347 #endif
348
349
350
351