b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
b311480e |
14 | |
7fd59977 |
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) |
20 | |
21 | // On regarde si le point donne est solution. |
22 | // Si c est le cas, |
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. |
33 | // |
34 | |
35 | { |
36 | gp_Pnt pt1,pt2; |
37 | gp_Vec V1,V2; |
38 | gp_Vec Tgp1,Tgp2,Nor1,Nor2; |
39 | gp_Vec2d V12d,V22d; |
40 | Blend_Status State1,State2; |
41 | IntSurf_TypeTrans tras1,tras2; |
42 | Blend_Point curpoint; |
43 | Standard_Boolean loctwist1 = Standard_False, loctwist2 = Standard_False; |
44 | Standard_Real tolsolu = tolesp; |
45 | |
46 | if ( !TestSolu) tolsolu *= 1000; //Ca doit toujours etre bon |
47 | if (Function.IsSolution(sol,tolsolu)) { |
48 | |
0797d9d3 |
49 | #ifdef OCCT_DEBUG |
7fd59977 |
50 | sectioncalculee = 1; |
51 | #endif |
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)); |
58 | } |
59 | else{ |
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), |
66 | V1,V2,V12d,V22d); |
67 | if(Function.TwistOnS1()) loctwist1 = Standard_True; |
68 | if(Function.TwistOnS2()) loctwist2 = Standard_True; |
69 | } |
70 | |
71 | if (TestDefl && check) { |
72 | |
73 | // Verification du critere de fleche sur chaque surface |
74 | //et sur la ligne guide |
75 | |
76 | State1 = CheckDeflection(Standard_True,curpoint); |
77 | State2 = CheckDeflection(Standard_False,curpoint); |
78 | } |
79 | else { |
80 | State1 = Blend_OK; |
81 | State2 = Blend_OK; |
82 | if (TestLengthStep) { |
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); |
88 | sup -= inf; |
89 | sup *= 0.05; // Pas max : 5% du domaine |
90 | |
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; |
99 | } |
100 | } |
101 | |
102 | if (State1 == Blend_Backward) { |
103 | State1 = Blend_StepTooLarge; |
104 | rebrou= Standard_True; |
105 | } |
106 | |
107 | if (State2 == Blend_Backward) { |
108 | State2 = Blend_StepTooLarge; |
109 | rebrou = Standard_True; |
110 | } |
111 | |
112 | if (State1 == Blend_StepTooLarge || |
113 | State2 == Blend_StepTooLarge) { |
114 | |
115 | return Blend_StepTooLarge; |
116 | } |
117 | |
118 | |
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; |
123 | |
124 | if (!comptra && !curpointistangent) { |
125 | Function.Tangent(sol(1),sol(2),sol(3),sol(4),Tgp1,Tgp2,Nor1,Nor2); |
126 | Nor1.Normalize(); |
127 | Nor2.Normalize(); |
128 | Standard_Real testra = Tgp1.Dot(Nor1.Crossed(V1)); |
129 | if (Abs(testra) > Precision::Confusion()) { |
130 | tras1 = IntSurf_In; |
131 | if ((testra > 0. && !loctwist1) || (testra < 0. && loctwist1)) { |
132 | tras1 = IntSurf_Out; |
133 | } |
134 | |
135 | testra = Tgp2.Dot(Nor2.Crossed(V2)); |
136 | if (Abs(testra) > Precision::Confusion()) { |
137 | tras2 = IntSurf_Out; |
138 | if ((testra > 0. && !loctwist2) || (testra < 0. && loctwist2)) { |
139 | tras2 = IntSurf_In; |
140 | } |
141 | comptra = Standard_True; |
142 | line->Set(tras1,tras2); |
143 | } |
144 | } |
145 | } |
146 | |
147 | if (State1 == Blend_OK || |
148 | State2 == Blend_OK ) { |
149 | previousP = curpoint; |
150 | return State; |
151 | } |
152 | |
153 | if (State1 == Blend_StepTooSmall && |
154 | State2 == Blend_StepTooSmall) { |
155 | previousP = curpoint; |
156 | if (State == Blend_OK) { |
157 | return Blend_StepTooSmall; |
158 | } |
159 | else { |
160 | return State; |
161 | } |
162 | } |
163 | |
164 | if (State == Blend_OK) { |
165 | return Blend_SamePoints; |
166 | } |
167 | else { |
168 | return State; |
169 | } |
170 | |
171 | } |
172 | else { |
173 | return Blend_StepTooLarge; |
174 | } |
175 | } |
176 | |
177 | |
178 | Blend_Status Blend_Walking::CheckDeflection |
179 | (const Standard_Boolean OnFirst, |
180 | const Blend_Point& CurPoint) |
181 | { |
182 | // regle par tests dans U4 correspond a 11.478 d |
183 | const Standard_Real CosRef3D = 0.98; |
184 | |
185 | const Standard_Real CosRef2D = 0.88; // correspond a 25 d |
186 | |
187 | Standard_Real Norme, Cosi, Cosi2; |
7fd59977 |
188 | Standard_Real prevNorme = 0.; |
7fd59977 |
189 | Standard_Real FlecheCourante; |
190 | Standard_Real Du,Dv,Duv; |
191 | Standard_Real tolu,tolv; |
192 | |
193 | gp_Pnt Psurf; |
194 | gp_Vec Tgsurf; |
195 | gp_Vec2d Tgonsurf; |
196 | Standard_Real curparamu, curparamv; |
197 | Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint(); |
198 | |
199 | gp_Pnt prevP; |
200 | gp_Vec prevTg; |
201 | gp_Vec2d previousd2d; |
202 | Standard_Real prevparamu, prevparamv; |
203 | Standard_Boolean prevpointistangent = previousP.IsTangencyPoint(); |
204 | |
205 | if (OnFirst) { |
206 | Psurf = CurPoint.PointOnS1(); |
207 | if(!curpointistangent){ |
208 | Tgsurf = CurPoint.TangentOnS1(); |
209 | } |
210 | prevP = previousP.PointOnS1(); |
211 | if(!prevpointistangent){ |
212 | prevTg = previousP.TangentOnS1(); |
213 | } |
214 | tolu = TheSurfaceTool::UResolution(surf1,tolesp); |
215 | tolv = TheSurfaceTool::VResolution(surf1,tolesp); |
216 | } |
217 | else { |
218 | Psurf = CurPoint.PointOnS2(); |
219 | if(!curpointistangent){ |
220 | Tgsurf = CurPoint.TangentOnS2(); |
221 | } |
222 | prevP = previousP.PointOnS2(); |
223 | if(!prevpointistangent){ |
224 | prevTg = previousP.TangentOnS2(); |
225 | } |
226 | tolu = TheSurfaceTool::UResolution(surf2,tolesp); |
227 | tolv = TheSurfaceTool::VResolution(surf2,tolesp); |
228 | } |
229 | |
230 | gp_Vec Corde(prevP,Psurf); |
231 | Norme = Corde.SquareMagnitude(); |
232 | // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude(); |
233 | if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude(); |
234 | |
235 | |
236 | if (Norme <= tolesp*tolesp){ |
237 | // il faudra peut etre forcer meme point |
238 | return Blend_SamePoints; |
239 | } |
240 | if(!prevpointistangent){ |
241 | if(prevNorme <= tolesp*tolesp) { |
242 | return Blend_SamePoints; |
243 | } |
244 | Cosi = sens*Corde*prevTg; |
245 | if (Cosi <0.) { // angle 3d>pi/2. --> retour arriere |
246 | return Blend_Backward; |
247 | } |
248 | |
249 | Cosi2 = Cosi * Cosi / prevNorme / Norme; |
250 | if (Cosi2 < CosRef3D) { |
251 | return Blend_StepTooLarge; |
252 | } |
253 | } |
254 | |
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; |
261 | } |
262 | } |
263 | |
264 | if(check2d){ |
265 | if (OnFirst) { |
266 | CurPoint.ParametersOnS1(curparamu,curparamv); |
267 | if(!curpointistangent) Tgonsurf = CurPoint.Tangent2dOnS1(); |
268 | previousP.ParametersOnS1(prevparamu,prevparamv); |
269 | if(!prevpointistangent) previousd2d = previousP.Tangent2dOnS1(); |
270 | } |
271 | else { |
272 | CurPoint.ParametersOnS2(curparamu,curparamv); |
273 | if(!curpointistangent) Tgonsurf = CurPoint.Tangent2dOnS2(); |
274 | previousP.ParametersOnS2(prevparamu,prevparamv); |
275 | if(!prevpointistangent) previousd2d = previousP.Tangent2dOnS2(); |
276 | } |
277 | |
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 |
285 | } |
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 |
290 | } |
291 | Cosi = sens*(Du * previousd2d.X() + Dv * previousd2d.Y()); |
292 | if (Cosi < 0) { |
293 | return Blend_Backward; |
294 | } |
295 | } |
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; |
302 | } |
303 | } |
304 | } |
305 | if(!curpointistangent && !prevpointistangent){ |
306 | // Estimation de la fleche courante |
307 | FlecheCourante = (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.; |
308 | |
309 | if (FlecheCourante <= 0.25*fleche*fleche) { |
310 | return Blend_StepTooSmall; |
311 | } |
312 | if (FlecheCourante > fleche*fleche) { |
313 | // pas trop grand : commentaire interessant |
314 | return Blend_StepTooLarge; |
315 | } |
316 | } |
317 | return Blend_OK; |
318 | } |