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