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 Blend_Walking::Blend_Walking(const TheSurface& Surf1,
16 const TheSurface& Surf2,
17 const Handle(TheTopolTool)& Domain1,
18 const Handle(TheTopolTool)& Domain2,
19 const Handle(ChFiDS_HElSpine)& HGuide):
20 sol(1,4),surf1(Surf1),surf2(Surf2),
21 ToCorrectOnRst1(Standard_False),ToCorrectOnRst2(Standard_False),
23 clasonS1(Standard_True),clasonS2(Standard_True),
24 check2d(Standard_True),check(Standard_True),
25 twistflag1(Standard_False),twistflag2(Standard_False)
35 void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1,
36 const Handle(TheTopolTool)& Domain2)
42 void Blend_Walking::AddSingularPoint(const Blend_Point& P)
44 if (jalons.Length() == 0) {
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++) {
53 ti = jalons.Value(jj).Parameter();
55 if (tp > ti) jalons.InsertAfter(jj, P);
56 else jalons.InsertBefore(jj, P);
60 void 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)
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;}
79 tolgui = Abs(TolGuide);
81 rebrou = Standard_False;
82 pasmax = Abs(MaxStep);
83 if (Pmax-Pdep >= 0.) {
97 TopAbs_State situ1,situ2;
98 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
99 Func.GetTolerance(tolerance,tolesp);
100 Func.GetBounds(infbound,supbound);
101 math_FunctionSetRoot rsnld(Func,tolerance,30);
103 rsnld.Perform(Func,ParDep,infbound,supbound);
105 if (!rsnld.IsDone()) {
110 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
111 Min(tolerance(1),tolerance(2)),0);
112 else situ1 = TopAbs_IN;
113 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
114 Min(tolerance(3),tolerance(4)),0);
115 else situ2 = TopAbs_IN;
117 if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) {
128 State = TestArret(Func, Blend_OK, Standard_False);
129 if (State!=Blend_OK) {
133 if (Blend_GettraceDRAWSECT()){
134 Drawsect(surf1,surf2,sol,param,Func);
136 nbcomputedsection = 1;
138 // Mettre a jour la ligne.
139 //Correct first parameter if needed
140 if (ToCorrectOnRst1 || ToCorrectOnRst2)
141 previousP.SetParameter(CorrectedParam);
142 line->Append(previousP);
145 TheExtremity ptf1 (previousP.PointOnS1(),
146 sol(1),sol(2),tolesp);
147 TheExtremity ptf2 (previousP.PointOnS2(),
148 sol(3),sol(4),tolesp);
149 if (!previousP.IsTangencyPoint()) {
150 ptf1.SetTangent(previousP.TangentOnS1());
151 ptf2.SetTangent(previousP.TangentOnS2());
155 line->SetStartPoints(ptf1, ptf2);
158 line->SetEndPoints(ptf1, ptf2);
162 InternalPerform(Func,FuncInv,Pmax);
164 done = Standard_True;
168 Standard_Boolean Blend_Walking::PerformFirstSection(Blend_Function& Func,
169 const Standard_Real Pdep,
171 const Standard_Real Tolesp,
172 const Standard_Real TolGuide,
176 iscomplete = Standard_False;
177 comptra = Standard_False;
178 line = new TheLine ();
179 tolesp = Abs(Tolesp);
180 tolgui = Abs(TolGuide);
182 Pos1 = Pos2 = TopAbs_UNKNOWN;
187 math_Vector tolerance(1, 4),infbound(1, 4),supbound(1, 4);
188 Func.GetTolerance(tolerance, tolesp);
189 Func.GetBounds(infbound, supbound);
190 math_FunctionSetRoot rsnld(Func, tolerance, 30);
192 rsnld.Perform(Func, ParDep, infbound, supbound);
196 return Standard_False;
200 Pos1 = domain1->Classify(gp_Pnt2d(sol(1), sol(2)), Min(tolerance(1), tolerance(2)), 0);
201 Pos2 = domain2->Classify(gp_Pnt2d(sol(3), sol(4)), Min(tolerance(3), tolerance(4)), 0);
202 if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN)
204 return Standard_False;
207 TestArret(Func, Blend_OK, Standard_False);
209 if (Blend_GettraceDRAWSECT())
211 Drawsect(surf1, surf2, sol, param, Func);
214 return Standard_True;
218 Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
219 Blend_FuncInv& FuncInv,
220 const Standard_Real Pdep,
221 const Standard_Real Pmax,
222 const math_Vector& ParDep,
223 const Standard_Real Tolesp,
224 const Standard_Real TolGuide,
225 const Standard_Boolean RecOnS1,
226 const Standard_Boolean RecOnS2,
231 iscomplete = Standard_False;
232 comptra = Standard_False;
233 line = new TheLine ();
235 Standard_Real w1, w2, extrapol;
236 Standard_Boolean recad1, recad2;
238 tolesp = Abs(Tolesp);
239 tolgui = Abs(TolGuide);
240 if (Pmax - Pdep >= 0.0)
248 extrapol = Abs(Pmax - Pdep) / 50.0; // 2%
255 math_Vector tolerance(1, 4),infbound(1, 4),supbound(1, 4);
256 math_Vector solrst1(1, 4),solrst2(1, 4);
257 TheExtremity Ext1, Ext2;
258 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
259 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False;
260 TheVertex Vtx1, Vtx2;
262 Standard_Real CorrectedU = 0., CorrectedV = 0.;
265 Func.GetTolerance(tolerance, tolesp);
266 Func.GetBounds(infbound, supbound);
267 math_FunctionSetRoot rsnld(Func, tolerance, 30);
269 rsnld.Perform(Func, ParDep, infbound, supbound);
273 return Standard_False;
279 recad1 = RecOnS1 && Recadre(FuncInv, Standard_True, sol, solrst1,
280 Index1, Isvtx1, Vtx1, extrapol);
286 recad2 = RecOnS2 && Recadre(FuncInv, Standard_False, sol, solrst2,
287 Index2, Isvtx2, Vtx2, extrapol);
293 if (!recad1 && !recad2)
295 return Standard_False;
298 if (recad1 && recad2)
300 if (Abs(w1 - w2) <= tolgui)
302 //sol sur 1 et 2 a la fois
303 State = Blend_OnRst12;
305 ParSol(1) = solrst2(3);
306 ParSol(2) = solrst2(4);
307 ParSol(3) = solrst1(3);
308 ParSol(4) = solrst1(4);
310 else if (sens * (w2 - w1) < 0.0)
311 { // on garde le plus grand
313 State = Blend_OnRst1;
318 while (nbarc < Index1)
323 p2d = TheArcTool::Value(recdomain1->Value(), solrst1(1));
326 ParSol(3) = solrst1(3);
327 ParSol(4) = solrst1(4);
333 State = Blend_OnRst2;
338 while (nbarc < Index2)
343 p2d = TheArcTool::Value(recdomain2->Value(), solrst2(1));
344 ParSol(1) = solrst2(3);
345 ParSol(2) = solrst2(4);
353 State = Blend_OnRst1;
357 while (nbarc < Index1)
362 p2d = TheArcTool::Value(recdomain1->Value(), solrst1(1));
365 ParSol(3) = solrst1(3);
366 ParSol(4) = solrst1(4);
367 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,ParSol(1),ParSol(2));
368 if (CorrectExtremityOnOneRst(1, ParSol(3), ParSol(4), param, thePntOnRst,
369 CorrectedU,CorrectedV,CorrectedPnt,CorrectedParam))
370 ToCorrectOnRst1 = Standard_True;
375 State = Blend_OnRst2;
380 while (nbarc < Index2)
385 p2d = TheArcTool::Value(recdomain2->Value(), solrst2(1));
386 ParSol(1) = solrst2(3);
387 ParSol(2) = solrst2(4);
390 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,ParSol(3),ParSol(4));
391 if (CorrectExtremityOnOneRst(2, ParSol(1), ParSol(2), param, thePntOnRst,
392 CorrectedU,CorrectedV,CorrectedPnt,CorrectedParam))
393 ToCorrectOnRst2 = Standard_True;
399 State = TestArret(Func, State, Standard_False);
405 if (Blend_GettraceDRAWSECT())
407 Drawsect(surf1, surf2, sol, param, Func);
410 MakeExtremity(Ext1, Standard_True, Index1, solrst1(1), Isvtx1, Vtx1);
412 Ext2.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolesp);
414 Ext2.SetValue(previousP.PointOnS2(), sol(3), sol(4), tolesp);
421 if (Blend_GettraceDRAWSECT())
423 Drawsect(surf1, surf2, sol, param, Func);
427 Ext1.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolesp);
429 Ext1.SetValue(previousP.PointOnS1(), sol(1), sol(2), tolesp);
430 MakeExtremity(Ext2, Standard_False, Index2, solrst2(1), Isvtx2, Vtx2);
437 if (Blend_GettraceDRAWSECT())
439 Drawsect(surf1, surf2, sol, param, Func);
442 MakeExtremity(Ext1, Standard_True , Index1, solrst1(1), Isvtx1, Vtx1);
443 MakeExtremity(Ext2, Standard_False, Index2, solrst2(1), Isvtx2, Vtx2);
448 throw Standard_Failure("Blend_Walking::PerformFirstSection : echec");
453 line->SetEndPoints(Ext1, Ext2);
457 line->SetStartPoints(Ext1, Ext2);
459 return Standard_True;
464 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
465 Blend_FuncInv& FuncInv,
466 const Standard_Real P)
468 if (!done) {throw StdFail_NotDone();}
469 const Blend_Point& firstBP = line->Point(1);
470 const Blend_Point& lastBP = line->Point(line->NbPoints());
472 if (P < firstBP.Parameter()){
476 else if(P > lastBP.Parameter()){
481 param = previousP.Parameter();
482 previousP.ParametersOnS1(sol(1),sol(2));
483 previousP.ParametersOnS2(sol(3),sol(4));
485 InternalPerform(Func,FuncInv,P);
486 return Standard_True;
490 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
491 Blend_FuncInv& FuncInv,
492 const Standard_Real P,
493 const Standard_Boolean OnS1)
495 if (!done) {throw StdFail_NotDone();}
496 TheExtremity Ext1,Ext2;
498 Ext1 = line->StartPointOnFirst();
499 Ext2 = line->StartPointOnSecond();
500 if ((OnS1 && Ext1.NbPointOnRst() == 0) ||
501 (!OnS1 && Ext2.NbPointOnRst() == 0)) {
502 return Standard_False;
504 previousP = line->Point(1);
509 Ext1 = line->EndPointOnFirst();
510 Ext2 = line->EndPointOnSecond();
511 if ((OnS1 && Ext1.NbPointOnRst() == 0) ||
512 (!OnS1 && Ext2.NbPointOnRst() == 0)) {
513 return Standard_False;
515 previousP = line->Point(line->NbPoints());
518 Standard_Integer length = line->NbPoints();
519 param = previousP.Parameter();
520 previousP.ParametersOnS1(sol(1),sol(2));
521 previousP.ParametersOnS2(sol(3),sol(4));
523 if(OnS1) clasonS1 = Standard_False;
524 else clasonS2 = Standard_False;
526 InternalPerform(Func,FuncInv,P);
528 clasonS1 = Standard_True;
529 clasonS2 = Standard_True;
531 Standard_Integer newlength = line->NbPoints();
533 if ((OnS1 && line->StartPointOnSecond().NbPointOnRst() == 0) ||
534 (!OnS1 && line->StartPointOnFirst().NbPointOnRst() == 0)) {
535 line->Remove(1,newlength-length);
536 line->SetStartPoints(Ext1,Ext2);
537 return Standard_False;
541 if ((OnS1 && line->EndPointOnSecond().NbPointOnRst() == 0) ||
542 (!OnS1 && line->EndPointOnFirst().NbPointOnRst() == 0)) {
543 line->Remove(length,newlength);
544 line->SetEndPoints(Ext1,Ext2);
545 return Standard_False;
548 return Standard_True;
552 Standard_Boolean Blend_Walking::Complete(Blend_Function& Func,
553 Blend_FuncInv& FuncInv,
554 const Standard_Real Pmin)
556 if (!done) {throw StdFail_NotDone();}
557 if (iscomplete) {return Standard_True;}
560 previousP = line->Point(1);
563 previousP = line->Point(line->NbPoints());
568 param = previousP.Parameter();
569 previousP.ParametersOnS1(sol(1),sol(2));
570 previousP.ParametersOnS2(sol(3),sol(4));
572 InternalPerform(Func,FuncInv,Pmin);
574 iscomplete = Standard_True;
575 return Standard_True;
578 void Blend_Walking::ClassificationOnS1(const Standard_Boolean C)
583 void Blend_Walking::ClassificationOnS2(const Standard_Boolean C)
588 void Blend_Walking::Check2d(const Standard_Boolean C)
593 void Blend_Walking::Check(const Standard_Boolean C)