1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 Blend_Status Blend_Walking::TestArret(Blend_Function& Function,
16 const Blend_Status State,
17 const Standard_Boolean TestDefl,
18 const Standard_Boolean TestSolu,
19 const Standard_Boolean TestLengthStep)
21 // On regarde si le point donne est solution.
23 // On verifie le critere de fleche sur surf1 et surf2
24 // Si OK, on classifie les points sur surf1 et sur surf2.
25 // Si les deux sont dedans : on retourne Blend_OK
26 // sinon si un seul est dedans
27 // on resout le pb inverse sur la restriction concernee
28 // sinon on resout le pb inverse sur la surface pour laquelle
29 // le point est le plus loin.
30 // sinon (fleche non OK)
31 // on renvoie Blend_StepTooLarge.
32 // sinon on renvoie Blend_StepTooLarge.
38 gp_Vec Tgp1,Tgp2,Nor1,Nor2;
40 Blend_Status State1,State2;
41 IntSurf_TypeTrans tras1,tras2;
43 Standard_Boolean loctwist1 = Standard_False, loctwist2 = Standard_False;
44 Standard_Real tolsolu = tolesp;
46 if ( !TestSolu) tolsolu *= 1000; //Ca doit toujours etre bon
47 if (Function.IsSolution(sol,tolsolu)) {
52 Standard_Boolean curpointistangent = Function.IsTangencyPoint();
53 pt1 = Function.PointOnS1();
54 pt2 = Function.PointOnS2();
55 if(curpointistangent){
56 curpoint.SetValue(pt1,pt2,param,
57 sol(1),sol(2),sol(3),sol(4));
60 V1 = Function.TangentOnS1();
61 V2 = Function.TangentOnS2();
62 V12d = Function.Tangent2dOnS1();
63 V22d = Function.Tangent2dOnS2();
64 curpoint.SetValue(pt1,pt2,param,
65 sol(1),sol(2),sol(3),sol(4),
67 if(Function.TwistOnS1()) loctwist1 = Standard_True;
68 if(Function.TwistOnS2()) loctwist2 = Standard_True;
71 if (TestDefl && check) {
73 // Verification du critere de fleche sur chaque surface
74 //et sur la ligne guide
76 State1 = CheckDeflection(Standard_True,curpoint);
77 State2 = CheckDeflection(Standard_False,curpoint);
83 // On verifie juste que le pas n'est pas trop grand
84 // (Cas des prolongements foireux)
85 Standard_Real curparamu,curparamv, prevparamu,prevparamv;
86 math_Vector inf(1,4), sup(1,4);
87 Function.GetBounds(inf, sup);
89 sup *= 0.05; // Pas max : 5% du domaine
91 curpoint.ParametersOnS1(curparamu,curparamv);
92 previousP.ParametersOnS1(prevparamu,prevparamv);
93 if (Abs(curparamu-prevparamu) > sup(1)) State1 = Blend_StepTooLarge;
94 if (Abs(curparamv-prevparamv) > sup(2)) State1 = Blend_StepTooLarge;
95 curpoint.ParametersOnS2(curparamu,curparamv);
96 previousP.ParametersOnS2(prevparamu,prevparamv);
97 if (Abs(curparamu-prevparamu) > sup(3)) State2 = Blend_StepTooLarge;
98 if (Abs(curparamv-prevparamv) > sup(4)) State2 = Blend_StepTooLarge;
102 if (State1 == Blend_Backward) {
103 State1 = Blend_StepTooLarge;
104 rebrou= Standard_True;
107 if (State2 == Blend_Backward) {
108 State2 = Blend_StepTooLarge;
109 rebrou = Standard_True;
112 if (State1 == Blend_StepTooLarge ||
113 State2 == Blend_StepTooLarge) {
115 return Blend_StepTooLarge;
119 // Ici seulement on peut statuer sur le twist
120 // Car les rejet ont ete effectue (BUC60322)
121 if (loctwist1) twistflag1 = Standard_True;
122 if (loctwist2) twistflag2 = Standard_True;
124 if (!comptra && !curpointistangent) {
125 Function.Tangent(sol(1),sol(2),sol(3),sol(4),Tgp1,Tgp2,Nor1,Nor2);
128 Standard_Real testra = Tgp1.Dot(Nor1.Crossed(V1));
129 if (Abs(testra) > Precision::Confusion()) {
131 if ((testra > 0. && !loctwist1) || (testra < 0. && loctwist1)) {
135 testra = Tgp2.Dot(Nor2.Crossed(V2));
136 if (Abs(testra) > Precision::Confusion()) {
138 if ((testra > 0. && !loctwist2) || (testra < 0. && loctwist2)) {
141 comptra = Standard_True;
142 line->Set(tras1,tras2);
147 if (State1 == Blend_OK ||
148 State2 == Blend_OK ) {
149 previousP = curpoint;
153 if (State1 == Blend_StepTooSmall &&
154 State2 == Blend_StepTooSmall) {
155 previousP = curpoint;
156 if (State == Blend_OK) {
157 return Blend_StepTooSmall;
164 if (State == Blend_OK) {
165 return Blend_SamePoints;
173 return Blend_StepTooLarge;
178 Blend_Status Blend_Walking::CheckDeflection
179 (const Standard_Boolean OnFirst,
180 const Blend_Point& CurPoint)
182 // regle par tests dans U4 correspond a 11.478 d
183 const Standard_Real CosRef3D = 0.98;
185 const Standard_Real CosRef2D = 0.88; // correspond a 25 d
187 Standard_Real Norme, Cosi, Cosi2;
188 Standard_Real prevNorme = 0.;
189 Standard_Real FlecheCourante;
190 Standard_Real Du,Dv,Duv;
191 Standard_Real tolu,tolv;
196 Standard_Real curparamu, curparamv;
197 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
201 gp_Vec2d previousd2d;
202 Standard_Real prevparamu, prevparamv;
203 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
206 Psurf = CurPoint.PointOnS1();
207 if(!curpointistangent){
208 Tgsurf = CurPoint.TangentOnS1();
210 prevP = previousP.PointOnS1();
211 if(!prevpointistangent){
212 prevTg = previousP.TangentOnS1();
214 tolu = TheSurfaceTool::UResolution(surf1,tolesp);
215 tolv = TheSurfaceTool::VResolution(surf1,tolesp);
218 Psurf = CurPoint.PointOnS2();
219 if(!curpointistangent){
220 Tgsurf = CurPoint.TangentOnS2();
222 prevP = previousP.PointOnS2();
223 if(!prevpointistangent){
224 prevTg = previousP.TangentOnS2();
226 tolu = TheSurfaceTool::UResolution(surf2,tolesp);
227 tolv = TheSurfaceTool::VResolution(surf2,tolesp);
230 gp_Vec Corde(prevP,Psurf);
231 Norme = Corde.SquareMagnitude();
232 // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
233 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
236 if (Norme <= tolesp*tolesp){
237 // il faudra peut etre forcer meme point
238 return Blend_SamePoints;
240 if(!prevpointistangent){
241 if(prevNorme <= tolesp*tolesp) {
242 return Blend_SamePoints;
244 Cosi = sens*Corde*prevTg;
245 if (Cosi <0.) { // angle 3d>pi/2. --> retour arriere
246 return Blend_Backward;
249 Cosi2 = Cosi * Cosi / prevNorme / Norme;
250 if (Cosi2 < CosRef3D) {
251 return Blend_StepTooLarge;
255 if(!curpointistangent){
256 // Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
257 Cosi = sens*Corde*Tgsurf;
258 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
259 if (Cosi2 < CosRef3D || Cosi < 0.) {
260 return Blend_StepTooLarge;
266 CurPoint.ParametersOnS1(curparamu,curparamv);
267 if(!curpointistangent) Tgonsurf = CurPoint.Tangent2dOnS1();
268 previousP.ParametersOnS1(prevparamu,prevparamv);
269 if(!prevpointistangent) previousd2d = previousP.Tangent2dOnS1();
272 CurPoint.ParametersOnS2(curparamu,curparamv);
273 if(!curpointistangent) Tgonsurf = CurPoint.Tangent2dOnS2();
274 previousP.ParametersOnS2(prevparamu,prevparamv);
275 if(!prevpointistangent) previousd2d = previousP.Tangent2dOnS2();
278 Du = curparamu - prevparamu;
279 Dv = curparamv - prevparamv;
280 Duv = Du * Du + Dv * Dv;
281 // SqrtDuv = Sqrt(Duv);
282 if (Abs(Du) < tolu && Abs(Dv) < tolv){
283 // il faudra peut etre forcer meme point
284 return Blend_SamePoints; //point confondu 2d
286 if(!prevpointistangent){
287 if(Abs(previousd2d.X()) < tolu && Abs(previousd2d.Y()) < tolv){
288 // il faudra peut etre forcer meme point
289 return Blend_SamePoints; //point confondu 2d
291 Cosi = sens*(Du * previousd2d.X() + Dv * previousd2d.Y());
293 return Blend_Backward;
296 if(!curpointistangent){
297 // Voir s il faut faire le controle sur le signe de Cosi
298 Cosi = sens*(Du * Tgonsurf.X() + Dv * Tgonsurf.Y())/Tgonsurf.Magnitude();
299 Cosi2 = Cosi * Cosi / Duv;
300 if (Cosi2 < CosRef2D || Cosi <0.) {
301 return Blend_StepTooLarge;
305 if(!curpointistangent && !prevpointistangent){
306 // Estimation de la fleche courante
307 FlecheCourante = (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
309 if (FlecheCourante <= 0.25*fleche*fleche) {
310 return Blend_StepTooSmall;
312 if (FlecheCourante > fleche*fleche) {
313 // pas trop grand : commentaire interessant
314 return Blend_StepTooLarge;