0023952: Improving thread-safety of intersections, approximations and other modeling...
[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-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 #define TOLTANGENCY 0.0000000001
23
24
25 #include <TColStd_Array1OfReal.hxx>
26 #include <math_FunctionSetRoot.hxx>
27 #include <Precision.hxx>
28
29 #define Debug(expr)  cout<<" expr :"<<expr;
30 #define MySurf1 MyIntersectionOn2S.Function().AuxillarSurface1()
31 #define MySurf2 MyIntersectionOn2S.Function().AuxillarSurface2()
32
33
34 //--------------------------------------------------------------------------------
35 ApproxInt_PrmPrmSvSurfaces::ApproxInt_PrmPrmSvSurfaces( const ThePSurface& Surf1
36                                                        ,const ThePSurface& Surf2):
37        MyHasBeenComputed(Standard_False),
38        MyHasBeenComputedbis(Standard_False),
39        MyIntersectionOn2S(Surf1,Surf2,TOLTANGENCY)
40
41 }
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 #ifdef DEB
227   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
228 #else
229   this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
230 #endif
231   P=MyPnt;
232 }
233 //--------------------------------------------------------------------------------
234 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Tangency(const Standard_Real u1,
235                                                       const Standard_Real v1,
236                                                       const Standard_Real u2,
237                                                       const Standard_Real v2,
238                                                       gp_Vec& T) { 
239   gp_Pnt aP;
240   gp_Vec aT;
241   gp_Vec2d aTS1,aTS2;
242   Standard_Real tu1=u1;
243   Standard_Real tu2=u2;
244   Standard_Real tv1=v1;
245   Standard_Real tv2=v2;
246   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
247   T=MyTg;
248   return(t);
249 }
250 //--------------------------------------------------------------------------------
251 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::TangencyOnSurf1(const Standard_Real u1,
252                                                              const Standard_Real v1,
253                                                              const Standard_Real u2,
254                                                              const Standard_Real v2,
255                                                              gp_Vec2d& T) { 
256   gp_Pnt aP;
257   gp_Vec aT;
258   gp_Vec2d aTS1,aTS2;
259   Standard_Real tu1=u1;
260   Standard_Real tu2=u2;
261   Standard_Real tv1=v1;
262   Standard_Real tv2=v2;
263   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
264   T=MyTguv1;
265   return(t);
266 }
267 //--------------------------------------------------------------------------------
268 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::TangencyOnSurf2(const Standard_Real u1,
269                                                              const Standard_Real v1,
270                                                              const Standard_Real u2,
271                                                              const Standard_Real v2,
272                                                              gp_Vec2d& T) { 
273   gp_Pnt aP;
274   gp_Vec aT;
275   gp_Vec2d aTS1,aTS2;
276   Standard_Real tu1=u1;
277   Standard_Real tu2=u2;
278   Standard_Real tv1=v1;
279   Standard_Real tv2=v2;
280   Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
281   T=MyTguv2;
282   return(t);
283 }
284 //--------------------------------------------------------------------------------
285
286
287
288
289 #if 0 
290   //------------------------------------------------------------
291   //-- Calcul de Tguv1
292   //--
293   ThePSurfaceTool::D1(MySurf1,u1,v1,P,TU,TV);
294   
295   TUTV = TU.Dot(TV);
296   TgTU = Tg.Dot(TU);
297   TgTV = Tg.Dot(TV);
298   UmTUTV2 = 1.0 - TUTV * TUTV;
299   
300   DeltaU = (TgTU - TgTV * TUTV ) / UmTUTV2 ; 
301   DeltaV = (TgTV - TgTU * TUTV ) / UmTUTV2 ;
302
303   Delta = 1.0 / Sqrt(DeltaU * DeltaU + DeltaV * DeltaV);
304   
305   Tguv1.Multiplied(Delta);  MyTguv1 = Tguv1;
306
307   //------------------------------------------------------------
308   //-- Calcul de Tguv2
309   //--  
310   ThePSurfaceTool::D1(MySurf2,u2,v2,P,TU,TV);
311
312   TUTV = TU.Dot(TV);
313   TgTU = Tg.Dot(TU);
314   TgTV = Tg.Dot(TV);
315   UmTUTV2 = 1.0 - TUTV * TUTV;
316   
317   DeltaU = (TgTU - TgTV * TUTV ) / UmTUTV2 ; 
318   DeltaV = (TgTV - TgTU * TUTV ) / UmTUTV2 ;
319   
320   Delta = 1.0 / Sqrt(DeltaU * DeltaU + DeltaV * DeltaV);
321   
322   Tguv2.Multiplied(Delta);  MyTguv2 = Tguv2;
323
324   return(Standard_True);
325 }
326 #endif
327
328
329
330