0022627: Change OCCT memory management defaults
[occt.git] / src / Blend / Blend_Walking_1.gxx
CommitLineData
7fd59977 1Blend_Walking::Blend_Walking(const TheSurface& Surf1,
2 const TheSurface& Surf2,
3 const Handle(TheTopolTool)& Domain1,
4 const Handle(TheTopolTool)& Domain2):
5 sol(1,4),surf1(Surf1),surf2(Surf2),
6 done(Standard_False),
7 clasonS1(Standard_True),clasonS2(Standard_True),
8 check2d(Standard_True),check(Standard_True),
9 twistflag1(Standard_False),twistflag2(Standard_False)
10
11{
12 domain1 = Domain1;
13 domain2 = Domain2;
14 recdomain1 = Domain1;
15 recdomain2 = Domain2;
16}
17
18void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1,
19 const Handle(TheTopolTool)& Domain2)
20{
21 recdomain1 = Domain1;
22 recdomain2 = Domain2;
23}
24
25void Blend_Walking::AddSingularPoint(const Blend_Point& P)
26{
27 if (jalons.Length() == 0) {
28 jalons.Append(P);
29 }
30 else {
31 Standard_Integer ii, jj;
32 Standard_Real tp = P.Parameter(),
33 ti=jalons.First().Parameter();
34 for (jj=1, ii=1; ii<=jalons.Length() && tp>ti; ii++) {
35 jj = ii;
36 ti = jalons.Value(jj).Parameter();
37 }
38 if (tp > ti) jalons.InsertAfter(jj, P);
39 else jalons.InsertBefore(jj, P);
40 }
41}
42
43void Blend_Walking::Perform(Blend_Function& Func,
44 Blend_FuncInv& FuncInv,
45 const Standard_Real Pdep,
46 const Standard_Real Pmax,
47 const Standard_Real MaxStep,
48 const Standard_Real TolGuide,
49 const math_Vector& ParDep,
50 const Standard_Real Tolesp,
51 const Standard_Real Fleche,
52 const Standard_Boolean Appro)
53{
54
55 done = Standard_False;
56 iscomplete = Standard_False;
57 comptra = Standard_False;
58 Standard_Boolean doextremities = 1;
59 if(line.IsNull()) line = new TheLine ();
60 else {line->Clear();doextremities = 0;}
61 tolesp = Abs(Tolesp);
62 tolgui = Abs(TolGuide);
63 fleche = Abs(Fleche);
64 rebrou = Standard_False;
65 pasmax = Abs(MaxStep);
66 if (Pmax-Pdep >= 0.) {
67 sens = 1.;
68 }
69 else {
70 sens = -1.;
71 }
72
73 Blend_Status State;
74 TheExtremity ptf1,ptf2;
75
76 param = Pdep;
77 Func.Set(param);
78
79 if (Appro) {
80
81 TopAbs_State situ1,situ2;
82 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
83 Func.GetTolerance(tolerance,tolesp);
84 Func.GetBounds(infbound,supbound);
85 math_FunctionSetRoot rsnld(Func,tolerance,30);
86
87 rsnld.Perform(Func,ParDep,infbound,supbound);
88
89 if (!rsnld.IsDone()) {
90 return;
91 }
92 rsnld.Root(sol);
93
94 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
95 Min(tolerance(1),tolerance(2)),0);
96 else situ1 = TopAbs_IN;
97 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
98 Min(tolerance(3),tolerance(4)),0);
99 else situ2 = TopAbs_IN;
100
101 if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) {
102 return;
103 }
104 }
105 else {
106 sol = ParDep;
107 }
108
109#ifdef DEB
110 sectioncalculee = 0;
111#endif
112 State = TestArret(Func, Blend_OK, Standard_False);
113 if (State!=Blend_OK) {
114 return;
115 }
116#ifdef DEB
117 if (Blend_GettraceDRAWSECT()){
118 Drawsect(surf1,surf2,sol,param,Func);
119 }
120 nbcomputedsection = 1;
121#endif
122 // Mettre a jour la ligne.
123 line->Append(previousP);
124
125 if(doextremities){
126 TheExtremity ptf1 (previousP.PointOnS1(),
127 sol(1),sol(2),tolesp);
128 TheExtremity ptf2 (previousP.PointOnS2(),
129 sol(3),sol(4),tolesp);
130 if (!previousP.IsTangencyPoint()) {
131 ptf1.SetTangent(previousP.TangentOnS1());
132 ptf2.SetTangent(previousP.TangentOnS2());
133 }
134
135 if (sens>0.) {
136 line->SetStartPoints(ptf1, ptf2);
137 }
138 else {
139 line->SetEndPoints(ptf1, ptf2);
140 }
141 }
142
143 InternalPerform(Func,FuncInv,Pmax);
144
145#ifdef DEB
146// cout <<"Perform : "<<nbcomputedsection<<" sections calculees"<<endl;
147// cout <<line->NbPoints()<<" sections gardees"<<endl;
148#endif
149
150 done = Standard_True;
151}
152
153
154Standard_Boolean Blend_Walking::PerformFirstSection
155(Blend_Function& Func,
156 const Standard_Real Pdep,
157 math_Vector& ParDep,
158 const Standard_Real Tolesp,
159 const Standard_Real TolGuide,
160 TopAbs_State& Pos1,
161 TopAbs_State& Pos2)
162{
163 iscomplete = Standard_False;
164 comptra = Standard_False;
165 line = new TheLine ();
166 tolesp = Abs(Tolesp);
167 tolgui = Abs(TolGuide);
168
169 Pos1 = Pos2 = TopAbs_UNKNOWN;
170
171 Blend_Status State;
172
173 param = Pdep;
174 Func.Set(param);
175
176 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
177 Func.GetTolerance(tolerance,tolesp);
178 Func.GetBounds(infbound,supbound);
179 math_FunctionSetRoot rsnld(Func,tolerance,30);
180
181 rsnld.Perform(Func,ParDep,infbound,supbound);
182
183 if (!rsnld.IsDone()) {
184 return Standard_False;
185 }
186 rsnld.Root(sol);
187 ParDep = sol;
188 Pos1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
189 Min(tolerance(1),tolerance(2)),0);
190 Pos2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
191 Min(tolerance(3),tolerance(4)),0);
192 if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN) {
193 return Standard_False;
194 }
195
196 State = TestArret(Func, Blend_OK, Standard_False);
197#ifdef DEB
198 if (Blend_GettraceDRAWSECT()){
199 Drawsect(surf1,surf2,sol,param,Func);
200 }
201#endif
202 return Standard_True;
203}
204
205
206Standard_Boolean Blend_Walking::PerformFirstSection
207 (Blend_Function& Func,
208 Blend_FuncInv& FuncInv,
209 const Standard_Real Pdep,
210 const Standard_Real Pmax,
211 const math_Vector& ParDep,
212 const Standard_Real Tolesp,
213 const Standard_Real TolGuide,
214 const Standard_Boolean RecOnS1,
215 const Standard_Boolean RecOnS2,
216 Standard_Real& Psol,
217 math_Vector& ParSol)
218
219{
220 iscomplete = Standard_False;
221 comptra = Standard_False;
222 line = new TheLine ();
223
224 Standard_Real w1,w2, extrapol;
225 Standard_Boolean recad1,recad2;
226
227 tolesp = Abs(Tolesp);
228 tolgui = Abs(TolGuide);
229 if (Pmax-Pdep >= 0.) {
230 sens = 1.;
231 }
232 else {
233 sens = -1.;
234 }
235 extrapol = Abs(Pmax-Pdep)/50; // 2%
236
237 Blend_Status State;
238
239 param = Pdep;
240 Func.Set(param);
241
242 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
243 math_Vector solrst1(1,4),solrst2(1,4);
244 TheExtremity Ext1,Ext2;
245 Standard_Integer Index1,Index2,nbarc;
246 Standard_Boolean Isvtx1,Isvtx2;
247 TheVertex Vtx1,Vtx2;
248 gp_Pnt2d p2d;
249
250 Func.GetTolerance(tolerance,tolesp);
251 Func.GetBounds(infbound,supbound);
252 math_FunctionSetRoot rsnld(Func,tolerance,30);
253
254 rsnld.Perform(Func,ParDep,infbound,supbound);
255
256 if (!rsnld.IsDone()) {
257 return Standard_False;
258 }
259 rsnld.Root(sol);
260
261 w1 = w2 = Pmax;
262
263 recad1 = RecOnS1 && Recadre(FuncInv,Standard_True,
264 sol,solrst1,Index1,Isvtx1,Vtx1, extrapol);
265 if (recad1) {
266 w1 = solrst1(2);
267 }
268
269 recad2 = RecOnS2 && Recadre(FuncInv,Standard_False,
270 sol,solrst2,Index2,Isvtx2,Vtx2, extrapol);
271 if (recad2) {
272 w2 = solrst2(2);
273 }
274
275 if (!recad1 && !recad2) {
276 return Standard_False;
277 }
278
279 if (recad1 && recad2) {
280 if (Abs(w1-w2) <= tolgui) {
281 //sol sur 1 et 2 a la fois
282 State = Blend_OnRst12;
283 param = w1;
284 ParSol(1) = solrst2(3);
285 ParSol(2) = solrst2(4);
286 ParSol(3) = solrst1(3);
287 ParSol(4) = solrst1(4);
288 }
289 else if (sens*(w2-w1) < 0.) { // on garde le plus grand
290 //sol sur 1
291 State = Blend_OnRst1;
292 param = w1;
293
294 recdomain1->Init();
295 nbarc = 1;
296 while (nbarc < Index1) {
297 nbarc++;
298 recdomain1->Next();
299 }
300 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
301 ParSol(1) = p2d.X();
302 ParSol(2) = p2d.Y();
303 ParSol(3) = solrst1(3);
304 ParSol(4) = solrst1(4);
305
306 }
307 else {
308 //sol sur 2
309 State = Blend_OnRst2;
310 param = w2;
311
312 recdomain2->Init();
313 nbarc = 1;
314 while (nbarc < Index2) {
315 nbarc++;
316 recdomain2->Next();
317 }
318 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
319 ParSol(1) = solrst2(3);
320 ParSol(2) = solrst2(4);
321 ParSol(3) = p2d.X();
322 ParSol(4) = p2d.Y();
323 }
324 }
325 else if (recad1) {
326 // sol sur 1
327 State = Blend_OnRst1;
328 param = w1;
329 recdomain1->Init();
330 nbarc = 1;
331 while (nbarc < Index1) {
332 nbarc++;
333 recdomain1->Next();
334 }
335 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
336 ParSol(1) = p2d.X();
337 ParSol(2) = p2d.Y();
338 ParSol(3) = solrst1(3);
339 ParSol(4) = solrst1(4);
340 }
341 else { //if (recad2) {
342 //sol sur 2
343 State = Blend_OnRst2;
344 param = w2;
345
346 recdomain2->Init();
347 nbarc = 1;
348 while (nbarc < Index2) {
349 nbarc++;
350 recdomain2->Next();
351 }
352 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
353 ParSol(1) = solrst2(3);
354 ParSol(2) = solrst2(4);
355 ParSol(3) = p2d.X();
356 ParSol(4) = p2d.Y();
357 }
358
359 Psol = param;
360 sol = ParSol;
361 Func.Set(param);
362 State = TestArret(Func, State, Standard_False);
363 switch (State) {
364 case Blend_OnRst1 :
365 {
366#ifdef DEB
367 if (Blend_GettraceDRAWSECT()){
368 Drawsect(surf1,surf2,sol,param,Func);
369 }
370#endif
371 MakeExtremity(Ext1,Standard_True,Index1,
372 solrst1(1),Isvtx1,Vtx1);
373 Ext2.SetValue(previousP.PointOnS2(),
374 sol(3),sol(4),tolesp);
375 }
376 break;
377
378 case Blend_OnRst2 :
379 {
380#ifdef DEB
381 if (Blend_GettraceDRAWSECT()){
382 Drawsect(surf1,surf2,sol,param,Func);
383 }
384#endif
385 Ext1.SetValue(previousP.PointOnS1(),
386 sol(1),sol(2),tolesp);
387 MakeExtremity(Ext2,Standard_False,Index2,
388 solrst2(1),Isvtx2,Vtx2);
389 }
390 break;
391
392 case Blend_OnRst12 :
393 {
394#ifdef DEB
395 if (Blend_GettraceDRAWSECT()){
396 Drawsect(surf1,surf2,sol,param,Func);
397 }
398#endif
399 MakeExtremity(Ext1,Standard_True,Index1,
400 solrst1(1),Isvtx1,Vtx1);
401 MakeExtremity(Ext2,Standard_False,Index2,
402 solrst2(1),Isvtx2,Vtx2);
403 }
404 break;
405 default:
406 {
407 Standard_Failure::Raise("Blend_Walking::PerformFirstSection : echec");
408 }
409 }
410 if (sens < 0.) {
411 line->SetEndPoints(Ext1,Ext2);
412 }
413 else {
414 line->SetStartPoints(Ext1,Ext2);
415 }
416 return Standard_True;
417}
418
419
420
421Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
422 Blend_FuncInv& FuncInv,
423 const Standard_Real P)
424{
425 if (!done) {StdFail_NotDone::Raise();}
426 const Blend_Point& firstBP = line->Point(1);
427 const Blend_Point& lastBP = line->Point(line->NbPoints());
428
429 if (P < firstBP.Parameter()){
430 sens = -1.;
431 previousP = firstBP;
432 }
433 else if(P > lastBP.Parameter()){
434 sens = 1.;
435 previousP = lastBP;
436 }
437
438 param = previousP.Parameter();
439 previousP.ParametersOnS1(sol(1),sol(2));
440 previousP.ParametersOnS2(sol(3),sol(4));
441
442 InternalPerform(Func,FuncInv,P);
443 return Standard_True;
444}
445
446
447Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
448 Blend_FuncInv& FuncInv,
449 const Standard_Real P,
450 const Standard_Boolean OnS1)
451{
452 if (!done) {StdFail_NotDone::Raise();}
453 TheExtremity Ext1,Ext2;
454 if (sens < 0.) {
455 Ext1 = line->StartPointOnFirst();
456 Ext2 = line->StartPointOnSecond();
457 if (OnS1 && Ext1.NbPointOnRst() == 0 ||
458 !OnS1 && Ext2.NbPointOnRst() == 0) {
459 return Standard_False;
460 }
461 previousP = line->Point(1);
462
463
464 }
465 else {
466 Ext1 = line->EndPointOnFirst();
467 Ext2 = line->EndPointOnSecond();
468 if (OnS1 && Ext1.NbPointOnRst() == 0 ||
469 !OnS1 && Ext2.NbPointOnRst() == 0) {
470 return Standard_False;
471 }
472 previousP = line->Point(line->NbPoints());
473 }
474
475 Standard_Integer length = line->NbPoints();
476 param = previousP.Parameter();
477 previousP.ParametersOnS1(sol(1),sol(2));
478 previousP.ParametersOnS2(sol(3),sol(4));
479
480 if(OnS1) clasonS1 = Standard_False;
481 else clasonS2 = Standard_False;
482
483 InternalPerform(Func,FuncInv,P);
484
485 clasonS1 = Standard_True;
486 clasonS2 = Standard_True;
487
488 Standard_Integer newlength = line->NbPoints();
489 if (sens <0.) {
490 if (OnS1 && line->StartPointOnSecond().NbPointOnRst() == 0 ||
491 !OnS1 && line->StartPointOnFirst().NbPointOnRst() == 0) {
492 line->Remove(1,newlength-length);
493 line->SetStartPoints(Ext1,Ext2);
494 return Standard_False;
495 }
496 }
497 else {
498 if (OnS1 && line->EndPointOnSecond().NbPointOnRst() == 0 ||
499 !OnS1 && line->EndPointOnFirst().NbPointOnRst() == 0) {
500 line->Remove(length,newlength);
501 line->SetEndPoints(Ext1,Ext2);
502 return Standard_False;
503 }
504 }
505 return Standard_True;
506}
507
508
509Standard_Boolean Blend_Walking::Complete(Blend_Function& Func,
510 Blend_FuncInv& FuncInv,
511 const Standard_Real Pmin)
512{
513 if (!done) {StdFail_NotDone::Raise();}
514 if (iscomplete) {return Standard_True;}
515
516 if (sens >0.) {
517 previousP = line->Point(1);
518 }
519 else {
520 previousP = line->Point(line->NbPoints());
521 }
522
523 sens = -sens;
524
525 param = previousP.Parameter();
526 previousP.ParametersOnS1(sol(1),sol(2));
527 previousP.ParametersOnS2(sol(3),sol(4));
528
529 InternalPerform(Func,FuncInv,Pmin);
530
531#ifdef DEB
532// cout <<"Complete : "<<nbcomputedsection<<" sections calculees"<<endl;
533// cout <<line->NbPoints()<<" sections gardees"<<endl;
534#endif
535
536 iscomplete = Standard_True;
537 return Standard_True;
538}
539
540void Blend_Walking::ClassificationOnS1(const Standard_Boolean C)
541{
542 clasonS1 = C;
543}
544
545void Blend_Walking::ClassificationOnS2(const Standard_Boolean C)
546{
547 clasonS2 = C;
548}
549
550void Blend_Walking::Check2d(const Standard_Boolean C)
551{
552 check2d = C;
553}
554
555void Blend_Walking::Check(const Standard_Boolean C)
556{
557 check = C;
558}
559