0023952: Improving thread-safety of intersections, approximations and other modeling...
[occt.git] / src / ApproxInt / ApproxInt_ImpPrmSvSurfaces.gxx
CommitLineData
b311480e 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
7fd59977 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//--------------------------------------------------------------------------------
35ApproxInt_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//--------------------------------------------------------------------------------
44ApproxInt_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//--------------------------------------------------------------------------------
53void 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//--------------------------------------------------------------------------------
73Standard_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//--------------------------------------------------------------------------------
90Standard_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//--------------------------------------------------------------------------------
107Standard_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//--------------------------------------------------------------------------------
124Standard_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
1ef32e96
RL
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);
7fd59977 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) {
c6541a0c
D
351 while(u1-tu1>M_PI) u1-=M_PI+M_PI;
352 while(tu1-u1>M_PI) u1+=M_PI+M_PI;
7fd59977 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) {
c6541a0c
D
364 while(u2-tu2>M_PI) u2-=M_PI+M_PI;
365 while(tu2-u2>M_PI) u2+=M_PI+M_PI;
7fd59977 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