7fd59977 |
1 | #include <Standard_Failure.hxx> |
2 | #include <Precision.hxx> |
3 | |
4 | //#define DEBUG 0 |
5 | |
6 | IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection() |
7 | |
8 | // tester si fleche respectee en calculant un majorant de fleche |
9 | // soit le point precedent et sa tangente ,le point nouveau calcule et sa |
10 | // tangente ;on peut trouver une cubique passant par ces 2 points et ayant |
11 | // pour derivee les tangentes de l intersection |
12 | // calculer le point au parametre 0.5 sur la cubique=p1 |
13 | // calculer le point milieu des 2 points d intersection=p2 |
14 | // si fleche/2<=||p1p2||<= fleche on considere que l on respecte la fleche |
15 | // sinon ajuster le pas en fonction du rapport ||p1p2||/fleche et du pas |
16 | // precedent |
17 | // tester si dans les 2 plans tangents des surfaces on a pas un angle2d trop |
18 | // grand : si oui diviser le pas |
19 | // tester s il n y a pas changement de rive |
20 | // |
21 | { |
22 | static Standard_Integer STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0; |
23 | static Standard_Integer STATIC_PRECEDENT_INFLEXION = 0; |
24 | |
25 | if(line->NbPoints() ==1 ) { |
26 | STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0; |
27 | } |
28 | |
29 | IntWalk_StatusDeflection Status = IntWalk_OK; |
30 | Standard_Real FlecheCourante ,Ratio; |
31 | |
32 | |
33 | const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point(); |
34 | //================================================================================== |
35 | //========= A r r e t s u r p o i n t ============ |
36 | //================================================================================== |
37 | if (myIntersectionOn2S.IsTangent()) { |
38 | return IntWalk_ArretSurPoint; |
39 | } |
40 | |
41 | const gp_Dir& TgCourante = myIntersectionOn2S.Direction(); |
42 | |
43 | //================================================================================== |
44 | //========= R i s q u e d e p o i n t d i n f l e x i o n ============ |
45 | //================================================================================== |
46 | if (TgCourante.Dot(previousd)<0) { |
47 | //------------------------------------------------------------ |
48 | //-- Risque de point d inflexion : On divise le pas par 2 |
49 | //-- On initialise STATIC_PRECEDENT_INFLEXION pour qu a |
50 | //-- l appel suivant, on retourne Pas_OK si il n y a |
51 | //-- plus de risque de point d inflexion |
52 | //------------------------------------------------------------ |
53 | |
54 | pasuv[0]*=0.5; |
55 | pasuv[1]*=0.5; |
56 | pasuv[2]*=0.5; |
57 | pasuv[3]*=0.5; |
58 | STATIC_PRECEDENT_INFLEXION+=3; |
59 | if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2) |
60 | return IntWalk_ArretSurPointPrecedent; |
61 | else |
62 | return IntWalk_PasTropGrand; |
63 | } |
64 | |
65 | else { |
66 | if(STATIC_PRECEDENT_INFLEXION > 0) { |
67 | STATIC_PRECEDENT_INFLEXION -- ; |
68 | return IntWalk_OK; |
69 | } |
70 | } |
71 | |
72 | //================================================================================== |
73 | //========= D e t e c t i o n d e P o in t s c o n f o n d u s =========== |
74 | //================================================================================== |
75 | |
76 | Standard_Real Dist = previousPoint.Value(). |
77 | SquareDistance(CurrentPoint.Value()); |
78 | |
79 | |
80 | if (Dist < tolconf*tolconf ) { |
81 | pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0])); |
82 | pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1])); |
83 | pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2])); |
84 | pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3])); |
85 | Status = IntWalk_PointConfondu; |
86 | } |
87 | |
88 | //================================================================================== |
89 | Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2; |
90 | Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2; |
91 | |
92 | previousPoint.Parameters(Up1,Vp1,Up2,Vp2); |
93 | CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2); |
94 | |
95 | Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1; |
96 | Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2; |
97 | |
98 | AbsDu1 = Abs(Du1); |
99 | AbsDu2 = Abs(Du2); |
100 | AbsDv1 = Abs(Dv1); |
101 | AbsDv2 = Abs(Dv2); |
102 | //================================================================================= |
103 | //==== P a s d e p r o g r e s s i o n (entre previous et Current) ======= |
104 | //================================================================================= |
105 | if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1 |
106 | && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) { |
107 | pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2; |
108 | return(IntWalk_ArretSurPointPrecedent); |
109 | } |
110 | //================================================================================== |
111 | //OCC431(apo): modified -> |
c6541a0c |
112 | static Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0; |
7fd59977 |
113 | |
114 | static Standard_Real /*tolArea = 100.0,*/ d = 7.0; |
115 | Standard_Real tolArea = 100.0; |
116 | if (ResoU1 < Precision::PConfusion() || |
117 | ResoV1 < Precision::PConfusion() || |
118 | ResoU2 < Precision::PConfusion() || |
119 | ResoV2 < Precision::PConfusion() ) |
120 | tolArea = tolArea*2.0; |
121 | |
122 | Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1; |
123 | Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2; |
124 | Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y(); |
125 | Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y(); |
126 | Duv1 = Du1*Du1 + Dv1*Dv1; |
127 | Duv2 = Du2*Du2 + Dv2*Dv2; |
128 | ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1; |
129 | ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2; |
130 | // |
131 | //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f |
132 | // |
133 | Standard_Real aMinDiv2=Precision::Confusion(); |
134 | aMinDiv2=aMinDiv2*aMinDiv2; |
135 | // |
136 | d1=d; |
137 | if (Duv1>aMinDiv2) { |
138 | d1 = Abs(ResoUV1/Duv1); |
139 | d1 = Min(Sqrt(d1)*tolArea, d); |
140 | } |
141 | //d1 = Abs(ResoUV1/Duv1); |
142 | //d1 = Min(Sqrt(d1)*tolArea,d); |
143 | //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t |
144 | tolCoeff1 = Exp(d1); |
145 | // |
146 | //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f |
147 | d2=d; |
148 | if (Duv2>aMinDiv2) { |
149 | d2 = Abs(ResoUV2/Duv2); |
150 | d2 = Min(Sqrt(d2)*tolArea,d); |
151 | } |
152 | //d2 = Abs(ResoUV2/Duv2); |
153 | //d2 = Min(Sqrt(d2)*tolArea,d); |
154 | //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t |
155 | tolCoeff2 = Exp(d2); |
156 | CosRef1 = CosRef2D/tolCoeff1; |
157 | CosRef2 = CosRef2D/tolCoeff2; |
158 | // |
159 | //================================================================================== |
160 | //== Les points ne sont pas confondus : == |
161 | //== D e t e c t i o n d e A r r e t s u r P o i n t p r e c e d e n t == |
162 | //== P a s T r o p G r a n d (angle dans Esp UV) == |
163 | //== C h a n g e m e n t d e r i v e == |
164 | //================================================================================== |
165 | if (Status != IntWalk_PointConfondu) { |
166 | if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) { |
167 | pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; |
168 | if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) { |
169 | return(IntWalk_ArretSurPointPrecedent); |
170 | } |
171 | else { |
172 | pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; |
173 | return(IntWalk_PasTropGrand); |
174 | } |
175 | } |
176 | const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1(); |
177 | const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2(); |
178 | Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y(); |
179 | Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y(); |
180 | Ang1 = Abs(previousd1.Angle(Tg2dcourante1)); |
181 | Ang2 = Abs(previousd2.Angle(Tg2dcourante2)); |
182 | AngRef1 = AngRef2D*tolCoeff1; |
183 | AngRef2 = AngRef2D*tolCoeff2; |
184 | //------------------------------------------------------- |
185 | //-- Test : Angle trop grand dans l espace UV ----- |
186 | //-- Changement de rive ----- |
187 | //------------------------------------------------------- |
188 | if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) { |
189 | pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; |
190 | if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) |
191 | return(IntWalk_ArretSurPoint); |
192 | else |
193 | return(IntWalk_PasTropGrand); |
194 | } |
195 | } |
196 | //<-OCC431(apo) |
197 | //================================================================================== |
198 | //== D e t e c t i o n d e : Pas Trop Petit |
199 | //== Pas Trop Grand |
200 | //================================================================================== |
201 | |
202 | //--------------------------------------- |
203 | //-- Estimation de la fleche -- |
204 | //--------------------------------------- |
205 | FlecheCourante = |
206 | Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.; |
207 | |
208 | if ( FlecheCourante<= fleche*0.5) { //-- Pas Courant trop petit |
209 | if(FlecheCourante>1e-16) { |
210 | Ratio = 0.5*(fleche/FlecheCourante); |
211 | } |
212 | else { |
213 | Ratio = 10.0; |
214 | } |
215 | Standard_Real pasSu1 = pasuv[0]; |
216 | Standard_Real pasSv1 = pasuv[1]; |
217 | Standard_Real pasSu2 = pasuv[2]; |
218 | Standard_Real pasSv2 = pasuv[3]; |
219 | |
220 | //-- Dans les cas ou lorsqu on demande |
221 | //-- un point a U+DeltaU , .... |
222 | //-- on recupere un point a U + Epsilon |
223 | //-- Epsilon << DeltaU. |
224 | |
225 | if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1; |
226 | if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1; |
227 | if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2; |
228 | if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2; |
229 | |
230 | if(pasuv[0]<ResoU1) pasuv[0]=ResoU1; |
231 | if(pasuv[1]<ResoV1) pasuv[1]=ResoV1; |
232 | if(pasuv[2]<ResoU2) pasuv[2]=ResoU2; |
233 | if(pasuv[3]<ResoV2) pasuv[3]=ResoV2; |
234 | //-- if(Ratio>10.0 ) { Ratio=10.0; } |
235 | Standard_Real R1,R = pasInit[0]/pasuv[0]; |
236 | R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1; |
237 | R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1; |
238 | R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1; |
239 | if(Ratio > R) Ratio=R; |
240 | pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]); |
241 | pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]); |
242 | pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]); |
243 | pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]); |
244 | if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2|| |
245 | pasuv[1] != pasSv1 || pasuv[3] != pasSv2) { |
246 | if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) { |
247 | STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0; |
248 | return IntWalk_PasTropGrand; |
249 | } |
250 | } |
251 | if(Status == IntWalk_OK) { |
252 | STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0; |
253 | //-- On tente d augmenter le pas |
254 | } |
255 | return Status; |
256 | } |
257 | else { //-- FlecheCourante > fleche*0.5 |
258 | if (FlecheCourante > fleche) { //-- Pas Courant Trop Grand |
259 | Ratio = fleche/FlecheCourante; |
260 | pasuv[0] = Ratio*pasuv[0]; |
261 | pasuv[1] = Ratio*pasuv[1]; |
262 | pasuv[2] = Ratio*pasuv[2]; |
263 | pasuv[3] = Ratio*pasuv[3]; |
264 | //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) { |
265 | // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0; |
266 | return IntWalk_PasTropGrand; |
267 | //} |
268 | } |
269 | else { //-- fleche/2 < FlecheCourante <= fleche |
270 | Ratio = 0.75 * (fleche / FlecheCourante); |
271 | } |
272 | } |
273 | pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0])); |
274 | pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1])); |
275 | pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2])); |
276 | pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3])); |
277 | if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0; |
278 | return Status; |
279 | } |
280 | |
281 | |
282 | |