0026937: Eliminate NO_CXX_EXCEPTION macro support
[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
43e9197e 64 IntWalk_StatusDeflection Status = 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
7fd59977 121 for (I = 1;I<=nbLoop;I++) {
b92f3572 122 if (wd2[I].etat > 12)
123 { // start point of closed line
7fd59977 124 LoopPnt = Pnts2.Value(I);
125 previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed,
b92f3572 126 wd2[I].ustart,wd2[I].vstart);
7fd59977 127 previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
128 previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
129
96a85238 130 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
7fd59977 131 CurrentLine->AddPoint(previousPoint);
132 CurrentLine->SetTangentVector(previousd3d,1);
133 Tgtbeg = Standard_False;
134 Tgtend = Standard_False;
96a85238
RL
135 Uvap(1) = wd2[I].ustart;
136 Uvap(2) = wd2[I].vstart;
7fd59977 137
138 StepSign = 1;
139
e9a6ce82 140 // first step of advancement
7fd59977 141
142 Standard_Real d2dx = Abs(previousd2d.X());
143 Standard_Real d2dy = Abs(previousd2d.Y());
144 if (d2dx < tolerance(1)) {
b92f3572 145 PasC = pas * (VM-Vm)/d2dy;
7fd59977 146 }
147 else if (d2dy < tolerance(2)) {
b92f3572 148 PasC = pas * (UM-Um)/d2dx;
7fd59977 149 }
150 else {
b92f3572 151 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
7fd59977 152 }
153
154 PasSav = PasC;
155
156 Arrive = Standard_False;
157 ArretAjout = Standard_False;
158 NbDivision = 0;
159 StatusPrecedent = IntWalk_OK;
b92f3572 160 Standard_Integer aNbIter = 10;
e9a6ce82 161 while (!Arrive) { // as no test of stop is passed
b92f3572 162 Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // border?
7fd59977 163#ifdef CHRONO
b92f3572 164 Chronrsnld.Start();
7fd59977 165#endif
166
b92f3572 167 Rsnld.Perform(Func,Uvap,BornInf,BornSup);
7fd59977 168
169#ifdef CHRONO
b92f3572 170 Chronrsnld.Stop();
7fd59977 171#endif
172
b92f3572 173 if (Cadre) { // update of limits.
174 BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
175 }
176 if (Rsnld.IsDone()) {
177 if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
178 PasC = PasC/2.;
179 PasCu = Abs(PasC*previousd2d.X());
180 PasCv = Abs(PasC*previousd2d.Y());
181
182 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
8d795b51 183 if (CurrentLine->NbPoints()==1)
184 {
185 RemoveTwoEndPoints(I);
186 break; //cancel the line
187 }
188 if (wd2[I].etat >12) { //the line should become open
189 wd2[I].etat = 12; //declare it open
190 ArretAjout = Standard_False;
191 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
192 StepSign = -1;
193 StatusPrecedent = IntWalk_OK;
194 Arrive = Standard_False;
195 PasC = PasSav;
196 Rajout = Standard_True;
197 seqAlone.Append(-lines.Length()-1);
198 seqAjout.Append(-lines.Length()-1);
199 }
200 else { // line s is open
201 Arrive =Standard_True;
202 CurrentLine->AddStatusLast(Standard_False);
203 Rajout = Standard_True;
204 seqAlone.Append(lines.Length()+1);
205 seqAjout.Append(lines.Length()+1);
206 Tgtend = Standard_True;
207 }
208 /*
b92f3572 209 Arrive = Standard_True;
210 CurrentLine->AddStatusFirstLast(Standard_False,
211 Standard_False,Standard_False);
212 Rajout = Standard_True;
8d795b51 213 seqAlone.Append(lines.Length()+1);
7fd59977 214 seqAjout.Append(lines.Length()+1);
b92f3572 215 Tgtend = Standard_True;
8d795b51 216 */
b92f3572 217 }
218 }
219 else { // there is a solution
220 Rsnld.Root(Uvap);
43e9197e 221
222 // Avoid unitialized memory access.
223 if (CurrentLine->NbPoints() > 2)
224 {
225 for(Standard_Integer aCoordIdx = 1; aCoordIdx <= 2; aCoordIdx++)
226 {
227 // Check degenerated cases and fix if possible.
228 if ( ( isLeftDegeneratedBorder[aCoordIdx - 1]
229 && Abs (Uvap(aCoordIdx) - BornInf(aCoordIdx)) < Precision::PConfusion())||
230 (isRightDegeneratedBorder[aCoordIdx - 1]
231 && Abs (Uvap(aCoordIdx) - BornSup(aCoordIdx)) < Precision::PConfusion()) )
232 {
233 Standard_Real uvprev[2], uv[2];
234 if (!reversed)
235 {
236 CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS2(uvprev[0], uvprev[1]);
237 CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS2(uv[0], uv[1]);
238 }
239 else
240 {
241 CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS1(uvprev[0], uvprev[1]);
242 CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS1(uv[0], uv[1]);
243 }
244
245 Standard_Real aScaleCoeff = 0.0;
246
247 // Avoid finite cycle which lead to stop computing iline.
248 if (Status != IntWalk_PasTropGrand)
249 {
250 // Make linear extrapolation.
251 if ( Abs(uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) > gp::Resolution())
252 aScaleCoeff = Abs ((Uvap(aCoordIdx) - uv[aCoordIdx - 1])
253 / (uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) );
254 Standard_Integer aFixIdx = aCoordIdx == 1? 2 : 1; // Fixing index;
255 Uvap(aFixIdx) = uv[aFixIdx - 1] + (uv[aFixIdx - 1] - uvprev[aFixIdx - 1]) * aScaleCoeff;
256 }
257 }
258 }
259 }
260
b92f3572 261 Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
262 if (Arrive) {//reset proper parameter to test the arrow.
263 Psol = CurrentLine->Value(1);
264 if (!reversed) {
265 Psol.ParametersOnS2(Uvap(1),Uvap(2));
266 }
267 else {
268 Psol.ParametersOnS1(Uvap(1),Uvap(2));
269 }
7fd59977 270 Cadre=Standard_False;
b92f3572 271 //in case if there is a frame and arrival at the same time
272 }
273 else { // modif jag 940615
274 if (Rajout) { // test on added points
275 ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
8d795b51 276 SaveN = N;
b92f3572 277 if (ArretAjout) {
278 if (N >0) {
279 Tgtend = lines.Value(N)->IsTangentAtEnd();
280 N = -N;
281 }
282 else {
283 Tgtend = lines.Value(-N)->IsTangentAtBegining();
284 }
285 Arrive = (wd2[I].etat == 12);
286 }
287 }
288
289 if (!ArretAjout&& Cadre) { // test on already marked points
8d795b51 290 if (CurrentLine->NbPoints() == 1)
291 {
292 RemoveTwoEndPoints(I);
293 break; // cancel the line
294 }
b92f3572 295 TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
8d795b51 296 SaveN = N;
b92f3572 297 // if (N==0) {
298 if (N <= 0) { // jag 941017
299 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
300 Tgtend = Func.IsTangent(); // jag 940616
301 N = -N;
302 }
303 Arrive = (wd2[I].etat == 12); // the line is open
304 }
305 }
306 Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
307 NbDivision,PasC,StepSign);
308
309 StatusPrecedent = Status;
310 if (Status == IntWalk_PasTropGrand) {// division of the step
311 Arrive = Standard_False;
312 ArretAjout = Standard_False;
313 Tgtend = Standard_False; // jag 940616
314 if (!reversed) {
315 previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
316 }
317 else {
318 previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
319 }
320 }
321 else if (ArretAjout || Cadre) {
322
323 if (Arrive) { // line s is open
324 CurrentLine->AddStatusLast(Standard_False);
8d795b51 325 //if (Status != IntWalk_ArretSurPointPrecedent)
326 CurrentLine->AddPoint(Psol);
327
328 //Remove <SaveN> from <seqAlone> and, if it is first found point,
329 //from <seqAjout> too
330 if (IsValidEndPoint(I, SaveN))
331 {
332 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
333 if (seqAlone(iseq) == SaveN)
334 {
335 seqAlone.Remove(iseq);
336 break;
337 }
338 if (CurrentLine->NbPoints() <= 3)
339 for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
340 if (seqAjout(iseq) == SaveN)
341 {
342 seqAjout.Remove(iseq);
343 break;
344 }
345 }
346 else
347 {
348 if (seqAlone.Last() == -lines.Length()-1)
349 {
350 seqAlone.Remove(seqAlone.Length());
351 seqAjout.Remove(seqAjout.Length());
352 }
353 RemoveTwoEndPoints(I);
354 Arrive = Standard_False;
355 break; //cancel the line
b92f3572 356 }
8d795b51 357
b92f3572 358 if (Cadre && N==0) {
359 Rajout = Standard_True;
8d795b51 360 //seqAlone.Append(lines.Length()+1);
b92f3572 361 seqAjout.Append(lines.Length()+1);
362 }
363
364 }
365 else { // open
366 wd2[I].etat = 12; // declare it open
367 Tgtbeg = Tgtend;
368 Tgtend = Standard_False;
369 ArretAjout = Standard_False;
370 StepSign = -1;
7fd59977 371 StatusPrecedent = IntWalk_OK;
b92f3572 372 PasC = PasSav;
373 if (Status == IntWalk_ArretSurPointPrecedent) {
8d795b51 374 CurrentLine->AddPoint(Psol);
b92f3572 375 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
376 }
377 else {
378 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
379 }
8d795b51 380 //Remove <SaveN> from <seqAlone> and, if it is first found point,
381 //from <seqAjout> too
382 if (IsValidEndPoint(I, SaveN))
383 {
384 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
385 if (seqAlone(iseq) == SaveN)
386 {
387 seqAlone.Remove(iseq);
388 break;
389 }
390 if (CurrentLine->NbPoints() <= 2)
391 for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
392 if (seqAjout(iseq) == SaveN)
393 {
394 seqAjout.Remove(iseq);
395 break;
396 }
397 }
398 else
399 {
400 RemoveTwoEndPoints(I);
401 break; //cancel the line
402 }
403
b92f3572 404 if (Cadre && N==0) {
405 Rajout = Standard_True;
406 seqAjout.Append(-lines.Length()-1);
407 }
408 }
409 }
410 else if ( Status == IntWalk_ArretSurPointPrecedent) {
411 if (CurrentLine->NbPoints() == 1) { //cancel the line
412 Arrive = Standard_False;
8d795b51 413 RemoveTwoEndPoints(I);
b92f3572 414 break;
415 }
416 if (wd2[I].etat >12) { //the line should become open
417 wd2[I].etat = 12; //declare it open
418 ArretAjout = Standard_False;
419 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
420 StepSign = -1;
7fd59977 421 StatusPrecedent = IntWalk_OK;
b92f3572 422 Arrive = Standard_False;
423 PasC = PasSav;
424 Rajout = Standard_True;
8d795b51 425 seqAlone.Append(-lines.Length()-1);
7fd59977 426 seqAjout.Append(-lines.Length()-1);
b92f3572 427 }
428 else { // line s is open
429 Arrive =Standard_True;
430 CurrentLine->AddStatusLast(Standard_False);
431 Rajout = Standard_True;
8d795b51 432 seqAlone.Append(lines.Length()+1);
7fd59977 433 seqAjout.Append(lines.Length()+1);
b92f3572 434 }
435 }
436 else if (Arrive) {
437 if (wd2[I].etat > 12) { //line closed good case
438 CurrentLine->AddStatusFirstLast(Standard_True,
439 Standard_False,Standard_False);
440 CurrentLine->AddPoint(CurrentLine->Value(1));
441 }
442 else if (N >0) { //point of stop given at input
443 PathPnt = Pnts1.Value(N);
444 CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
7fd59977 445 AddPointInCurrentLine(N,PathPnt,CurrentLine);
b92f3572 446 }
447 }
448 else if (Status == IntWalk_ArretSurPoint) {
449 if (wd2[I].etat >12) { //line should become open
450 wd2[I].etat = 12; //declare it open
451 Tgtbeg = Standard_True;
452 Tgtend = Standard_False;
7fd59977 453 N= -lines.Length()-1;
454 Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
b92f3572 455 OpenLine(N,Psol,Pnts1,Func,CurrentLine);
456 StepSign = -1;
457 Rajout = Standard_True;
8d795b51 458 seqAlone.Append(N);
7fd59977 459 seqAjout.Append(N);
460 StatusPrecedent = IntWalk_OK;
b92f3572 461 Arrive = Standard_False;
462 PasC = PasSav;
463 }
464 else {
465 Arrive = Standard_True;
466 if (Ipass!=0) { //point of passage, point of stop
467 PathPnt = Pnts1.Value(Ipass);
468 CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
7fd59977 469 AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
b92f3572 470 }
471 else {
7fd59977 472 CurrentLine->AddStatusLast(Standard_False);
b92f3572 473 IntSurf_PntOn2S newP;
474 newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
7fd59977 475 CurrentLine->AddPoint(newP);
b92f3572 476 Rajout = Standard_True;
8d795b51 477 seqAlone.Append(lines.Length()+1);
b92f3572 478 seqAjout.Append(lines.Length()+1);
7fd59977 479 }
b92f3572 480 }
481 }
482 else if (Status == IntWalk_OK) {
483 if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
484 previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
485 previousd3d = Func.Direction3d();
486 previousd2d = Func.Direction2d();
487 CurrentLine->AddPoint(previousPoint);
488 }
489 else if (Status == IntWalk_PointConfondu)
490 {
491 aNbIter --;
492 }
493 }
494 }
495 else { //no numerical solution NotDone
496 PasC = PasC/2.;
497 PasCu = Abs(PasC*previousd2d.X());
498 PasCv = Abs(PasC*previousd2d.Y());
499
500 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
8d795b51 501 if (CurrentLine->NbPoints() == 1)
502 {
503 RemoveTwoEndPoints(I);
504 break; // cancel the line
505 }
506 if (wd2[I].etat >12) { //the line should become open
507 wd2[I].etat = 12; //declare it open
508 ArretAjout = Standard_False;
509 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
510 StepSign = -1;
511 StatusPrecedent = IntWalk_OK;
512 Arrive = Standard_False;
513 PasC = PasSav;
514 Rajout = Standard_True;
515 seqAlone.Append(-lines.Length()-1);
516 seqAjout.Append(-lines.Length()-1);
517 }
518 else { // line s is open
519 Arrive =Standard_True;
520 CurrentLine->AddStatusLast(Standard_False);
521 Tgtend = Standard_True;
522 Rajout = Standard_True;
523 seqAlone.Append(lines.Length()+1);
524 seqAjout.Append(lines.Length()+1);
525 }
526 /*
b92f3572 527 Arrive = Standard_True;
528 CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
529 Standard_False);
530 Tgtend = Standard_True;
531 Rajout = Standard_True;
8d795b51 532 seqAlone.Append(lines.Length()+1);
b92f3572 533 seqAjout.Append(lines.Length()+1);
8d795b51 534 */
b92f3572 535 }
536 }
537
538 if(aNbIter < 0)
539 break;
e9a6ce82 540 }// end of started line
7fd59977 541 if (Arrive) {
b92f3572 542 CurrentLine->SetTangencyAtBegining(Tgtbeg);
543 CurrentLine->SetTangencyAtEnd(Tgtend);
544
545 lines.Append(CurrentLine);
546 wd2[I].etat=-wd2[I].etat; //mark point as processed
7fd59977 547 }
e9a6ce82 548 } //end of processing of start point
549 } //end of all start points
7fd59977 550}