0024612: Wrong pcurve of the section curve
[occt.git] / src / IntWalk / IntWalk_IWalking_3.gxx
CommitLineData
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.
7fd59977 14
96a85238
RL
15#include <NCollection_IncAllocator.hxx>
16#include <NCollection_LocalArray.hxx>
17
7fd59977 18
19// modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN
96a85238 20static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
7fd59977 21 const TColStd_SequenceOfReal& Umult,
22 const TColStd_SequenceOfReal& Vmult,
7fd59977 23 const Standard_Real& prevUp,
24 const Standard_Real& prevVp,
96a85238 25 const IntWalk_VectorOfInteger& nbMultiplicities,
7fd59977 26 const math_Vector& tolerance,
27 TheIWFunction& sp,
28 math_Vector& UV,
29 Standard_Integer& Irang);
30// modified by NIZHNY-MKK Thu Nov 2 15:07:39 2000.END
31
32
33void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
34 const TColStd_SequenceOfReal& Vmult,
35 const ThePOPIterator& Pnts1,
36 TheIWFunction& Func,
37 Standard_Boolean& Rajout)
38
e9a6ce82 39// Processing of open line.
7fd59977 40//
e9a6ce82 41// 1) for any starting point, which is not passing and not tangent and not yet processed,
42// calculation of the step of advancement = step depending on the arrow and the maximum step.
7fd59977 43//
e9a6ce82 44// 2) calculate a point of approach (this point is on the tangent to the section
45// of distance = no point in the interior)
7fd59977 46//
e9a6ce82 47// 3) conditions {
48// (all calculated points do not exceed a point in the
49// list of starting points)
50// or
51// (all points do not form an open line going
52// from one border of the domain to the other or from a point tangent
53// to border or from 2 tangent points : single cases)
7fd59977 54//
e9a6ce82 55// 1) framing of approached point on borders if necessary (there is
56// calculation of step)
57// 2) calculation of the point
58// 3) if the point is not found the step is divided
59// 4) stpo tests
60// 5) calculation of the step depending on the arrow and the max step,
7fd59977 61// (TestDeflection)
e9a6ce82 62// stop possible.
63// end of conditions.
7fd59977 64
65{
66 Standard_Integer I, N;
1ef32e96
RL
67 Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
68 math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2);
7fd59977 69 Standard_Real PasC, PasCu, PasCv;
e9a6ce82 70 Standard_Boolean Arrive; // shows if the line ends
71 Standard_Boolean Cadre; // shows if one is on border of the domain
72 Standard_Boolean ArretAjout; //shows if one is on added point
7fd59977 73 IntSurf_PntOn2S Psol;
e9a6ce82 74 Handle(IntWalk_TheIWLine) CurrentLine; // line under construction
7fd59977 75 Standard_Boolean Tgtend;
76
77 IntWalk_StatusDeflection Status, StatusPrecedent;
78
79 Standard_Integer NbDivision;
e9a6ce82 80 // number of divisions of step for each section
7fd59977 81
82 Standard_Integer StepSign;
83
84 ThePointOfPath PathPnt;
85
86 BornInf(1) = Um;
87 BornSup(1) = UM;
88 BornInf(2) = Vm;
89 BornSup(2) = VM;
90
91 math_FunctionSetRoot Rsnld(Func, tolerance);
92 Standard_Integer nbPath = Pnts1.Length();
93
94 // modified by NIZHNY-MKK Fri Oct 27 12:32:34 2000.BEGIN
96a85238
RL
95 NCollection_LocalArray<Standard_Integer> movementdirectioninfoarr (nbPath + 1);
96 Standard_Integer* movementdirectioninfo = movementdirectioninfoarr;
97 for (I = 0; I <= nbPath; I++) {
98 movementdirectioninfo[I] = 0;
7fd59977 99 }
100 // modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END
101
102 for (I = 1; I <= nbPath; I++) {
e9a6ce82 103 //start point of the progression
96a85238 104 // if (wd1[I].etat > 11) {
7fd59977 105 // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN
96a85238 106 if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
7fd59977 107 // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END
108 PathPnt = Pnts1.Value(I);
96a85238 109 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
7fd59977 110 CurrentLine->SetTangencyAtBegining(Standard_False);
111 Tgtend = Standard_False;
112 CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
96a85238
RL
113 UVap(1) = wd1[I].ustart;
114 UVap(2) = wd1[I].vstart;
7fd59977 115 MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
116 previousd3d = Func.Direction3d();
117 previousd2d = Func.Direction2d();
118 CurrentLine->AddPoint(previousPoint);
119 // modified by NIZHNY-MKK Fri Oct 27 12:34:32 2000.BEGIN
96a85238 120 if(movementdirectioninfo[I] !=0) {
b92f3572 121 if(movementdirectioninfo[I] < 0) {
122 StepSign = -1;
123 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
124 } else {
125 StepSign = 1;
126 CurrentLine->SetTangentVector(previousd3d,1);
127 }
7fd59977 128 } else {
b92f3572 129 Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
130 if( tyutuyt < 0) {
131 StepSign = -1;
132 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
133 }
134 else {
135 StepSign = 1;
136 CurrentLine->SetTangentVector(previousd3d,1);
137 }
7fd59977 138 }
139 // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END
140
b92f3572 141 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
96a85238
RL
142 wd1[I].etat = - abs(wd1[I].etat);
143 movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0;
7fd59977 144// Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
e9a6ce82 145 // first step of advancement
7fd59977 146 Standard_Real d2dx = Abs(previousd2d.X());
147 Standard_Real d2dy = Abs(previousd2d.Y());
148 if (d2dx < tolerance(1)) {
b92f3572 149 PasC = pas * (VM-Vm)/d2dy;
7fd59977 150 }
151 else if (d2dy < tolerance(2)) {
b92f3572 152 PasC = pas * (UM-Um)/d2dx;
7fd59977 153 }
154 else {
b92f3572 155 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
7fd59977 156 }
157
158 Arrive = Standard_False;
159 ArretAjout = Standard_False;
160 NbDivision = 0;
161 StatusPrecedent = IntWalk_OK;
162 // modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000
163 Standard_Integer IndexOfPathPointDoNotCheck=0;
b92f3572 164 Standard_Integer aNbIter = 10;
e9a6ce82 165 while (!Arrive) { // as one of stop tests is not checked
b92f3572 166 Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
167 // Border?
7fd59977 168
169#ifdef CHRONO
b92f3572 170 Chronrsnld.Start();
7fd59977 171#endif
172
b92f3572 173 Rsnld.Perform(Func,UVap,BornInf,BornSup);
7fd59977 174
175#ifdef CHRONO
b92f3572 176 Chronrsnld.Stop();
7fd59977 177#endif
178
b92f3572 179 if (Cadre) {
180 BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
181 }
182 if (Rsnld.IsDone()) {
183 if (Abs(Func.Root()) > Func.Tolerance()) {
184 PasC = PasC / 2.0;
185 PasCu = Abs(PasC*previousd2d.X());
186 PasCv = Abs(PasC*previousd2d.Y());
187 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
188 if (CurrentLine->NbPoints() == 1) break;
189 Arrive = Standard_True;
190 CurrentLine->AddStatusLast(Standard_False);
191 Tgtend = Standard_True; // check
7fd59977 192 Rajout = Standard_True;
b92f3572 193 seqAjout.Append(lines.Length() + 1);
194 }
195 }
196 else { // test stop
197 Rsnld.Root(UVap);
198 Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
199 if (Arrive) {
200 Cadre = Standard_False;
201 //in case if there is a frame and arrive at the same time
202 }
203 else {
204 if (Rajout) {
205 ArretAjout =TestArretAjout(Func, UVap, N, Psol);
206 if (ArretAjout) {
207 // jag 940615
208 Tgtend = lines.Value(N)->IsTangentAtEnd();
7fd59977 209 N = -N;
b92f3572 210 }
211 }
212 // modified by NIZHNY-MKK Thu Nov 2 15:09:08 2000.BEGIN
213 if(!(Rajout && ArretAjout)) {
214 Standard_Real prevUp, prevVp;
215 if (!reversed) {
216 previousPoint.ParametersOnS2(prevUp, prevVp);
217 }
218 else {
219 previousPoint.ParametersOnS1(prevUp, prevVp);
220 }
221 Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
222 nbMultiplicities, tolerance, Func, UVap, N);
223 if(Arrive) {
224 Cadre = Standard_False;
225 }
226 }
227 // modified by NIZHNY-MKK Thu Nov 2 15:09:13 2000.END
228 if (!ArretAjout && Cadre) {
229 if (CurrentLine->NbPoints() == 1) break; // cancel the line
230 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
231 // if (N == 0) {
232 if (N <= 0) { // jag 941017
233 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
234 Tgtend = Func.IsTangent();
235 N = -N;
236 }
237 }
238 }
239 Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
240 NbDivision,PasC,StepSign);
241 StatusPrecedent = Status;
242 if (Status == IntWalk_PasTropGrand) {
243 Arrive = Standard_False;
244 ArretAjout = Standard_False;
245 Tgtend = Standard_False; // jag 940615
246 if (!reversed) {
247 previousPoint.ParametersOnS2(UVap(1), UVap(2));
248 }
249 else {
250 previousPoint.ParametersOnS1(UVap(1), UVap(2));
251 }
252 }
253 else if (ArretAjout || Cadre) {
254 Arrive = Standard_True;
255 CurrentLine->AddStatusLast(Standard_False);
256 if (Status != IntWalk_ArretSurPointPrecedent) {
257 CurrentLine->AddPoint(Psol);
258 }
259 if (Cadre && N==0) {
260 Rajout = Standard_True;
261 seqAjout.Append(lines.Length()+1);
262 }
263 }
264 else if (Status == IntWalk_ArretSurPointPrecedent) {
265 if (CurrentLine->NbPoints() == 1) { //cancel the line
266 Arrive = Standard_False;
267 break;
268 }
269 Arrive = Standard_True;
270 Rajout = Standard_True;
7fd59977 271 seqAjout.Append(lines.Length() + 1);
b92f3572 272 CurrentLine->AddStatusLast(Standard_False);
273 Tgtend = Standard_True; // check
274 }
275 else if (Arrive) {
276 if (CurrentLine->NbPoints() == 1 && // cancel the line
277 (N == I || Status == IntWalk_PointConfondu) ) {
278 // if N == I the main uv is probably lost
279 // or the point is a point of accumulation
280 // if point is confused the start data is bad
281 Arrive = Standard_False;
282 break;
283 }
284 // necessairily N > 0 jag 940617
e9a6ce82 285 // point of stop given at input
b92f3572 286 PathPnt = Pnts1.Value(N);
7fd59977 287
b92f3572 288 Standard_Integer etat1N=wd1[N].etat;
289 // modified by NIZHNY-MKK Thu Nov 2 15:09:51 2000.BEGIN
290 // if (etat1N < 11) { // passing point that is a stop
291 if (Abs(etat1N) < 11) { // passing point that is a stop
292 // modified by NIZHNY-MKK Thu Nov 2 15:12:11 2000.END
293 if (Status == IntWalk_ArretSurPoint) {
294 CurrentLine->AddStatusLast(Standard_False);
295 Tgtend = Standard_True; // need check
296 }
297 else {
298 Arrive = Standard_False;
299 }
300 CurrentLine->AddIndexPassing(N);
301 }
302 else { // point of stop given at input
303 if (etat1N == 11) {
304 Tgtend = Standard_True;
305 }
306 CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
307 }
308 AddPointInCurrentLine(N,PathPnt,CurrentLine);
309 if ((etat1N != 1 && etat1N != 11)) {
310 // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN
311 // wd1[N].etat= - wd1[N].etat;
312 wd1[N].etat = - Abs(etat1N);
313 movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
314 if(Arrive && movementdirectioninfo[N]!=0) {
315 IndexOfPathPointDoNotCheck = N;
316 }
317
318 if(Arrive) {
319 Rajout = Standard_True;
320 seqAjout.Append(lines.Length() + 1);
321 }
322 // modified by NIZHNY-MKK Fri Oct 27 12:45:33 2000.END
323 }
324 }
325 else if (Status == IntWalk_ArretSurPoint) {
326 Arrive = Standard_True;
327 CurrentLine->AddStatusLast(Standard_False);
328 Tgtend = Standard_True;
7fd59977 329 MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
b92f3572 330 CurrentLine->AddPoint(Psol);
331 Rajout = Standard_True;
7fd59977 332 seqAjout.Append(lines.Length() + 1);
b92f3572 333 }
334 else if (Status == IntWalk_OK) {
7fd59977 335 MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
b92f3572 336 previousd3d = Func.Direction3d();
337 previousd2d = Func.Direction2d();
338 CurrentLine->AddPoint(previousPoint);
339 }
340 else if (Status == IntWalk_PointConfondu)
341 {
342 aNbIter --;
343 }
344 }
345 }
346 else { // no numerical solution
347 PasC = PasC / 2.;
348 PasCu = Abs(PasC*previousd2d.X());
349 PasCv = Abs(PasC*previousd2d.Y());
350 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
351 if (CurrentLine->NbPoints()==1) break;
352 Arrive = Standard_True;
353 CurrentLine->AddStatusLast(Standard_False);
354 Tgtend = Standard_True; // need check
355 Rajout = Standard_True;
7fd59977 356 seqAjout.Append(lines.Length() + 1);
b92f3572 357 }
358 }
359
360 if(aNbIter < 0)
361 break;
e9a6ce82 362 } // end of started line
7fd59977 363
364 if (Arrive) {
b92f3572 365 CurrentLine->SetTangencyAtEnd(Tgtend);
366 lines.Append(CurrentLine);
367 // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN
368 movementdirectioninfo[I]=0;
369 if(wd1[I].etat > 0)
370 // modified by NIZHNY-MKK Fri Oct 27 12:59:42 2000.END
371 wd1[I].etat=-wd1[I].etat;
372
373 //-- lbr le 5 juin 97 (Pb ds Contap)
374 for(Standard_Integer av=1; av<=nbPath; av++) {
375 // modified by NIZHNY-MKK Fri Oct 27 13:00:22 2000.BEGIN
376 // if (wd1[av].etat > 11) {
377 if ((wd1[av].etat > 11) ||
378 ((av!=I) &&
379 (av!=IndexOfPathPointDoNotCheck) &&
380 (wd1[av].etat < -11) &&
381 (movementdirectioninfo[av]!=0)))
382 {
383 // modified by NIZHNY-MKK Fri Oct 27 13:00:26 2000.END
384 Standard_Real Uav=wd1[av].ustart;
385 Standard_Real Vav=wd1[av].vstart;
386 Standard_Real Uavp,Vavp;
387 const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
388 if (!reversed) {
389 avP.ParametersOnS2(Uavp,Vavp);
390 }
391 else {
392 avP.ParametersOnS1(Uavp,Vavp);
393 }
394 Uav-=Uavp;
395 Vav-=Vavp;
396 Uav*=0.001; Vav*=0.001;
397 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
398 // modified by NIZHNY-MKK Fri Oct 27 13:01:38 2000.BEGIN
399 // wd1[av].etat=-wd1[av].etat;
400 if(wd1[av].etat < 0) {
401 movementdirectioninfo[av] = 0;
402 } else {
403 wd1[av].etat=-wd1[av].etat;
404 movementdirectioninfo[av] = StepSign;
405 }
406 // modified by NIZHNY-MKK Fri Oct 27 13:01:42 2000.END
407 CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
408 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
409 }
7fd59977 410
b92f3572 411 const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
412 if (!reversed) {
413 avPP.ParametersOnS2(Uavp,Vavp);
414 }
415 else {
416 avPP.ParametersOnS1(Uavp,Vavp);
417 }
418 Uav=wd1[av].ustart;
419 Vav=wd1[av].vstart;
420 Uav-=Uavp;
421 Vav-=Vavp;
422 Uav*=0.001; Vav*=0.001;
423 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
424 // modified by NIZHNY-MKK Fri Oct 27 13:02:49 2000.BEGIN
425 // wd1[av].etat=-wd1[av].etat;
426 if(wd1[av].etat < 0) {
427 movementdirectioninfo[av] = 0;
428 } else {
429 wd1[av].etat=-wd1[av].etat;
430 movementdirectioninfo[av] = -StepSign;
431 }
432 // modified by NIZHNY-MKK Fri Oct 27 13:02:52 2000.END
433 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
434 CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
435 }
436 }
437 }
7fd59977 438 }
e9a6ce82 439 } //end of point processing
440 } //end of all points
7fd59977 441}
442
443// modified by NIZHNY-MKK Thu Nov 2 15:07:53 2000.BEGIN
96a85238 444static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
7fd59977 445 const TColStd_SequenceOfReal& Umult,
446 const TColStd_SequenceOfReal& Vmult,
7fd59977 447 const Standard_Real& prevUp,
448 const Standard_Real& prevVp,
96a85238 449 const IntWalk_VectorOfInteger& nbMultiplicities,
7fd59977 450 const math_Vector& tolerance,
451 TheIWFunction& sp,
452 math_Vector& UV,
453 Standard_Integer& Irang) {
454 Standard_Boolean Arrive = Standard_False;
455 Standard_Real Dup, Dvp, Utest,Vtest;
456 Standard_Real tolu = tolerance(1);
457 Standard_Real tolv = tolerance(2);
458 Standard_Integer i, j, k, N;
96a85238
RL
459 for (i = 1; i < (int)wd.size(); i++) {
460 if (wd[i].etat < -11) {
7fd59977 461
e9a6ce82 462 // debug jag see with isg
7fd59977 463
96a85238
RL
464 Utest = wd[i].ustart;
465 Vtest = wd[i].vstart;
7fd59977 466 Dup = prevUp - Utest;
467 Dvp = prevVp - Vtest;
468 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
469 Standard_Real UV1mUtest = UV(1)-Utest;
470 Standard_Real UV2mVtest = UV(2)-Vtest;
471 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
472 ( Abs(UV1mUtest) < tolu
473 && Abs(UV2mVtest) < tolv)) {
474 Irang=i;
475 Arrive = Standard_True;
476 UV(1) = Utest;
477 UV(2) = Vtest;
478 }
96a85238 479 else if (nbMultiplicities[i] > 0) {
7fd59977 480 N=0;
481 for (k = 1; k < i; k++) {
96a85238 482 N+=nbMultiplicities[k];
7fd59977 483 }
96a85238 484 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
7fd59977 485 if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
486 (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
487 (Abs(UV(1)-Umult(j)) < tolu &&
488 Abs(UV(2)-Vmult(j)) < tolv)) {
489 Irang=i;
490 Arrive = Standard_True;
491 UV(1) = Utest;
492 UV(2) = Vtest;
493 break;
494 }
495 }
496 }
497 if (Arrive) {
1ef32e96
RL
498 Standard_Real abidF[1], abidD[1][2];
499 math_Vector bidF(abidF,1,1);
500 math_Matrix bidD(abidD,1,1,1,2);
6e6cd5d9 501 sp.Values(UV,bidF,bidD);
7fd59977 502 break;
503 }
504 }
505 }
506 }
507 return Arrive;
508}
509// modified by NIZHNY-MKK Thu Nov 2 15:07:58 2000.END