1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 #include <Standard_Failure.hxx>
20 #include <Precision.hxx>
24 IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
26 // tester si fleche respectee en calculant un majorant de fleche
27 // soit le point precedent et sa tangente ,le point nouveau calcule et sa
28 // tangente ;on peut trouver une cubique passant par ces 2 points et ayant
29 // pour derivee les tangentes de l intersection
30 // calculer le point au parametre 0.5 sur la cubique=p1
31 // calculer le point milieu des 2 points d intersection=p2
32 // si fleche/2<=||p1p2||<= fleche on considere que l on respecte la fleche
33 // sinon ajuster le pas en fonction du rapport ||p1p2||/fleche et du pas
35 // tester si dans les 2 plans tangents des surfaces on a pas un angle2d trop
36 // grand : si oui diviser le pas
37 // tester s il n y a pas changement de rive
40 static Standard_Integer STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
41 static Standard_Integer STATIC_PRECEDENT_INFLEXION = 0;
43 if(line->NbPoints() ==1 ) {
44 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
47 IntWalk_StatusDeflection Status = IntWalk_OK;
48 Standard_Real FlecheCourante ,Ratio;
51 const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
52 //==================================================================================
53 //========= A r r e t s u r p o i n t ============
54 //==================================================================================
55 if (myIntersectionOn2S.IsTangent()) {
56 return IntWalk_ArretSurPoint;
59 const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
61 //==================================================================================
62 //========= R i s q u e d e p o i n t d i n f l e x i o n ============
63 //==================================================================================
64 if (TgCourante.Dot(previousd)<0) {
65 //------------------------------------------------------------
66 //-- Risque de point d inflexion : On divise le pas par 2
67 //-- On initialise STATIC_PRECEDENT_INFLEXION pour qu a
68 //-- l appel suivant, on retourne Pas_OK si il n y a
69 //-- plus de risque de point d inflexion
70 //------------------------------------------------------------
76 STATIC_PRECEDENT_INFLEXION+=3;
77 if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
78 return IntWalk_ArretSurPointPrecedent;
80 return IntWalk_PasTropGrand;
84 if(STATIC_PRECEDENT_INFLEXION > 0) {
85 STATIC_PRECEDENT_INFLEXION -- ;
90 //==================================================================================
91 //========= 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 ===========
92 //==================================================================================
94 Standard_Real Dist = previousPoint.Value().
95 SquareDistance(CurrentPoint.Value());
98 if (Dist < tolconf*tolconf ) {
99 pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
100 pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
101 pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
102 pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
103 Status = IntWalk_PointConfondu;
106 //==================================================================================
107 Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
108 Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
110 previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
111 CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);
113 Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1;
114 Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2;
120 //=================================================================================
121 //==== P a s d e p r o g r e s s i o n (entre previous et Current) =======
122 //=================================================================================
123 if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1
124 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
125 pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
126 return(IntWalk_ArretSurPointPrecedent);
128 //==================================================================================
129 //OCC431(apo): modified ->
130 static Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0;
132 static Standard_Real /*tolArea = 100.0,*/ d = 7.0;
133 Standard_Real tolArea = 100.0;
134 if (ResoU1 < Precision::PConfusion() ||
135 ResoV1 < Precision::PConfusion() ||
136 ResoU2 < Precision::PConfusion() ||
137 ResoV2 < Precision::PConfusion() )
138 tolArea = tolArea*2.0;
140 Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;
141 Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;
142 Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
143 Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
144 Duv1 = Du1*Du1 + Dv1*Dv1;
145 Duv2 = Du2*Du2 + Dv2*Dv2;
146 ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
147 ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
149 //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
151 Standard_Real aMinDiv2=Precision::Confusion();
152 aMinDiv2=aMinDiv2*aMinDiv2;
156 d1 = Abs(ResoUV1/Duv1);
157 d1 = Min(Sqrt(d1)*tolArea, d);
159 //d1 = Abs(ResoUV1/Duv1);
160 //d1 = Min(Sqrt(d1)*tolArea,d);
161 //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
164 //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
167 d2 = Abs(ResoUV2/Duv2);
168 d2 = Min(Sqrt(d2)*tolArea,d);
170 //d2 = Abs(ResoUV2/Duv2);
171 //d2 = Min(Sqrt(d2)*tolArea,d);
172 //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
174 CosRef1 = CosRef2D/tolCoeff1;
175 CosRef2 = CosRef2D/tolCoeff2;
177 //==================================================================================
178 //== Les points ne sont pas confondus : ==
179 //== 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 ==
180 //== P a s T r o p G r a n d (angle dans Esp UV) ==
181 //== C h a n g e m e n t d e r i v e ==
182 //==================================================================================
183 if (Status != IntWalk_PointConfondu) {
184 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
185 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
186 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) {
187 return(IntWalk_ArretSurPointPrecedent);
190 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
191 return(IntWalk_PasTropGrand);
194 const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
195 const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
196 Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
197 Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
198 Ang1 = Abs(previousd1.Angle(Tg2dcourante1));
199 Ang2 = Abs(previousd2.Angle(Tg2dcourante2));
200 AngRef1 = AngRef2D*tolCoeff1;
201 AngRef2 = AngRef2D*tolCoeff2;
202 //-------------------------------------------------------
203 //-- Test : Angle trop grand dans l espace UV -----
204 //-- Changement de rive -----
205 //-------------------------------------------------------
206 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
207 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
208 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2)
209 return(IntWalk_ArretSurPoint);
211 return(IntWalk_PasTropGrand);
215 //==================================================================================
216 //== D e t e c t i o n d e : Pas Trop Petit
218 //==================================================================================
220 //---------------------------------------
221 //-- Estimation de la fleche --
222 //---------------------------------------
224 Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
226 if ( FlecheCourante<= fleche*0.5) { //-- Pas Courant trop petit
227 if(FlecheCourante>1e-16) {
228 Ratio = 0.5*(fleche/FlecheCourante);
233 Standard_Real pasSu1 = pasuv[0];
234 Standard_Real pasSv1 = pasuv[1];
235 Standard_Real pasSu2 = pasuv[2];
236 Standard_Real pasSv2 = pasuv[3];
238 //-- Dans les cas ou lorsqu on demande
239 //-- un point a U+DeltaU , ....
240 //-- on recupere un point a U + Epsilon
241 //-- Epsilon << DeltaU.
243 if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
244 if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
245 if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
246 if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
248 if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
249 if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
250 if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
251 if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
252 //-- if(Ratio>10.0 ) { Ratio=10.0; }
253 Standard_Real R1,R = pasInit[0]/pasuv[0];
254 R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1;
255 R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1;
256 R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1;
257 if(Ratio > R) Ratio=R;
258 pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
259 pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
260 pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
261 pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
262 if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2||
263 pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
264 if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
265 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
266 return IntWalk_PasTropGrand;
269 if(Status == IntWalk_OK) {
270 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
271 //-- On tente d augmenter le pas
275 else { //-- FlecheCourante > fleche*0.5
276 if (FlecheCourante > fleche) { //-- Pas Courant Trop Grand
277 Ratio = fleche/FlecheCourante;
278 pasuv[0] = Ratio*pasuv[0];
279 pasuv[1] = Ratio*pasuv[1];
280 pasuv[2] = Ratio*pasuv[2];
281 pasuv[3] = Ratio*pasuv[3];
282 //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
283 // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
284 return IntWalk_PasTropGrand;
287 else { //-- fleche/2 < FlecheCourante <= fleche
288 Ratio = 0.75 * (fleche / FlecheCourante);
291 pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
292 pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
293 pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
294 pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
295 if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;