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