0024428: Implementation of LGPL license
[occt.git] / src / ApproxInt / ApproxInt_ImpPrmSvSurfaces.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
9 // under the terms of the GNU Lesser General Public 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 #include <TColStd_Array1OfReal.hxx>
18 #include <math_FunctionSetRoot.hxx>
19 #include <StdFail_NotDone.hxx>
20 #include <GeomAbs_SurfaceType.hxx>
21 #include <Precision.hxx>
22
23 #define       ComputeParametersOnImplicitSurface(MyISurf,P,u,v)  MyISurf.Parameters(P,u,v)
24
25 #define Debug(expr)  cout<<" expr :"<<expr;
26 #define MyISurf MyZerImpFunc.ISurface()
27 #define MyPSurf MyZerImpFunc.PSurface()
28
29 //--------------------------------------------------------------------------------
30 ApproxInt_ImpPrmSvSurfaces::ApproxInt_ImpPrmSvSurfaces( const TheISurface& ISurf
31                                                        ,const ThePSurface& PSurf):
32        MyHasBeenComputed(Standard_False),
33        MyHasBeenComputedbis(Standard_False),
34        MyImplicitFirst(Standard_True),
35        MyZerImpFunc(PSurf,ISurf)
36
37 }
38 //--------------------------------------------------------------------------------
39 ApproxInt_ImpPrmSvSurfaces::ApproxInt_ImpPrmSvSurfaces( const ThePSurface& PSurf
40                                                        ,const TheISurface& ISurf):
41        MyHasBeenComputed(Standard_False),
42        MyHasBeenComputedbis(Standard_False),
43        MyImplicitFirst(Standard_False),
44        MyZerImpFunc(PSurf,ISurf)
45
46 }
47 //--------------------------------------------------------------------------------
48 void ApproxInt_ImpPrmSvSurfaces::Pnt(const Standard_Real u1,
49                                      const Standard_Real v1,
50                                      const Standard_Real u2,
51                                      const Standard_Real v2,
52                                      gp_Pnt& P) { 
53   gp_Pnt aP;
54   gp_Vec aT;
55   gp_Vec2d aTS1,aTS2;
56   Standard_Real tu1=u1;
57   Standard_Real tu2=u2;
58   Standard_Real tv1=v1;
59   Standard_Real tv2=v2;
60   this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
61   P=MyPnt;
62 }
63 //--------------------------------------------------------------------------------
64 Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Tangency(const Standard_Real u1,
65                                                       const Standard_Real v1,
66                                                       const Standard_Real u2,
67                                                       const Standard_Real v2,
68                                                       gp_Vec& T) { 
69   gp_Pnt aP;
70   gp_Vec aT;
71   gp_Vec2d aTS1,aTS2;
72   Standard_Real tu1=u1;
73   Standard_Real tu2=u2;
74   Standard_Real tv1=v1;
75   Standard_Real tv2=v2;
76   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
77   T=MyTg;
78   return(t);
79 }
80 //--------------------------------------------------------------------------------
81 Standard_Boolean ApproxInt_ImpPrmSvSurfaces::TangencyOnSurf1(const Standard_Real u1,
82                                                              const Standard_Real v1,
83                                                              const Standard_Real u2,
84                                                              const Standard_Real v2,
85                                                              gp_Vec2d& T) { 
86   gp_Pnt aP;
87   gp_Vec aT;
88   gp_Vec2d aTS1,aTS2;
89   Standard_Real tu1=u1;
90   Standard_Real tu2=u2;
91   Standard_Real tv1=v1;
92   Standard_Real tv2=v2;
93   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
94   T=MyTguv1;
95   return(t);
96 }
97 //--------------------------------------------------------------------------------
98 Standard_Boolean ApproxInt_ImpPrmSvSurfaces::TangencyOnSurf2(const Standard_Real u1,
99                                                              const Standard_Real v1,
100                                                              const Standard_Real u2,
101                                                              const Standard_Real v2,
102                                                              gp_Vec2d& T) { 
103   gp_Pnt aP;
104   gp_Vec aT;
105   gp_Vec2d aTS1,aTS2;
106   Standard_Real tu1=u1;
107   Standard_Real tu2=u2;
108   Standard_Real tv1=v1;
109   Standard_Real tv2=v2;
110   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
111   T=MyTguv2;
112   return(t);
113 }
114 //--------------------------------------------------------------------------------
115 Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
116                                                      ,Standard_Real& v1
117                                                      ,Standard_Real& u2
118                                                      ,Standard_Real& v2
119                                                      ,gp_Pnt& P
120                                                      ,gp_Vec& Tg
121                                                      ,gp_Vec2d& Tguv1
122                                                      ,gp_Vec2d& Tguv2) { 
123   
124   Standard_Real tu1=u1;
125   Standard_Real tu2=u2;
126   Standard_Real tv1=v1;
127   Standard_Real tv2=v2;
128   
129   if(MyHasBeenComputed) { 
130     if(  (MyParOnS1.X()==u1)&&(MyParOnS1.Y()==v1)
131        &&(MyParOnS2.X()==u2)&&(MyParOnS2.Y()==v2)) {
132       return(MyIsTangent);
133     }
134     else if(MyHasBeenComputedbis == Standard_False) { 
135       MyTgbis         = MyTg;
136       MyTguv1bis      = MyTguv1;
137       MyTguv2bis      = MyTguv2;
138       MyPntbis        = MyPnt;
139       MyParOnS1bis    = MyParOnS1;
140       MyParOnS2bis    = MyParOnS2;
141       MyIsTangentbis  = MyIsTangent;
142       MyHasBeenComputedbis = MyHasBeenComputed; 
143     }
144   }
145
146   if(MyHasBeenComputedbis) { 
147     if(  (MyParOnS1bis.X()==u1)&&(MyParOnS1bis.Y()==v1)
148        &&(MyParOnS2bis.X()==u2)&&(MyParOnS2bis.Y()==v2)) {
149
150       gp_Vec            TV(MyTg);
151       gp_Vec2d          TV1(MyTguv1);
152       gp_Vec2d          TV2(MyTguv2);
153       gp_Pnt            TP(MyPnt);
154       gp_Pnt2d          TP1(MyParOnS1);
155       gp_Pnt2d          TP2(MyParOnS2);
156       Standard_Boolean  TB=MyIsTangent;
157
158       MyTg        = MyTgbis;
159       MyTguv1     = MyTguv1bis;
160       MyTguv2     = MyTguv2bis;
161       MyPnt       = MyPntbis;
162       MyParOnS1   = MyParOnS1bis;
163       MyParOnS2   = MyParOnS2bis;
164       MyIsTangent = MyIsTangentbis;
165
166       MyTgbis         = TV;
167       MyTguv1bis      = TV1;
168       MyTguv2bis      = TV2;
169       MyPntbis        = TP;
170       MyParOnS1bis    = TP1;
171       MyParOnS2bis    = TP2;
172       MyIsTangentbis  = TB;
173
174       return(MyIsTangent);
175     }
176   }
177
178
179   Standard_Real aBornInf[2],aBornSup[2],aF[1],aX[2],aTolerance[2];
180   math_Vector BornInf(aBornInf,1,2),BornSup(aBornSup,1,2),F(aF,1,1),
181     X(aX,1,2),Tolerance(aTolerance,1,2);
182   Standard_Real aD[1][2];
183   math_Matrix D(aD,1, 1, 1, 2); 
184
185   Standard_Real binfu,bsupu,binfv,bsupv;
186   binfu = ThePSurfaceTool::FirstUParameter(MyPSurf);
187   binfv = ThePSurfaceTool::FirstVParameter(MyPSurf);
188   bsupu = ThePSurfaceTool::LastUParameter(MyPSurf);
189   bsupv = ThePSurfaceTool::LastVParameter(MyPSurf);
190   BornInf(1) = binfu; BornSup(1) = bsupu; 
191   BornInf(2) = binfv; BornSup(2) = bsupv;
192
193   //--- ThePSurfaceTool::GetResolution(MyPSurf,Tolerance(1),Tolerance(2));
194   Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
195
196   Standard_Real TranslationU=0.0;
197   Standard_Real TranslationV=0.0;
198
199   math_FunctionSetRoot  Rsnld(MyZerImpFunc);
200   Rsnld.SetTolerance(Tolerance);
201   if(MyImplicitFirst) { 
202     if(u2<binfu-0.0000000001) { 
203       if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
204         Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
205         do {  TranslationU+=d; } while(u2+TranslationU < binfu);
206       }
207       else { 
208         MyIsTangent=MyIsTangentbis=Standard_False;
209         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
210         return(Standard_False);
211       }
212     }
213     else if(u2>bsupu+0.0000000001) { 
214       if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
215         Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
216         do { TranslationU-=d; } while(u2+TranslationU > bsupu);
217       }
218       else { 
219         MyIsTangent=MyIsTangentbis=Standard_False;
220         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
221         return(Standard_False);
222       } 
223     }
224     if(v2<binfv-0.0000000001) { 
225       if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
226         Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
227         do { TranslationV+=d; } while(v2+TranslationV < binfv);
228       }
229       else { 
230         MyIsTangent=MyIsTangentbis=Standard_False;
231         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
232         return(Standard_False);
233       }
234     }
235     else if(v2>bsupv+0.0000000001) { 
236       if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
237         Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
238         do { TranslationV-=d; } while(v2+TranslationV > bsupv);
239       }
240       else { 
241         MyIsTangent=MyIsTangentbis=Standard_False;
242         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
243         return(Standard_False);
244       } 
245     }
246     X(1) = u2+TranslationU; 
247     X(2) = v2+TranslationV;
248   }
249   else { 
250     if(u1<binfu-0.0000000001) { 
251       if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
252         Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
253         do {  TranslationU+=d;  } while(u1+TranslationU < binfu);
254       }
255       else { 
256         MyIsTangent=MyIsTangentbis=Standard_False;
257         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
258         return(Standard_False);
259       }
260     }
261     else if(u1>bsupu+0.0000000001) { 
262       if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
263         Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
264         do { TranslationU-=d; } while(u1+TranslationU > bsupu);
265       }
266       else { 
267         MyIsTangent=MyIsTangentbis=Standard_False;
268         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
269         return(Standard_False);
270       } 
271     }
272     if(v1<binfv-0.0000000001) { 
273       if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
274         Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
275         do { TranslationV+=d; } while(v1+TranslationV < binfv);
276       }
277       else { 
278         MyIsTangent=MyIsTangentbis=Standard_False;
279         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
280         return(Standard_False);
281       }
282     }
283     else if(v1>bsupv+0.0000000001) { 
284       if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
285         Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
286         do { TranslationV-=d; } while(v1+TranslationV > bsupv);
287       }
288       else { 
289         MyIsTangent=MyIsTangentbis=Standard_False;
290         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
291         return(Standard_False);
292       } 
293     }
294     X(1) = u1+TranslationU;
295     X(2) = v1+TranslationV;
296   }
297   
298   //----------------------------------------------------
299   //-- Pour eviter de coller le point de depart de la 
300   //-- recherche sur une des bornes (Rsnld -> NotDone)
301   //-- 
302   if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001;
303   if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001;
304   if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001;
305   if(X(2)+0.0000000001 >= bsupv) X(2)=X(2)-0.0000001;
306   
307
308   Standard_Real PourTesterU = X(1);
309   Standard_Real PourTesterV = X(2);
310   
311
312   /* ***************************************************************
313   cout<<" Envoi a Rsnld : "; Debug(X(1)); Debug(X(2)); 
314   Debug(BornInf(1)); Debug(BornInf(2));
315   Debug(BornSup(1)); Debug(BornSup(2)); cout<<endl;
316   Debug(u1); Debug(v1); Debug(u2); Debug(v2); Debug(MyImplicitFirst); 
317   cout<<endl;
318   **************************************************************** */
319
320   Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup);
321   if(Rsnld.IsDone()) { 
322     MyHasBeenComputed = Standard_True;
323     Rsnld.Root(X);
324     
325     Standard_Real DistAvantApresU = Abs(PourTesterU-X(1));
326     Standard_Real DistAvantApresV = Abs(PourTesterV-X(2));
327  
328     MyPnt = P = ThePSurfaceTool::Value(MyPSurf,X(1),X(2));
329     
330     if(   (DistAvantApresV <= 0.001 )
331        && (DistAvantApresU <= 0.001 )) { 
332       
333       gp_Vec PD1U,PD1V;
334       gp_Vec ID1U,ID1V;
335       
336       
337       if(MyImplicitFirst) { 
338         u2 = X(1)-TranslationU; 
339         v2 = X(2)-TranslationV;
340         ComputeParametersOnImplicitSurface(MyISurf,P,u1,v1);
341         if(MyISurf.TypeQuadric() != GeomAbs_Plane) { 
342           while(u1-tu1>M_PI)  u1-=M_PI+M_PI;
343           while(tu1-u1>M_PI)  u1+=M_PI+M_PI;
344         }
345         MyParOnS1.SetCoord(tu1,tv1);
346         MyParOnS2.SetCoord(tu2,tv2);
347         ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V);
348         MyISurf.D1(u1,v1,P,ID1U,ID1V);
349       }
350       else { 
351         u1 = X(1)-TranslationU;
352         v1 = X(2)-TranslationV;
353         ComputeParametersOnImplicitSurface(MyISurf,P,u2,v2);
354         if(MyISurf.TypeQuadric() != GeomAbs_Plane) { 
355           while(u2-tu2>M_PI)  u2-=M_PI+M_PI;
356           while(tu2-u2>M_PI)  u2+=M_PI+M_PI;
357         }
358         MyParOnS1.SetCoord(tu1,tv1);
359         MyParOnS2.SetCoord(tu2,tu2);
360         ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V);
361         MyISurf.D1(u2,v2,P,ID1U,ID1V);
362       }
363       
364       
365       gp_Vec VNormaleImp = MyISurf.Normale(MyPnt);
366       gp_Vec VNormalePrm = PD1U.Crossed(PD1V);
367       if(   VNormaleImp.SquareMagnitude() <= gp::Resolution()
368          || VNormalePrm.SquareMagnitude() <= gp::Resolution()) { 
369         MyIsTangent = Standard_False;
370         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
371         return(Standard_False);
372       }
373       
374       gp_Dir NormaleImp(VNormaleImp);
375       gp_Dir NormalePrm(VNormalePrm);
376       
377       gp_Vec VNImp(NormaleImp);
378       gp_Vec VNPrm(NormalePrm);
379       MyTg = VNImp.Crossed(VNPrm);
380       Standard_Real NmyTg = MyTg.Magnitude();
381       if(NmyTg < 0.000001) { 
382         MyIsTangent = Standard_False;
383         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
384         return(Standard_False);
385       }
386       MyTg.SetCoord(MyTg.X()/NmyTg,MyTg.Y()/NmyTg,MyTg.Z()/NmyTg);
387       
388       
389       MyTg              = NormaleImp.Crossed(NormalePrm);
390       Tg = MyTg;
391       
392       Standard_Real TUTV,TgTU,TgTV,TUTU,TVTV,DIS;
393       Standard_Real DeltaU,DeltaV;
394       TUTU = PD1U.Dot(PD1U);
395       TVTV = PD1V.Dot(PD1V);
396       TUTV = PD1U.Dot(PD1V);
397       TgTU = MyTg.Dot(PD1U);
398       TgTV = MyTg.Dot(PD1V);
399       DIS  = TUTU * TVTV - TUTV * TUTV;
400       
401       if(DIS<1e-10 && DIS>-1e-10) {
402         MyIsTangent = Standard_False;
403         MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
404         return(Standard_False);
405       }
406
407
408       DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ; 
409       DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ;
410       
411       if(MyImplicitFirst) { 
412         MyTguv1.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
413                          ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
414         MyTguv2.SetCoord(DeltaU,DeltaV);
415         Tguv1 = MyTguv1;
416         Tguv2 = MyTguv2;
417       }
418       else { 
419         MyTguv1.SetCoord(DeltaU,DeltaV);
420         MyTguv2.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
421                          ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
422         Tguv1 = MyTguv1;
423         Tguv2 = MyTguv2;
424       }
425       MyIsTangent=Standard_True;
426       return(Standard_True); 
427     }
428     else { 
429       
430       //-- cout<<" ApproxInt_ImpImpSvSurfaces.gxx : Distance apres recadrage Trop Grande "<<endl;
431     
432       MyIsTangent=Standard_False;
433       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
434       return(Standard_False);
435     }
436   }
437   else { 
438     MyIsTangent = Standard_False;
439     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
440     return(Standard_False);
441   }
442 }
443
444 //--------------------------------------------------------------------------------
445
446
447
448
449