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