Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
3 | // | |
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. | |
8 | // | |
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. | |
11 | // | |
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. | |
18 | ||
1ef32e96 | 19 | namespace { |
b1c5c4e6 | 20 | static const Standard_Real CosRef3D = 0.98;// rule by tests in U4 |
21 | // correspond to 11.478 d | |
22 | static const Standard_Real CosRef2D = 0.88; // correspond to 25 d | |
23 | static const Standard_Integer MaxDivision = 60; // max number of step division | |
24 | // because the angle is too great in 2d (U4) | |
1ef32e96 RL |
25 | } |
26 | ||
7fd59977 | 27 | IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection |
28 | (TheIWFunction& sp, | |
29 | const Standard_Boolean Finished, | |
30 | const math_Vector& UV, | |
31 | const IntWalk_StatusDeflection StatusPrecedent, | |
32 | Standard_Integer& NbDivision, | |
33 | Standard_Real& Step, | |
34 | const Standard_Integer StepSign) | |
35 | { | |
b1c5c4e6 | 36 | // Check the step of advancement, AND recalculate this step : |
7fd59977 | 37 | // |
b1c5c4e6 | 38 | // 1) test point confused |
39 | // if yes other tests are not done | |
40 | // 2) test angle 3d too great | |
41 | // if yes divide the step and leave | |
42 | // angle3d = angle ((previous point, calculated point), | |
43 | // previous tangent) | |
44 | // 3) check step of advancement in 2d | |
45 | // 4) test point confused | |
46 | // 5) test angle 2d too great | |
47 | // 6) test point of tangency | |
48 | // if yes leave | |
49 | // 7) calculate the tangent by u,v of the section | |
50 | // 8) test angle 3d too great | |
51 | // angle3d = angle ((previous point, calculated point), | |
52 | // new tangent) | |
53 | // 9) test angle 2d too great | |
54 | //10) test change of side (pass the tangent point not knowing it) | |
55 | //11) calculate the step of advancement depending on the vector | |
56 | //12) adjust the step depending on the previous steps | |
7fd59977 | 57 | |
58 | IntWalk_StatusDeflection Status = IntWalk_OK; | |
59 | ||
7fd59977 | 60 | //--------------------------------------------------------------------------------- |
b1c5c4e6 | 61 | //-- lbr le 4 Avril 95 : it is possible that the status returns points confused |
62 | //-- if epsilon is great enough (1e-11). In this case one loops | |
63 | //-- without ever changing the values sent to Rsnld. | |
7fd59977 | 64 | //--------------------------------------------------------------------------------- |
65 | Standard_Real Paramu, Paramv, StepU,StepV; | |
66 | Standard_Real Cosi, Cosi2, Norme; | |
67 | ||
68 | gp_Vec Corde(previousPoint.Value(), sp.Point()); | |
69 | ||
70 | Norme = Corde.SquareMagnitude(); | |
71 | // if (Norme <= epsilon*epsilon) { | |
b1c5c4e6 | 72 | if ((++NbPointsConfondusConsecutifs < 10) && (Norme <= epsilon)) { // the square is already taken in the constructor |
7fd59977 | 73 | Status = IntWalk_PointConfondu; |
74 | if (StatusPrecedent == IntWalk_PasTropGrand) { | |
75 | return IntWalk_ArretSurPointPrecedent; | |
76 | } | |
77 | ||
b1c5c4e6 | 78 | if(++EpsilonSembleTropGrand > 5 && NbPointsConfondusConsecutifs == 8) { //-- Temporary |
79 | if(epsilon>0.00000000001) epsilon*=0.5; //-- Temporary | |
80 | EpsilonSembleTropGrand = 0; //-- Temporary | |
7fd59977 | 81 | } |
82 | } | |
83 | else { | |
b1c5c4e6 | 84 | NbPointsConfondusConsecutifs = 0; //-- Temporary |
85 | EpsilonSembleTropGrand = 0; //-- Temporary | |
86 | if(Norme<1e-16) Norme = 1e-16; //-- Temporary | |
7fd59977 | 87 | |
88 | Cosi = Corde * previousd3d; | |
89 | if (Cosi*StepSign < 0.) { // angle 3d > pi/2 !!!! | |
90 | Cosi2 = 0.; | |
91 | } | |
92 | else { | |
93 | Cosi2 = Cosi * Cosi / previousd3d.SquareMagnitude() / Norme; | |
94 | } | |
b1c5c4e6 | 95 | if (Cosi2 < CosRef3D) { //angle 3d too great |
7fd59977 | 96 | Step = Step /2.0; |
97 | StepU = Abs(Step*previousd2d.X()); | |
98 | StepV = Abs(Step*previousd2d.Y()); | |
99 | if (StepU < tolerance(1) && StepV < tolerance(2)) | |
100 | Status = IntWalk_ArretSurPointPrecedent; | |
101 | else | |
102 | Status = IntWalk_PasTropGrand; | |
103 | return Status; | |
104 | } | |
105 | } | |
106 | ||
107 | if (!reversed) { | |
108 | previousPoint.ParametersOnS2(Paramu, Paramv); | |
109 | } | |
110 | else { | |
111 | previousPoint.ParametersOnS1(Paramu, Paramv); | |
112 | } | |
113 | Standard_Real Du = UV(1) - Paramu; | |
114 | Standard_Real Dv = UV(2) - Paramv; | |
115 | Standard_Real Duv = Du * Du + Dv * Dv; | |
116 | if (Abs(Du) < tolerance(1) && Abs(Dv) < tolerance(2)) | |
b1c5c4e6 | 117 | return IntWalk_ArretSurPointPrecedent; //confused point 2d |
7fd59977 | 118 | Cosi = StepSign * (Du * previousd2d.X() + |
119 | Dv * previousd2d.Y()); | |
120 | if (Cosi < 0 && Status == IntWalk_PointConfondu) | |
b1c5c4e6 | 121 | return IntWalk_ArretSurPointPrecedent; // leave as step back |
122 | // with confused point | |
7fd59977 | 123 | |
124 | ||
125 | if (sp.IsTangent()) | |
126 | return IntWalk_ArretSurPoint; | |
127 | ||
b1c5c4e6 | 128 | //if during routing one has subdivided more than MaxDivision for each |
129 | //previous step, bug on the square; do nothing (experience U4) | |
7fd59977 | 130 | |
131 | if (NbDivision < MaxDivision && | |
132 | Status != IntWalk_PointConfondu && | |
133 | StatusPrecedent!= IntWalk_PointConfondu ) { | |
134 | Cosi2 = Cosi * Cosi / Duv; | |
135 | if (Cosi2 < CosRef2D || Cosi < 0 ) { | |
136 | Step = Step / 2.0; | |
137 | StepU = Abs(Step*previousd2d.X()); | |
138 | StepV = Abs(Step*previousd2d.Y()); | |
139 | ||
140 | if (StepU < tolerance(1) && StepV < tolerance(2)) | |
141 | Status = IntWalk_ArretSurPointPrecedent; | |
142 | else | |
143 | Status = IntWalk_PasTropGrand; | |
144 | NbDivision = NbDivision + 1; | |
145 | return Status; | |
146 | } | |
147 | ||
148 | Cosi = Corde * sp.Direction3d(); | |
149 | Cosi2 = Cosi * Cosi / sp.Direction3d().SquareMagnitude() / Norme; | |
b1c5c4e6 | 150 | if (Cosi2 < CosRef3D ){ //angle 3d too great |
7fd59977 | 151 | Step = Step / 2.; |
152 | StepU = Abs(Step*previousd2d.X()); | |
153 | StepV = Abs(Step*previousd2d.Y()); | |
154 | if (StepU < tolerance(1) && StepV < tolerance(2)) | |
155 | Status = IntWalk_ArretSurPoint; | |
156 | else | |
157 | Status = IntWalk_PasTropGrand; | |
158 | return Status; | |
159 | } | |
160 | Cosi = Du * sp.Direction2d().X() + | |
161 | Dv * sp.Direction2d().Y(); | |
162 | Cosi2 = Cosi * Cosi / Duv; | |
163 | if (Cosi2 < CosRef2D || | |
164 | sp.Direction2d() * previousd2d < 0) { | |
b1c5c4e6 | 165 | //angle 2d too great or change the side |
7fd59977 | 166 | Step = Step / 2.; |
167 | StepU = Abs(Step*previousd2d.X()); | |
168 | StepV = Abs(Step*previousd2d.Y()); | |
169 | if (StepU < tolerance(1) && StepV < tolerance(2)) | |
170 | Status = IntWalk_ArretSurPointPrecedent; | |
171 | else | |
172 | Status = IntWalk_PasTropGrand; | |
173 | return Status; | |
174 | } | |
175 | } | |
176 | ||
177 | if (!Finished) { | |
178 | ||
179 | if (Status == IntWalk_PointConfondu) { | |
180 | StepU = Min(Abs(1.5 * Du),pas*(UM-Um)); | |
181 | StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm)); | |
182 | ||
183 | Standard_Real d2dx = Abs(previousd2d.X()); | |
184 | Standard_Real d2dy = Abs(previousd2d.Y()); | |
185 | ||
186 | if (d2dx < tolerance(1)) { | |
187 | Step = StepV/d2dy; | |
188 | } | |
189 | else if (d2dy < tolerance(2)) { | |
190 | Step = StepU/d2dx; | |
191 | } | |
192 | else { | |
193 | Step = Min(StepU/d2dx,StepV/d2dy); | |
194 | } | |
195 | ||
196 | ||
197 | ||
198 | } | |
199 | else { | |
b1c5c4e6 | 200 | // estimate the current vector. |
201 | // if vector/2<=current vector<= vector it is considered that the criterion | |
202 | // is observed. | |
203 | // otherwise adjust the step depending on the previous step | |
7fd59977 | 204 | |
205 | /* | |
206 | Standard_Real Dist = Sqrt(Norme)/3.; | |
207 | TColgp_Array1OfPnt Poles(1,4); | |
208 | gp_Pnt POnCurv,Milieu; | |
209 | Poles(1) = previousPoint.Value(); | |
210 | Poles(4) = sp.Point(); | |
211 | Poles(2) = Poles(1).XYZ() + | |
212 | StepSign * Dist* previousd3d.Normalized().XYZ(); | |
213 | Poles(3) = Poles(4).XYZ() - | |
214 | StepSign * Dist*sp.Direction3d().Normalized().XYZ(); | |
215 | BzCLib::PntPole(0.5,Poles,POnCurv); | |
216 | Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5; | |
217 | // FlecheCourante = Milieu.Distance(POnCurv); | |
218 | Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv); | |
219 | */ | |
220 | ||
b1c5c4e6 | 221 | // Direct calculation : |
7fd59977 | 222 | // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2. |
b1c5c4e6 | 223 | // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8. |
7fd59977 | 224 | // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4 |
b1c5c4e6 | 225 | // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8. |
226 | // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate | |
227 | // the norm (square) of 3.*lambda (d1 - d4)/8. | |
228 | // either the norm of : | |
7fd59977 | 229 | // 3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8. |
b1c5c4e6 | 230 | // which produces, takin the square : |
7fd59977 | 231 | // Norme * (d1-d4).SquareMagnitude()/64. |
232 | ||
233 | Standard_Real FlecheCourante = | |
234 | (previousd3d.Normalized().XYZ()-sp.Direction3d().Normalized().XYZ()).SquareModulus()*Norme/64.; | |
235 | ||
236 | ||
237 | // if (FlecheCourante <= 0.5*fleche) { | |
238 | if (FlecheCourante <= 0.25*fleche*fleche) { | |
239 | ||
240 | Standard_Real d2dx = Abs(sp.Direction2d().X()); | |
241 | Standard_Real d2dy = Abs(sp.Direction2d().Y()); | |
242 | ||
243 | StepU = Min(Abs(1.5*Du),pas*(UM-Um)); | |
244 | StepV = Min(Abs(1.5*Dv),pas*(VM-Vm)); | |
245 | ||
246 | if (d2dx < tolerance(1)) { | |
247 | Step = StepV/d2dy; | |
248 | } | |
249 | else if (d2dy < tolerance(2)) { | |
250 | Step = StepU/d2dx; | |
251 | } | |
252 | else { | |
253 | Step = Min(StepU/d2dx,StepV/d2dy); | |
254 | } | |
255 | ||
256 | } | |
257 | else { | |
de09d2a2 | 258 | // if (FlecheCourante > fleche) { // step too great |
259 | if (FlecheCourante > fleche*fleche) { // step too great | |
7fd59977 | 260 | Step = Step /2.; |
de09d2a2 | 261 | StepU = Abs(Step*previousd2d.X()); |
262 | StepV = Abs(Step*previousd2d.Y()); | |
263 | if (StepU < tolerance(1) && StepV < tolerance(2)) | |
264 | Status = IntWalk_ArretSurPointPrecedent; | |
265 | else | |
266 | Status = IntWalk_PasTropGrand; | |
7fd59977 | 267 | } |
268 | else { | |
269 | Standard_Real d2dx = Abs(sp.Direction2d().X()); | |
270 | Standard_Real d2dy = Abs(sp.Direction2d().Y()); | |
271 | ||
272 | StepU = Min(Abs(1.5*Du),pas*(UM-Um)); | |
273 | StepV = Min(Abs(1.5*Dv),pas*(VM-Vm)); | |
274 | ||
275 | if (d2dx < tolerance(1)) { | |
276 | Step = Min(Step,StepV/d2dy); | |
277 | } | |
278 | else if (d2dy < tolerance(2)) { | |
279 | Step = Min(Step,StepU/d2dx); | |
280 | } | |
281 | else { | |
282 | Step = Min(Step,Min(StepU/d2dx,StepV/d2dy)); | |
283 | } | |
284 | } | |
285 | } | |
286 | } | |
287 | } | |
288 | return Status; | |
289 | } | |
290 | ||
291 | ||
292 | ||
293 |