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 aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK;
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 TheIWFunction aFuncForDuplicate = Func;
104 for (I = 1; I <= nbPath; I++) {
105 //start point of the progression
106 // if (wd1[I].etat > 11) {
107 // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN
108 if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
109 // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END
110 PathPnt = Pnts1.Value(I);
111 UVap(1) = wd1[I].ustart;
112 UVap(2) = wd1[I].vstart;
113 MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
115 if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
117 wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed
121 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
122 CurrentLine->SetTangencyAtBegining(Standard_False);
123 Tgtend = Standard_False;
124 CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
125 previousd3d = Func.Direction3d();
126 previousd2d = Func.Direction2d();
127 CurrentLine->AddPoint(previousPoint);
128 // modified by NIZHNY-MKK Fri Oct 27 12:34:32 2000.BEGIN
129 if(movementdirectioninfo[I] !=0) {
130 if(movementdirectioninfo[I] < 0) {
132 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
135 CurrentLine->SetTangentVector(previousd3d,1);
138 Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
141 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
145 CurrentLine->SetTangentVector(previousd3d,1);
148 // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END
150 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
151 wd1[I].etat = -Abs(wd1[I].etat);
152 movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0;
153 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
154 // first step of advancement
155 Standard_Real d2dx = Abs(previousd2d.X());
156 Standard_Real d2dy = Abs(previousd2d.Y());
157 if (d2dx < tolerance(1)) {
158 PasC = pas * (VM-Vm)/d2dy;
160 else if (d2dy < tolerance(2)) {
161 PasC = pas * (UM-Um)/d2dx;
164 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
167 Arrive = Standard_False;
168 ArretAjout = Standard_False;
170 StatusPrecedent = IntWalk_OK;
171 // modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000
172 Standard_Integer IndexOfPathPointDoNotCheck=0;
173 Standard_Integer aNbIter = 10;
174 while (!Arrive) { // as one of stop tests is not checked
175 Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
182 Rsnld.Perform(Func,UVap,BornInf,BornSup);
189 BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
191 if (Rsnld.IsDone()) {
192 if (Abs(Func.Root()) > Func.Tolerance()) {
194 PasCu = Abs(PasC*previousd2d.X());
195 PasCv = Abs(PasC*previousd2d.Y());
196 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
197 if (CurrentLine->NbPoints() == 1) break;
198 Arrive = Standard_True;
199 CurrentLine->AddStatusLast(Standard_False);
200 Tgtend = Standard_True; // check
201 Rajout = Standard_True;
202 seqAlone.Append(lines.Length() + 1);
203 seqAjout.Append(lines.Length() + 1);
208 Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
210 Cadre = Standard_False;
211 //in case if there is a frame and arrive at the same time
215 ArretAjout =TestArretAjout(Func, UVap, N, Psol);
219 Tgtend = lines.Value(N)->IsTangentAtEnd();
223 // modified by NIZHNY-MKK Thu Nov 2 15:09:08 2000.BEGIN
224 if(!(Rajout && ArretAjout)) {
225 Standard_Real prevUp, prevVp;
227 previousPoint.ParametersOnS2(prevUp, prevVp);
230 previousPoint.ParametersOnS1(prevUp, prevVp);
232 Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
233 nbMultiplicities, tolerance, Func, UVap, N);
235 Cadre = Standard_False;
238 // modified by NIZHNY-MKK Thu Nov 2 15:09:13 2000.END
239 if (!ArretAjout && Cadre) {
240 if (CurrentLine->NbPoints() == 1) break; // cancel the line
241 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
243 if (N <= 0) { // jag 941017
244 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
245 Tgtend = Func.IsTangent();
250 aStatus = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
251 NbDivision,PasC,StepSign);
252 StatusPrecedent = aStatus;
253 if (aStatus == IntWalk_PasTropGrand) {
254 Arrive = Standard_False;
255 ArretAjout = Standard_False;
256 Tgtend = Standard_False; // jag 940615
258 previousPoint.ParametersOnS2(UVap(1), UVap(2));
261 previousPoint.ParametersOnS1(UVap(1), UVap(2));
264 else if (ArretAjout || Cadre) {
265 Arrive = Standard_True;
266 CurrentLine->AddStatusLast(Standard_False);
267 //if (aStatus != IntWalk_ArretSurPointPrecedent)
268 CurrentLine->AddPoint(Psol);
269 //Remove <SaveN> from <seqAlone>
270 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
271 if (seqAlone(iseq) == SaveN)
273 seqAlone.Remove(iseq);
278 Rajout = Standard_True;
279 seqAjout.Append(lines.Length()+1);
282 else if (aStatus == IntWalk_ArretSurPointPrecedent) {
283 if (CurrentLine->NbPoints() == 1) { //cancel the line
284 Arrive = Standard_False;
287 Arrive = Standard_True;
288 Rajout = Standard_True;
290 seqAlone.Append(lines.Length() + 1);
291 seqAjout.Append(lines.Length() + 1);
292 CurrentLine->AddStatusLast(Standard_False);
293 Tgtend = Standard_True; // check
296 if (CurrentLine->NbPoints() == 1 && // cancel the line
297 (N == I || aStatus == IntWalk_PointConfondu) ) {
298 // if N == I the main uv is probably lost
299 // or the point is a point of accumulation
300 // if point is confused the start data is bad
301 Arrive = Standard_False;
304 // necessairily N > 0 jag 940617
305 // point of stop given at input
306 PathPnt = Pnts1.Value(N);
308 Standard_Integer etat1N=wd1[N].etat;
309 // modified by NIZHNY-MKK Thu Nov 2 15:09:51 2000.BEGIN
310 // if (etat1N < 11) { // passing point that is a stop
311 if (Abs(etat1N) < 11) { // passing point that is a stop
312 // modified by NIZHNY-MKK Thu Nov 2 15:12:11 2000.END
313 if (aStatus == IntWalk_ArretSurPoint) {
314 CurrentLine->AddStatusLast(Standard_False);
315 Tgtend = Standard_True; // need check
318 Arrive = Standard_False;
320 CurrentLine->AddIndexPassing(N);
322 else { // point of stop given at input
324 Tgtend = Standard_True;
326 CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
328 AddPointInCurrentLine(N,PathPnt,CurrentLine);
329 if ((etat1N != 1 && etat1N != 11)) {
330 // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN
331 // wd1[N].etat= - wd1[N].etat;
332 wd1[N].etat = - Abs(etat1N);
333 movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
334 if(Arrive && movementdirectioninfo[N]!=0) {
335 IndexOfPathPointDoNotCheck = N;
339 Rajout = Standard_True;
340 seqAjout.Append(lines.Length() + 1);
342 // modified by NIZHNY-MKK Fri Oct 27 12:45:33 2000.END
345 else if (aStatus == IntWalk_ArretSurPoint) {
346 Arrive = Standard_True;
347 CurrentLine->AddStatusLast(Standard_False);
348 Tgtend = Standard_True;
349 MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
350 CurrentLine->AddPoint(Psol);
351 Rajout = Standard_True;
352 seqAlone.Append(lines.Length() + 1);
353 seqAjout.Append(lines.Length() + 1);
355 else if (aStatus == IntWalk_OK) {
356 MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
357 previousd3d = Func.Direction3d();
358 previousd2d = Func.Direction2d();
359 CurrentLine->AddPoint(previousPoint);
361 else if (aStatus == IntWalk_PointConfondu)
367 else { // no numerical solution
369 PasCu = Abs(PasC*previousd2d.X());
370 PasCv = Abs(PasC*previousd2d.Y());
371 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
372 if (CurrentLine->NbPoints()==1) break;
373 Arrive = Standard_True;
374 CurrentLine->AddStatusLast(Standard_False);
375 Tgtend = Standard_True; // need check
376 Rajout = Standard_True;
377 seqAlone.Append(lines.Length() + 1);
378 seqAjout.Append(lines.Length() + 1);
384 } // end of started line
387 CurrentLine->SetTangencyAtEnd(Tgtend);
388 lines.Append(CurrentLine);
389 // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN
390 movementdirectioninfo[I]=0;
392 // modified by NIZHNY-MKK Fri Oct 27 12:59:42 2000.END
393 wd1[I].etat=-wd1[I].etat;
395 //-- lbr le 5 juin 97 (Pb ds Contap)
396 for(Standard_Integer av=1; av<=nbPath; av++) {
397 // modified by NIZHNY-MKK Fri Oct 27 13:00:22 2000.BEGIN
398 // if (wd1[av].etat > 11) {
399 if ((wd1[av].etat > 11) ||
401 (av!=IndexOfPathPointDoNotCheck) &&
402 (wd1[av].etat < -11) &&
403 (movementdirectioninfo[av]!=0)))
405 // modified by NIZHNY-MKK Fri Oct 27 13:00:26 2000.END
406 Standard_Real Uav=wd1[av].ustart;
407 Standard_Real Vav=wd1[av].vstart;
408 Standard_Real Uavp,Vavp;
409 const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
411 avP.ParametersOnS2(Uavp,Vavp);
414 avP.ParametersOnS1(Uavp,Vavp);
418 Uav*=0.001; Vav*=0.001;
419 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
420 // modified by NIZHNY-MKK Fri Oct 27 13:01:38 2000.BEGIN
421 // wd1[av].etat=-wd1[av].etat;
422 if(wd1[av].etat < 0) {
423 movementdirectioninfo[av] = 0;
425 wd1[av].etat=-wd1[av].etat;
426 movementdirectioninfo[av] = StepSign;
428 // modified by NIZHNY-MKK Fri Oct 27 13:01:42 2000.END
429 CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
430 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
433 const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
435 avPP.ParametersOnS2(Uavp,Vavp);
438 avPP.ParametersOnS1(Uavp,Vavp);
444 Uav*=0.001; Vav*=0.001;
445 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
446 // modified by NIZHNY-MKK Fri Oct 27 13:02:49 2000.BEGIN
447 // wd1[av].etat=-wd1[av].etat;
448 if(wd1[av].etat < 0) {
449 movementdirectioninfo[av] = 0;
451 wd1[av].etat=-wd1[av].etat;
452 movementdirectioninfo[av] = -StepSign;
454 // modified by NIZHNY-MKK Fri Oct 27 13:02:52 2000.END
455 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
456 CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
461 } //end of point processing
462 } //end of all points
465 // modified by NIZHNY-MKK Thu Nov 2 15:07:53 2000.BEGIN
466 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
467 const TColStd_SequenceOfReal& Umult,
468 const TColStd_SequenceOfReal& Vmult,
469 const Standard_Real& prevUp,
470 const Standard_Real& prevVp,
471 const IntWalk_VectorOfInteger& nbMultiplicities,
472 const math_Vector& tolerance,
475 Standard_Integer& Irang) {
476 Standard_Boolean Arrive = Standard_False;
477 Standard_Real Dup, Dvp, Utest,Vtest;
478 Standard_Real tolu = tolerance(1);
479 Standard_Real tolv = tolerance(2);
480 Standard_Integer i, j, k, N;
481 for (i = 1; i < (int)wd.size(); i++) {
482 if (wd[i].etat < -11) {
484 // debug jag see with isg
486 Utest = wd[i].ustart;
487 Vtest = wd[i].vstart;
488 Dup = prevUp - Utest;
489 Dvp = prevVp - Vtest;
490 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
491 Standard_Real UV1mUtest = UV(1)-Utest;
492 Standard_Real UV2mVtest = UV(2)-Vtest;
493 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
494 ( Abs(UV1mUtest) < tolu
495 && Abs(UV2mVtest) < tolv)) {
497 Arrive = Standard_True;
501 else if (nbMultiplicities[i] > 0) {
503 for (k = 1; k < i; k++) {
504 N+=nbMultiplicities[k];
506 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
507 if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
508 (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
509 (Abs(UV(1)-Umult(j)) < tolu &&
510 Abs(UV(2)-Vmult(j)) < tolv)) {
512 Arrive = Standard_True;
520 Standard_Real abidF[1], abidD[1][2];
521 math_Vector bidF(abidF,1,1);
522 math_Matrix bidD(abidD,1,1,1,2);
523 sp.Values(UV,bidF,bidD);
531 // modified by NIZHNY-MKK Thu Nov 2 15:07:58 2000.END