1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <NCollection_IncAllocator.hxx>
16 #include <NCollection_LocalArray.hxx>
19 // modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN
20 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
21 const TColStd_SequenceOfReal& Umult,
22 const TColStd_SequenceOfReal& Vmult,
23 const Standard_Real& prevUp,
24 const Standard_Real& prevVp,
25 const IntWalk_VectorOfInteger& nbMultiplicities,
26 const math_Vector& tolerance,
29 Standard_Integer& Irang);
30 // modified by NIZHNY-MKK Thu Nov 2 15:07:39 2000.END
33 void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
34 const TColStd_SequenceOfReal& Vmult,
35 const ThePOPIterator& Pnts1,
37 Standard_Boolean& Rajout)
39 // Processing of open line.
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.
44 // 2) calculate a point of approach (this point is on the tangent to the section
45 // of distance = no point in the interior)
48 // (all calculated points do not exceed a point in the
49 // list of starting points)
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)
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
60 // 5) calculation of the step depending on the arrow and the max step,
66 Standard_Integer I, N = 0, SaveN = 0;
67 Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
68 math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2);
69 Standard_Real PasC, PasCu, PasCv;
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
74 Handle(IntWalk_TheIWLine) CurrentLine; // line under construction
75 Standard_Boolean Tgtend;
77 IntWalk_StatusDeflection Status, StatusPrecedent;
79 Standard_Integer NbDivision;
80 // number of divisions of step for each section
82 Standard_Integer StepSign;
84 ThePointOfPath PathPnt;
91 math_FunctionSetRoot Rsnld(Func, tolerance);
92 Standard_Integer nbPath = Pnts1.Length();
94 // modified by NIZHNY-MKK Fri Oct 27 12:32:34 2000.BEGIN
95 NCollection_LocalArray<Standard_Integer> movementdirectioninfoarr (nbPath + 1);
96 Standard_Integer* movementdirectioninfo = movementdirectioninfoarr;
97 for (I = 0; I <= nbPath; I++) {
98 movementdirectioninfo[I] = 0;
100 // modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END
102 for (I = 1; I <= nbPath; I++) {
103 //start point of the progression
104 // if (wd1[I].etat > 11) {
105 // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN
106 if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
107 // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END
108 PathPnt = Pnts1.Value(I);
109 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
110 CurrentLine->SetTangencyAtBegining(Standard_False);
111 Tgtend = Standard_False;
112 CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
113 UVap(1) = wd1[I].ustart;
114 UVap(2) = wd1[I].vstart;
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
120 if(movementdirectioninfo[I] !=0) {
121 if(movementdirectioninfo[I] < 0) {
123 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
126 CurrentLine->SetTangentVector(previousd3d,1);
129 Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
132 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
136 CurrentLine->SetTangentVector(previousd3d,1);
139 // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END
141 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
142 wd1[I].etat = - abs(wd1[I].etat);
143 movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0;
144 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
145 // first step of advancement
146 Standard_Real d2dx = Abs(previousd2d.X());
147 Standard_Real d2dy = Abs(previousd2d.Y());
148 if (d2dx < tolerance(1)) {
149 PasC = pas * (VM-Vm)/d2dy;
151 else if (d2dy < tolerance(2)) {
152 PasC = pas * (UM-Um)/d2dx;
155 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
158 Arrive = Standard_False;
159 ArretAjout = Standard_False;
161 StatusPrecedent = IntWalk_OK;
162 // modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000
163 Standard_Integer IndexOfPathPointDoNotCheck=0;
164 Standard_Integer aNbIter = 10;
165 while (!Arrive) { // as one of stop tests is not checked
166 Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
173 Rsnld.Perform(Func,UVap,BornInf,BornSup);
180 BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
182 if (Rsnld.IsDone()) {
183 if (Abs(Func.Root()) > Func.Tolerance()) {
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
192 Rajout = Standard_True;
193 seqAlone.Append(lines.Length() + 1);
194 seqAjout.Append(lines.Length() + 1);
199 Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
201 Cadre = Standard_False;
202 //in case if there is a frame and arrive at the same time
206 ArretAjout =TestArretAjout(Func, UVap, N, Psol);
210 Tgtend = lines.Value(N)->IsTangentAtEnd();
214 // modified by NIZHNY-MKK Thu Nov 2 15:09:08 2000.BEGIN
215 if(!(Rajout && ArretAjout)) {
216 Standard_Real prevUp, prevVp;
218 previousPoint.ParametersOnS2(prevUp, prevVp);
221 previousPoint.ParametersOnS1(prevUp, prevVp);
223 Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
224 nbMultiplicities, tolerance, Func, UVap, N);
226 Cadre = Standard_False;
229 // modified by NIZHNY-MKK Thu Nov 2 15:09:13 2000.END
230 if (!ArretAjout && Cadre) {
231 if (CurrentLine->NbPoints() == 1) break; // cancel the line
232 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
234 if (N <= 0) { // jag 941017
235 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
236 Tgtend = Func.IsTangent();
241 Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
242 NbDivision,PasC,StepSign);
243 StatusPrecedent = Status;
244 if (Status == IntWalk_PasTropGrand) {
245 Arrive = Standard_False;
246 ArretAjout = Standard_False;
247 Tgtend = Standard_False; // jag 940615
249 previousPoint.ParametersOnS2(UVap(1), UVap(2));
252 previousPoint.ParametersOnS1(UVap(1), UVap(2));
255 else if (ArretAjout || Cadre) {
256 Arrive = Standard_True;
257 CurrentLine->AddStatusLast(Standard_False);
258 //if (Status != IntWalk_ArretSurPointPrecedent)
259 CurrentLine->AddPoint(Psol);
260 //Remove <SaveN> from <seqAlone>
261 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
262 if (seqAlone(iseq) == SaveN)
264 seqAlone.Remove(iseq);
269 Rajout = Standard_True;
270 seqAjout.Append(lines.Length()+1);
273 else if (Status == IntWalk_ArretSurPointPrecedent) {
274 if (CurrentLine->NbPoints() == 1) { //cancel the line
275 Arrive = Standard_False;
278 Arrive = Standard_True;
279 Rajout = Standard_True;
281 seqAlone.Append(lines.Length() + 1);
282 seqAjout.Append(lines.Length() + 1);
283 CurrentLine->AddStatusLast(Standard_False);
284 Tgtend = Standard_True; // check
287 if (CurrentLine->NbPoints() == 1 && // cancel the line
288 (N == I || Status == IntWalk_PointConfondu) ) {
289 // if N == I the main uv is probably lost
290 // or the point is a point of accumulation
291 // if point is confused the start data is bad
292 Arrive = Standard_False;
295 // necessairily N > 0 jag 940617
296 // point of stop given at input
297 PathPnt = Pnts1.Value(N);
299 Standard_Integer etat1N=wd1[N].etat;
300 // modified by NIZHNY-MKK Thu Nov 2 15:09:51 2000.BEGIN
301 // if (etat1N < 11) { // passing point that is a stop
302 if (Abs(etat1N) < 11) { // passing point that is a stop
303 // modified by NIZHNY-MKK Thu Nov 2 15:12:11 2000.END
304 if (Status == IntWalk_ArretSurPoint) {
305 CurrentLine->AddStatusLast(Standard_False);
306 Tgtend = Standard_True; // need check
309 Arrive = Standard_False;
311 CurrentLine->AddIndexPassing(N);
313 else { // point of stop given at input
315 Tgtend = Standard_True;
317 CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
319 AddPointInCurrentLine(N,PathPnt,CurrentLine);
320 if ((etat1N != 1 && etat1N != 11)) {
321 // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN
322 // wd1[N].etat= - wd1[N].etat;
323 wd1[N].etat = - Abs(etat1N);
324 movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
325 if(Arrive && movementdirectioninfo[N]!=0) {
326 IndexOfPathPointDoNotCheck = N;
330 Rajout = Standard_True;
331 seqAjout.Append(lines.Length() + 1);
333 // modified by NIZHNY-MKK Fri Oct 27 12:45:33 2000.END
336 else if (Status == IntWalk_ArretSurPoint) {
337 Arrive = Standard_True;
338 CurrentLine->AddStatusLast(Standard_False);
339 Tgtend = Standard_True;
340 MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
341 CurrentLine->AddPoint(Psol);
342 Rajout = Standard_True;
343 seqAlone.Append(lines.Length() + 1);
344 seqAjout.Append(lines.Length() + 1);
346 else if (Status == IntWalk_OK) {
347 MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
348 previousd3d = Func.Direction3d();
349 previousd2d = Func.Direction2d();
350 CurrentLine->AddPoint(previousPoint);
352 else if (Status == IntWalk_PointConfondu)
358 else { // no numerical solution
360 PasCu = Abs(PasC*previousd2d.X());
361 PasCv = Abs(PasC*previousd2d.Y());
362 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
363 if (CurrentLine->NbPoints()==1) break;
364 Arrive = Standard_True;
365 CurrentLine->AddStatusLast(Standard_False);
366 Tgtend = Standard_True; // need check
367 Rajout = Standard_True;
368 seqAlone.Append(lines.Length() + 1);
369 seqAjout.Append(lines.Length() + 1);
375 } // end of started line
378 CurrentLine->SetTangencyAtEnd(Tgtend);
379 lines.Append(CurrentLine);
380 // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN
381 movementdirectioninfo[I]=0;
383 // modified by NIZHNY-MKK Fri Oct 27 12:59:42 2000.END
384 wd1[I].etat=-wd1[I].etat;
386 //-- lbr le 5 juin 97 (Pb ds Contap)
387 for(Standard_Integer av=1; av<=nbPath; av++) {
388 // modified by NIZHNY-MKK Fri Oct 27 13:00:22 2000.BEGIN
389 // if (wd1[av].etat > 11) {
390 if ((wd1[av].etat > 11) ||
392 (av!=IndexOfPathPointDoNotCheck) &&
393 (wd1[av].etat < -11) &&
394 (movementdirectioninfo[av]!=0)))
396 // modified by NIZHNY-MKK Fri Oct 27 13:00:26 2000.END
397 Standard_Real Uav=wd1[av].ustart;
398 Standard_Real Vav=wd1[av].vstart;
399 Standard_Real Uavp,Vavp;
400 const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
402 avP.ParametersOnS2(Uavp,Vavp);
405 avP.ParametersOnS1(Uavp,Vavp);
409 Uav*=0.001; Vav*=0.001;
410 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
411 // modified by NIZHNY-MKK Fri Oct 27 13:01:38 2000.BEGIN
412 // wd1[av].etat=-wd1[av].etat;
413 if(wd1[av].etat < 0) {
414 movementdirectioninfo[av] = 0;
416 wd1[av].etat=-wd1[av].etat;
417 movementdirectioninfo[av] = StepSign;
419 // modified by NIZHNY-MKK Fri Oct 27 13:01:42 2000.END
420 CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
421 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
424 const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
426 avPP.ParametersOnS2(Uavp,Vavp);
429 avPP.ParametersOnS1(Uavp,Vavp);
435 Uav*=0.001; Vav*=0.001;
436 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
437 // modified by NIZHNY-MKK Fri Oct 27 13:02:49 2000.BEGIN
438 // wd1[av].etat=-wd1[av].etat;
439 if(wd1[av].etat < 0) {
440 movementdirectioninfo[av] = 0;
442 wd1[av].etat=-wd1[av].etat;
443 movementdirectioninfo[av] = -StepSign;
445 // modified by NIZHNY-MKK Fri Oct 27 13:02:52 2000.END
446 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
447 CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
452 } //end of point processing
453 } //end of all points
456 // modified by NIZHNY-MKK Thu Nov 2 15:07:53 2000.BEGIN
457 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
458 const TColStd_SequenceOfReal& Umult,
459 const TColStd_SequenceOfReal& Vmult,
460 const Standard_Real& prevUp,
461 const Standard_Real& prevVp,
462 const IntWalk_VectorOfInteger& nbMultiplicities,
463 const math_Vector& tolerance,
466 Standard_Integer& Irang) {
467 Standard_Boolean Arrive = Standard_False;
468 Standard_Real Dup, Dvp, Utest,Vtest;
469 Standard_Real tolu = tolerance(1);
470 Standard_Real tolv = tolerance(2);
471 Standard_Integer i, j, k, N;
472 for (i = 1; i < (int)wd.size(); i++) {
473 if (wd[i].etat < -11) {
475 // debug jag see with isg
477 Utest = wd[i].ustart;
478 Vtest = wd[i].vstart;
479 Dup = prevUp - Utest;
480 Dvp = prevVp - Vtest;
481 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
482 Standard_Real UV1mUtest = UV(1)-Utest;
483 Standard_Real UV2mVtest = UV(2)-Vtest;
484 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
485 ( Abs(UV1mUtest) < tolu
486 && Abs(UV2mVtest) < tolv)) {
488 Arrive = Standard_True;
492 else if (nbMultiplicities[i] > 0) {
494 for (k = 1; k < i; k++) {
495 N+=nbMultiplicities[k];
497 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
498 if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
499 (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
500 (Abs(UV(1)-Umult(j)) < tolu &&
501 Abs(UV(2)-Vmult(j)) < tolv)) {
503 Arrive = Standard_True;
511 Standard_Real abidF[1], abidD[1][2];
512 math_Vector bidF(abidF,1,1);
513 math_Matrix bidD(abidD,1,1,1,2);
514 sp.Values(UV,bidF,bidD);
522 // modified by NIZHNY-MKK Thu Nov 2 15:07:58 2000.END