0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / IntWalk / IntWalk_IWalking_4.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 15#include <NCollection_IncAllocator.hxx>
7fd59977 16
17void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
18 const TColStd_SequenceOfReal& Vmult,
19 const ThePOPIterator& Pnts1,
20 const ThePOLIterator& Pnts2,
21 TheIWFunction& Func,
43e9197e 22 Standard_Boolean& Rajout )
e9a6ce82 23// *********** Processing of closed line **********************
7fd59977 24//
e9a6ce82 25// for any interior non-processed point
26// calculate the step of advancement=step depending on the arrow and max step
27// calculate a point of approach (this point is on the tangent to the section
28// of distance = no interior point)
29// conditions
30// (all calculated points do not form a closed loop)
31// or
32// (all points do not form an open line going from
33// one border of the domain to the other or from a point tangent
34// to the border or from 2 tangent points : single cases)
7fd59977 35//
e9a6ce82 36// frame the point of approach on borders if necessary
37// calculate the point
38// if point not found divide the step
39// test of stop
40// calculate step depending on the arrow and the max step (stop possible)
7fd59977 41//
42// ********************************************************************
43{
8d795b51 44 Standard_Integer I,N = 0,SaveN = 0;
1ef32e96
RL
45 Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
46 math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
47 math_Vector Uvap(aUVap,1,2);// parameters of current approach
de09d2a2 48 Standard_Real PasC; // step of advancement on the tangent
49 Standard_Real PasCu; // step of advancement current by U
e9a6ce82 50 Standard_Real PasCv; // step of advancement current by V
51 Standard_Real PasSav; // save first step of advancement
52 Standard_Boolean Arrive;// show if line ends
53 Standard_Boolean Cadre; // show if on border of the domains
54 Standard_Boolean ArretAjout; // show if on the added point
7fd59977 55 IntSurf_PntOn2S Psol;
e9a6ce82 56 Handle(IntWalk_TheIWLine) CurrentLine; //line under construction
7fd59977 57 ThePointOfPath PathPnt;
58 ThePointOfLoop LoopPnt;
59
60 Standard_Boolean Tgtbeg,Tgtend;
61
62 Standard_Integer StepSign;
63
9fd2d2c3 64 IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent;
e9a6ce82 65 Standard_Integer NbDivision ; // number of divisions of step
66 // during calculation of 1 section
7fd59977 67
68 Standard_Integer Ipass ;
e9a6ce82 69 //index in the iterator of points on edge of point of passage
7fd59977 70
71
72 BornInf(1) = Um;
73 BornSup(1) = UM;
74 BornInf(2) = Vm;
75 BornSup(2) = VM;
76
77 math_FunctionSetRoot Rsnld(Func,tolerance);
78 Standard_Integer nbLoop = Pnts2.Length();
b92f3572 79
43e9197e 80 // Check borders for degeneracy:
81 math_Matrix D(1,1,1,2);
82 const Standard_Integer aNbSamplePnt = 10;
83 Standard_Boolean isLeftDegeneratedBorder[2] = {Standard_True, Standard_True};
84 Standard_Boolean isRightDegeneratedBorder[2] = {Standard_True, Standard_True};
85 math_Vector aStep(1,2);
86 aStep = (BornSup - BornInf) / (aNbSamplePnt - 1);
87 for(Standard_Integer aBorderIdx = 1; aBorderIdx <= 2; aBorderIdx++)
88 {
89 Standard_Integer aChangeIdx = aBorderIdx == 2? 1 : 2;
90 math_Vector UV(1,2);
91
92 // Left border.
93 UV(aBorderIdx) = BornInf(aBorderIdx);
94 for(Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
95 {
96 Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
97 UV(aChangeIdx) = aParam;
98 Func.Derivatives(UV, D);
99 if ( Abs(D(1, aChangeIdx) ) > Precision::Confusion())
100 {
101 isLeftDegeneratedBorder[aBorderIdx - 1] = Standard_False;
102 break;
103 }
104 }
105
106 // Right border.
107 UV(aBorderIdx) = BornSup(aBorderIdx);
108 for(Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
109 {
110 Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
111 UV(aChangeIdx) = aParam;
112 Func.Derivatives(UV, D);
113 if ( Abs(D(1, aChangeIdx) ) > Precision::Confusion())
114 {
115 isRightDegeneratedBorder[aBorderIdx - 1] = Standard_False;
116 break;
117 }
118 }
119 }
120
92a55b01 121 TheIWFunction aFuncForDuplicate = Func;
122
7fd59977 123 for (I = 1;I<=nbLoop;I++) {
b92f3572 124 if (wd2[I].etat > 12)
125 { // start point of closed line
7fd59977 126 LoopPnt = Pnts2.Value(I);
92a55b01 127 previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt), reversed,
128 wd2[I].ustart, wd2[I].vstart);
129
130 if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
131 {
132 wd2[I].etat = -wd2[I].etat; //mark point as processed
133 continue;
134 }
135
7fd59977 136 previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
137 previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
138
96a85238 139 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
7fd59977 140 CurrentLine->AddPoint(previousPoint);
141 CurrentLine->SetTangentVector(previousd3d,1);
142 Tgtbeg = Standard_False;
143 Tgtend = Standard_False;
96a85238
RL
144 Uvap(1) = wd2[I].ustart;
145 Uvap(2) = wd2[I].vstart;
7fd59977 146
147 StepSign = 1;
148
e9a6ce82 149 // first step of advancement
7fd59977 150
151 Standard_Real d2dx = Abs(previousd2d.X());
152 Standard_Real d2dy = Abs(previousd2d.Y());
153 if (d2dx < tolerance(1)) {
b92f3572 154 PasC = pas * (VM-Vm)/d2dy;
7fd59977 155 }
156 else if (d2dy < tolerance(2)) {
b92f3572 157 PasC = pas * (UM-Um)/d2dx;
7fd59977 158 }
159 else {
b92f3572 160 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
7fd59977 161 }
162
163 PasSav = PasC;
164
165 Arrive = Standard_False;
166 ArretAjout = Standard_False;
167 NbDivision = 0;
168 StatusPrecedent = IntWalk_OK;
b92f3572 169 Standard_Integer aNbIter = 10;
e9a6ce82 170 while (!Arrive) { // as no test of stop is passed
b92f3572 171 Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // border?
7fd59977 172#ifdef CHRONO
b92f3572 173 Chronrsnld.Start();
7fd59977 174#endif
175
b92f3572 176 Rsnld.Perform(Func,Uvap,BornInf,BornSup);
7fd59977 177
178#ifdef CHRONO
b92f3572 179 Chronrsnld.Stop();
7fd59977 180#endif
181
b92f3572 182 if (Cadre) { // update of limits.
183 BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
184 }
185 if (Rsnld.IsDone()) {
186 if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
187 PasC = PasC/2.;
188 PasCu = Abs(PasC*previousd2d.X());
189 PasCv = Abs(PasC*previousd2d.Y());
190
191 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
8d795b51 192 if (CurrentLine->NbPoints()==1)
193 {
194 RemoveTwoEndPoints(I);
195 break; //cancel the line
196 }
197 if (wd2[I].etat >12) { //the line should become open
198 wd2[I].etat = 12; //declare it open
199 ArretAjout = Standard_False;
200 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
201 StepSign = -1;
202 StatusPrecedent = IntWalk_OK;
203 Arrive = Standard_False;
204 PasC = PasSav;
205 Rajout = Standard_True;
206 seqAlone.Append(-lines.Length()-1);
207 seqAjout.Append(-lines.Length()-1);
208 }
209 else { // line s is open
210 Arrive =Standard_True;
211 CurrentLine->AddStatusLast(Standard_False);
212 Rajout = Standard_True;
213 seqAlone.Append(lines.Length()+1);
214 seqAjout.Append(lines.Length()+1);
215 Tgtend = Standard_True;
216 }
217 /*
b92f3572 218 Arrive = Standard_True;
219 CurrentLine->AddStatusFirstLast(Standard_False,
220 Standard_False,Standard_False);
221 Rajout = Standard_True;
8d795b51 222 seqAlone.Append(lines.Length()+1);
7fd59977 223 seqAjout.Append(lines.Length()+1);
b92f3572 224 Tgtend = Standard_True;
8d795b51 225 */
b92f3572 226 }
227 }
228 else { // there is a solution
229 Rsnld.Root(Uvap);
43e9197e 230
231 // Avoid unitialized memory access.
232 if (CurrentLine->NbPoints() > 2)
233 {
234 for(Standard_Integer aCoordIdx = 1; aCoordIdx <= 2; aCoordIdx++)
235 {
236 // Check degenerated cases and fix if possible.
237 if ( ( isLeftDegeneratedBorder[aCoordIdx - 1]
238 && Abs (Uvap(aCoordIdx) - BornInf(aCoordIdx)) < Precision::PConfusion())||
239 (isRightDegeneratedBorder[aCoordIdx - 1]
240 && Abs (Uvap(aCoordIdx) - BornSup(aCoordIdx)) < Precision::PConfusion()) )
241 {
242 Standard_Real uvprev[2], uv[2];
243 if (!reversed)
244 {
245 CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS2(uvprev[0], uvprev[1]);
246 CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS2(uv[0], uv[1]);
247 }
248 else
249 {
250 CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS1(uvprev[0], uvprev[1]);
251 CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS1(uv[0], uv[1]);
252 }
253
254 Standard_Real aScaleCoeff = 0.0;
255
256 // Avoid finite cycle which lead to stop computing iline.
9fd2d2c3 257 if (aStatus != IntWalk_PasTropGrand)
43e9197e 258 {
259 // Make linear extrapolation.
260 if ( Abs(uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) > gp::Resolution())
261 aScaleCoeff = Abs ((Uvap(aCoordIdx) - uv[aCoordIdx - 1])
262 / (uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) );
263 Standard_Integer aFixIdx = aCoordIdx == 1? 2 : 1; // Fixing index;
264 Uvap(aFixIdx) = uv[aFixIdx - 1] + (uv[aFixIdx - 1] - uvprev[aFixIdx - 1]) * aScaleCoeff;
265 }
266 }
267 }
268 }
269
b92f3572 270 Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
271 if (Arrive) {//reset proper parameter to test the arrow.
272 Psol = CurrentLine->Value(1);
273 if (!reversed) {
274 Psol.ParametersOnS2(Uvap(1),Uvap(2));
275 }
276 else {
277 Psol.ParametersOnS1(Uvap(1),Uvap(2));
278 }
7fd59977 279 Cadre=Standard_False;
b92f3572 280 //in case if there is a frame and arrival at the same time
281 }
282 else { // modif jag 940615
283 if (Rajout) { // test on added points
284 ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
8d795b51 285 SaveN = N;
b92f3572 286 if (ArretAjout) {
287 if (N >0) {
288 Tgtend = lines.Value(N)->IsTangentAtEnd();
289 N = -N;
290 }
291 else {
292 Tgtend = lines.Value(-N)->IsTangentAtBegining();
293 }
294 Arrive = (wd2[I].etat == 12);
295 }
296 }
297
298 if (!ArretAjout&& Cadre) { // test on already marked points
8d795b51 299 if (CurrentLine->NbPoints() == 1)
300 {
301 RemoveTwoEndPoints(I);
302 break; // cancel the line
303 }
b92f3572 304 TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
8d795b51 305 SaveN = N;
b92f3572 306 // if (N==0) {
307 if (N <= 0) { // jag 941017
308 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
309 Tgtend = Func.IsTangent(); // jag 940616
310 N = -N;
311 }
312 Arrive = (wd2[I].etat == 12); // the line is open
313 }
314 }
9fd2d2c3 315 aStatus = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
b92f3572 316 NbDivision,PasC,StepSign);
317
9fd2d2c3 318 StatusPrecedent = aStatus;
319 if (aStatus == IntWalk_PasTropGrand) {// division of the step
b92f3572 320 Arrive = Standard_False;
321 ArretAjout = Standard_False;
322 Tgtend = Standard_False; // jag 940616
323 if (!reversed) {
324 previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
325 }
326 else {
327 previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
328 }
329 }
330 else if (ArretAjout || Cadre) {
331
332 if (Arrive) { // line s is open
333 CurrentLine->AddStatusLast(Standard_False);
9fd2d2c3 334 //if (aStatus != IntWalk_ArretSurPointPrecedent)
8d795b51 335 CurrentLine->AddPoint(Psol);
336
337 //Remove <SaveN> from <seqAlone> and, if it is first found point,
338 //from <seqAjout> too
339 if (IsValidEndPoint(I, SaveN))
340 {
341 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
342 if (seqAlone(iseq) == SaveN)
343 {
344 seqAlone.Remove(iseq);
345 break;
346 }
347 if (CurrentLine->NbPoints() <= 3)
348 for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
349 if (seqAjout(iseq) == SaveN)
350 {
351 seqAjout.Remove(iseq);
352 break;
353 }
354 }
355 else
356 {
357 if (seqAlone.Last() == -lines.Length()-1)
358 {
359 seqAlone.Remove(seqAlone.Length());
360 seqAjout.Remove(seqAjout.Length());
361 }
362 RemoveTwoEndPoints(I);
363 Arrive = Standard_False;
364 break; //cancel the line
b92f3572 365 }
8d795b51 366
b92f3572 367 if (Cadre && N==0) {
368 Rajout = Standard_True;
8d795b51 369 //seqAlone.Append(lines.Length()+1);
b92f3572 370 seqAjout.Append(lines.Length()+1);
371 }
372
373 }
374 else { // open
375 wd2[I].etat = 12; // declare it open
376 Tgtbeg = Tgtend;
377 Tgtend = Standard_False;
378 ArretAjout = Standard_False;
379 StepSign = -1;
7fd59977 380 StatusPrecedent = IntWalk_OK;
b92f3572 381 PasC = PasSav;
9fd2d2c3 382 if (aStatus == IntWalk_ArretSurPointPrecedent) {
8d795b51 383 CurrentLine->AddPoint(Psol);
b92f3572 384 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
385 }
386 else {
387 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
388 }
8d795b51 389 //Remove <SaveN> from <seqAlone> and, if it is first found point,
390 //from <seqAjout> too
391 if (IsValidEndPoint(I, SaveN))
392 {
393 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
394 if (seqAlone(iseq) == SaveN)
395 {
396 seqAlone.Remove(iseq);
397 break;
398 }
399 if (CurrentLine->NbPoints() <= 2)
400 for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
401 if (seqAjout(iseq) == SaveN)
402 {
403 seqAjout.Remove(iseq);
404 break;
405 }
406 }
407 else
408 {
409 RemoveTwoEndPoints(I);
410 break; //cancel the line
411 }
412
b92f3572 413 if (Cadre && N==0) {
414 Rajout = Standard_True;
415 seqAjout.Append(-lines.Length()-1);
416 }
417 }
418 }
9fd2d2c3 419 else if (aStatus == IntWalk_ArretSurPointPrecedent) {
b92f3572 420 if (CurrentLine->NbPoints() == 1) { //cancel the line
421 Arrive = Standard_False;
8d795b51 422 RemoveTwoEndPoints(I);
b92f3572 423 break;
424 }
425 if (wd2[I].etat >12) { //the line should become open
426 wd2[I].etat = 12; //declare it open
427 ArretAjout = Standard_False;
428 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
429 StepSign = -1;
7fd59977 430 StatusPrecedent = IntWalk_OK;
b92f3572 431 Arrive = Standard_False;
432 PasC = PasSav;
433 Rajout = Standard_True;
8d795b51 434 seqAlone.Append(-lines.Length()-1);
7fd59977 435 seqAjout.Append(-lines.Length()-1);
b92f3572 436 }
437 else { // line s is open
438 Arrive =Standard_True;
439 CurrentLine->AddStatusLast(Standard_False);
440 Rajout = Standard_True;
8d795b51 441 seqAlone.Append(lines.Length()+1);
7fd59977 442 seqAjout.Append(lines.Length()+1);
b92f3572 443 }
444 }
445 else if (Arrive) {
446 if (wd2[I].etat > 12) { //line closed good case
447 CurrentLine->AddStatusFirstLast(Standard_True,
448 Standard_False,Standard_False);
98974dcc 449 CurrentLine->AddPoint(CurrentLine->Value(1));
b92f3572 450 }
98974dcc 451 else if ((N >0) && (Pnts1.Length() >= N))
452 {
453 //point of stop given at input
b92f3572 454 PathPnt = Pnts1.Value(N);
455 CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
7fd59977 456 AddPointInCurrentLine(N,PathPnt,CurrentLine);
b92f3572 457 }
458 }
9fd2d2c3 459 else if (aStatus == IntWalk_ArretSurPoint) {
b92f3572 460 if (wd2[I].etat >12) { //line should become open
461 wd2[I].etat = 12; //declare it open
462 Tgtbeg = Standard_True;
463 Tgtend = Standard_False;
7fd59977 464 N= -lines.Length()-1;
465 Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
b92f3572 466 OpenLine(N,Psol,Pnts1,Func,CurrentLine);
467 StepSign = -1;
468 Rajout = Standard_True;
8d795b51 469 seqAlone.Append(N);
7fd59977 470 seqAjout.Append(N);
471 StatusPrecedent = IntWalk_OK;
b92f3572 472 Arrive = Standard_False;
473 PasC = PasSav;
474 }
475 else {
476 Arrive = Standard_True;
477 if (Ipass!=0) { //point of passage, point of stop
478 PathPnt = Pnts1.Value(Ipass);
479 CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
7fd59977 480 AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
b92f3572 481 }
482 else {
7fd59977 483 CurrentLine->AddStatusLast(Standard_False);
b92f3572 484 IntSurf_PntOn2S newP;
485 newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
7fd59977 486 CurrentLine->AddPoint(newP);
b92f3572 487 Rajout = Standard_True;
8d795b51 488 seqAlone.Append(lines.Length()+1);
b92f3572 489 seqAjout.Append(lines.Length()+1);
7fd59977 490 }
b92f3572 491 }
492 }
9fd2d2c3 493 else if (aStatus == IntWalk_OK) {
b92f3572 494 if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
495 previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
496 previousd3d = Func.Direction3d();
497 previousd2d = Func.Direction2d();
498 CurrentLine->AddPoint(previousPoint);
499 }
9fd2d2c3 500 else if (aStatus == IntWalk_PointConfondu)
b92f3572 501 {
502 aNbIter --;
503 }
504 }
505 }
506 else { //no numerical solution NotDone
507 PasC = PasC/2.;
508 PasCu = Abs(PasC*previousd2d.X());
509 PasCv = Abs(PasC*previousd2d.Y());
510
511 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
8d795b51 512 if (CurrentLine->NbPoints() == 1)
513 {
514 RemoveTwoEndPoints(I);
515 break; // cancel the line
516 }
517 if (wd2[I].etat >12) { //the line should become open
518 wd2[I].etat = 12; //declare it open
519 ArretAjout = Standard_False;
520 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
521 StepSign = -1;
522 StatusPrecedent = IntWalk_OK;
523 Arrive = Standard_False;
524 PasC = PasSav;
525 Rajout = Standard_True;
526 seqAlone.Append(-lines.Length()-1);
527 seqAjout.Append(-lines.Length()-1);
528 }
529 else { // line s is open
530 Arrive =Standard_True;
531 CurrentLine->AddStatusLast(Standard_False);
532 Tgtend = Standard_True;
533 Rajout = Standard_True;
534 seqAlone.Append(lines.Length()+1);
535 seqAjout.Append(lines.Length()+1);
536 }
537 /*
b92f3572 538 Arrive = Standard_True;
539 CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
540 Standard_False);
541 Tgtend = Standard_True;
542 Rajout = Standard_True;
8d795b51 543 seqAlone.Append(lines.Length()+1);
b92f3572 544 seqAjout.Append(lines.Length()+1);
8d795b51 545 */
b92f3572 546 }
547 }
548
549 if(aNbIter < 0)
550 break;
e9a6ce82 551 }// end of started line
7fd59977 552 if (Arrive) {
b92f3572 553 CurrentLine->SetTangencyAtBegining(Tgtbeg);
554 CurrentLine->SetTangencyAtEnd(Tgtend);
555
556 lines.Append(CurrentLine);
557 wd2[I].etat=-wd2[I].etat; //mark point as processed
7fd59977 558 }
e9a6ce82 559 } //end of processing of start point
560 } //end of all start points
7fd59977 561}