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