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
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License 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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TColStd_Array1OfReal.hxx>
18 #include <math_FunctionSetRoot.hxx>
19 #include <StdFail_NotDone.hxx>
20 #include <GeomAbs_SurfaceType.hxx>
21 #include <Precision.hxx>
23 #define ComputeParametersOnImplicitSurface(MyISurf,P,u,v) MyISurf.Parameters(P,u,v)
25 #define Debug(expr) cout<<" expr :"<<expr;
26 #define MyISurf MyZerImpFunc.ISurface()
27 #define MyPSurf MyZerImpFunc.PSurface()
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)
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)
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,
60 this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
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,
76 Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
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,
93 Standard_Boolean t=this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
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,
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);
114 //--------------------------------------------------------------------------------
115 Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
124 Standard_Real tu1=u1;
125 Standard_Real tu2=u2;
126 Standard_Real tv1=v1;
127 Standard_Real tv2=v2;
129 if(MyHasBeenComputed) {
130 if( (MyParOnS1.X()==u1)&&(MyParOnS1.Y()==v1)
131 &&(MyParOnS2.X()==u2)&&(MyParOnS2.Y()==v2)) {
134 else if(MyHasBeenComputedbis == Standard_False) {
136 MyTguv1bis = MyTguv1;
137 MyTguv2bis = MyTguv2;
139 MyParOnS1bis = MyParOnS1;
140 MyParOnS2bis = MyParOnS2;
141 MyIsTangentbis = MyIsTangent;
142 MyHasBeenComputedbis = MyHasBeenComputed;
146 if(MyHasBeenComputedbis) {
147 if( (MyParOnS1bis.X()==u1)&&(MyParOnS1bis.Y()==v1)
148 &&(MyParOnS2bis.X()==u2)&&(MyParOnS2bis.Y()==v2)) {
151 gp_Vec2d TV1(MyTguv1);
152 gp_Vec2d TV2(MyTguv2);
154 gp_Pnt2d TP1(MyParOnS1);
155 gp_Pnt2d TP2(MyParOnS2);
156 Standard_Boolean TB=MyIsTangent;
159 MyTguv1 = MyTguv1bis;
160 MyTguv2 = MyTguv2bis;
162 MyParOnS1 = MyParOnS1bis;
163 MyParOnS2 = MyParOnS2bis;
164 MyIsTangent = MyIsTangentbis;
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);
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;
193 //--- ThePSurfaceTool::GetResolution(MyPSurf,Tolerance(1),Tolerance(2));
194 Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
196 Standard_Real TranslationU=0.0;
197 Standard_Real TranslationV=0.0;
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);
208 MyIsTangent=MyIsTangentbis=Standard_False;
209 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
210 return(Standard_False);
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);
219 MyIsTangent=MyIsTangentbis=Standard_False;
220 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
221 return(Standard_False);
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);
230 MyIsTangent=MyIsTangentbis=Standard_False;
231 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
232 return(Standard_False);
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);
241 MyIsTangent=MyIsTangentbis=Standard_False;
242 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
243 return(Standard_False);
246 X(1) = u2+TranslationU;
247 X(2) = v2+TranslationV;
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);
256 MyIsTangent=MyIsTangentbis=Standard_False;
257 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
258 return(Standard_False);
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);
267 MyIsTangent=MyIsTangentbis=Standard_False;
268 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
269 return(Standard_False);
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);
278 MyIsTangent=MyIsTangentbis=Standard_False;
279 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
280 return(Standard_False);
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);
289 MyIsTangent=MyIsTangentbis=Standard_False;
290 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
291 return(Standard_False);
294 X(1) = u1+TranslationU;
295 X(2) = v1+TranslationV;
298 //----------------------------------------------------
299 //-- Pour eviter de coller le point de depart de la
300 //-- recherche sur une des bornes (Rsnld -> NotDone)
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;
308 Standard_Real PourTesterU = X(1);
309 Standard_Real PourTesterV = X(2);
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);
318 **************************************************************** */
320 Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup);
322 MyHasBeenComputed = Standard_True;
325 Standard_Real DistAvantApresU = Abs(PourTesterU-X(1));
326 Standard_Real DistAvantApresV = Abs(PourTesterV-X(2));
328 MyPnt = P = ThePSurfaceTool::Value(MyPSurf,X(1),X(2));
330 if( (DistAvantApresV <= 0.001 )
331 && (DistAvantApresU <= 0.001 )) {
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;
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);
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;
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);
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);
374 gp_Dir NormaleImp(VNormaleImp);
375 gp_Dir NormalePrm(VNormalePrm);
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);
386 MyTg.SetCoord(MyTg.X()/NmyTg,MyTg.Y()/NmyTg,MyTg.Z()/NmyTg);
389 MyTg = NormaleImp.Crossed(NormalePrm);
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;
401 if(DIS<1e-10 && DIS>-1e-10) {
402 MyIsTangent = Standard_False;
403 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
404 return(Standard_False);
408 DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ;
409 DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ;
411 if(MyImplicitFirst) {
412 MyTguv1.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
413 ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
414 MyTguv2.SetCoord(DeltaU,DeltaV);
419 MyTguv1.SetCoord(DeltaU,DeltaV);
420 MyTguv2.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
421 ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
425 MyIsTangent=Standard_True;
426 return(Standard_True);
430 //-- cout<<" ApproxInt_ImpImpSvSurfaces.gxx : Distance apres recadrage Trop Grande "<<endl;
432 MyIsTangent=Standard_False;
433 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
434 return(Standard_False);
438 MyIsTangent = Standard_False;
439 MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
440 return(Standard_False);
444 //--------------------------------------------------------------------------------