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