1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
19 Blend_Walking::Blend_Walking(const TheSurface& Surf1,
20 const TheSurface& Surf2,
21 const Handle(TheTopolTool)& Domain1,
22 const Handle(TheTopolTool)& Domain2):
23 sol(1,4),surf1(Surf1),surf2(Surf2),
25 clasonS1(Standard_True),clasonS2(Standard_True),
26 check2d(Standard_True),check(Standard_True),
27 twistflag1(Standard_False),twistflag2(Standard_False)
36 void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1,
37 const Handle(TheTopolTool)& Domain2)
43 void Blend_Walking::AddSingularPoint(const Blend_Point& P)
45 if (jalons.Length() == 0) {
49 Standard_Integer ii, jj;
50 Standard_Real tp = P.Parameter(),
51 ti=jalons.First().Parameter();
52 for (jj=1, ii=1; ii<=jalons.Length() && tp>ti; ii++) {
54 ti = jalons.Value(jj).Parameter();
56 if (tp > ti) jalons.InsertAfter(jj, P);
57 else jalons.InsertBefore(jj, P);
61 void Blend_Walking::Perform(Blend_Function& Func,
62 Blend_FuncInv& FuncInv,
63 const Standard_Real Pdep,
64 const Standard_Real Pmax,
65 const Standard_Real MaxStep,
66 const Standard_Real TolGuide,
67 const math_Vector& ParDep,
68 const Standard_Real Tolesp,
69 const Standard_Real Fleche,
70 const Standard_Boolean Appro)
73 done = Standard_False;
74 iscomplete = Standard_False;
75 comptra = Standard_False;
76 Standard_Boolean doextremities = 1;
77 if(line.IsNull()) line = new TheLine ();
78 else {line->Clear();doextremities = 0;}
80 tolgui = Abs(TolGuide);
82 rebrou = Standard_False;
83 pasmax = Abs(MaxStep);
84 if (Pmax-Pdep >= 0.) {
92 TheExtremity ptf1,ptf2;
99 TopAbs_State situ1,situ2;
100 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
101 Func.GetTolerance(tolerance,tolesp);
102 Func.GetBounds(infbound,supbound);
103 math_FunctionSetRoot rsnld(Func,tolerance,30);
105 rsnld.Perform(Func,ParDep,infbound,supbound);
107 if (!rsnld.IsDone()) {
112 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
113 Min(tolerance(1),tolerance(2)),0);
114 else situ1 = TopAbs_IN;
115 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
116 Min(tolerance(3),tolerance(4)),0);
117 else situ2 = TopAbs_IN;
119 if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) {
130 State = TestArret(Func, Blend_OK, Standard_False);
131 if (State!=Blend_OK) {
135 if (Blend_GettraceDRAWSECT()){
136 Drawsect(surf1,surf2,sol,param,Func);
138 nbcomputedsection = 1;
140 // Mettre a jour la ligne.
141 line->Append(previousP);
144 TheExtremity ptf1 (previousP.PointOnS1(),
145 sol(1),sol(2),tolesp);
146 TheExtremity ptf2 (previousP.PointOnS2(),
147 sol(3),sol(4),tolesp);
148 if (!previousP.IsTangencyPoint()) {
149 ptf1.SetTangent(previousP.TangentOnS1());
150 ptf2.SetTangent(previousP.TangentOnS2());
154 line->SetStartPoints(ptf1, ptf2);
157 line->SetEndPoints(ptf1, ptf2);
161 InternalPerform(Func,FuncInv,Pmax);
164 // cout <<"Perform : "<<nbcomputedsection<<" sections calculees"<<endl;
165 // cout <<line->NbPoints()<<" sections gardees"<<endl;
168 done = Standard_True;
172 Standard_Boolean Blend_Walking::PerformFirstSection
173 (Blend_Function& Func,
174 const Standard_Real Pdep,
176 const Standard_Real Tolesp,
177 const Standard_Real TolGuide,
181 iscomplete = Standard_False;
182 comptra = Standard_False;
183 line = new TheLine ();
184 tolesp = Abs(Tolesp);
185 tolgui = Abs(TolGuide);
187 Pos1 = Pos2 = TopAbs_UNKNOWN;
194 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
195 Func.GetTolerance(tolerance,tolesp);
196 Func.GetBounds(infbound,supbound);
197 math_FunctionSetRoot rsnld(Func,tolerance,30);
199 rsnld.Perform(Func,ParDep,infbound,supbound);
201 if (!rsnld.IsDone()) {
202 return Standard_False;
206 Pos1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
207 Min(tolerance(1),tolerance(2)),0);
208 Pos2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
209 Min(tolerance(3),tolerance(4)),0);
210 if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN) {
211 return Standard_False;
214 State = TestArret(Func, Blend_OK, Standard_False);
216 if (Blend_GettraceDRAWSECT()){
217 Drawsect(surf1,surf2,sol,param,Func);
220 return Standard_True;
224 Standard_Boolean Blend_Walking::PerformFirstSection
225 (Blend_Function& Func,
226 Blend_FuncInv& FuncInv,
227 const Standard_Real Pdep,
228 const Standard_Real Pmax,
229 const math_Vector& ParDep,
230 const Standard_Real Tolesp,
231 const Standard_Real TolGuide,
232 const Standard_Boolean RecOnS1,
233 const Standard_Boolean RecOnS2,
238 iscomplete = Standard_False;
239 comptra = Standard_False;
240 line = new TheLine ();
242 Standard_Real w1,w2, extrapol;
243 Standard_Boolean recad1,recad2;
245 tolesp = Abs(Tolesp);
246 tolgui = Abs(TolGuide);
247 if (Pmax-Pdep >= 0.) {
253 extrapol = Abs(Pmax-Pdep)/50; // 2%
260 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
261 math_Vector solrst1(1,4),solrst2(1,4);
262 TheExtremity Ext1,Ext2;
263 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
264 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False;
268 Func.GetTolerance(tolerance,tolesp);
269 Func.GetBounds(infbound,supbound);
270 math_FunctionSetRoot rsnld(Func,tolerance,30);
272 rsnld.Perform(Func,ParDep,infbound,supbound);
274 if (!rsnld.IsDone()) {
275 return Standard_False;
281 recad1 = RecOnS1 && Recadre(FuncInv,Standard_True,
282 sol,solrst1,Index1,Isvtx1,Vtx1, extrapol);
287 recad2 = RecOnS2 && Recadre(FuncInv,Standard_False,
288 sol,solrst2,Index2,Isvtx2,Vtx2, extrapol);
293 if (!recad1 && !recad2) {
294 return Standard_False;
297 if (recad1 && recad2) {
298 if (Abs(w1-w2) <= tolgui) {
299 //sol sur 1 et 2 a la fois
300 State = Blend_OnRst12;
302 ParSol(1) = solrst2(3);
303 ParSol(2) = solrst2(4);
304 ParSol(3) = solrst1(3);
305 ParSol(4) = solrst1(4);
307 else if (sens*(w2-w1) < 0.) { // on garde le plus grand
309 State = Blend_OnRst1;
314 while (nbarc < Index1) {
318 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
321 ParSol(3) = solrst1(3);
322 ParSol(4) = solrst1(4);
327 State = Blend_OnRst2;
332 while (nbarc < Index2) {
336 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
337 ParSol(1) = solrst2(3);
338 ParSol(2) = solrst2(4);
345 State = Blend_OnRst1;
349 while (nbarc < Index1) {
353 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
356 ParSol(3) = solrst1(3);
357 ParSol(4) = solrst1(4);
359 else { //if (recad2) {
361 State = Blend_OnRst2;
366 while (nbarc < Index2) {
370 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
371 ParSol(1) = solrst2(3);
372 ParSol(2) = solrst2(4);
380 State = TestArret(Func, State, Standard_False);
385 if (Blend_GettraceDRAWSECT()){
386 Drawsect(surf1,surf2,sol,param,Func);
389 MakeExtremity(Ext1,Standard_True,Index1,
390 solrst1(1),Isvtx1,Vtx1);
391 Ext2.SetValue(previousP.PointOnS2(),
392 sol(3),sol(4),tolesp);
399 if (Blend_GettraceDRAWSECT()){
400 Drawsect(surf1,surf2,sol,param,Func);
403 Ext1.SetValue(previousP.PointOnS1(),
404 sol(1),sol(2),tolesp);
405 MakeExtremity(Ext2,Standard_False,Index2,
406 solrst2(1),Isvtx2,Vtx2);
413 if (Blend_GettraceDRAWSECT()){
414 Drawsect(surf1,surf2,sol,param,Func);
417 MakeExtremity(Ext1,Standard_True,Index1,
418 solrst1(1),Isvtx1,Vtx1);
419 MakeExtremity(Ext2,Standard_False,Index2,
420 solrst2(1),Isvtx2,Vtx2);
425 Standard_Failure::Raise("Blend_Walking::PerformFirstSection : echec");
429 line->SetEndPoints(Ext1,Ext2);
432 line->SetStartPoints(Ext1,Ext2);
434 return Standard_True;
439 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
440 Blend_FuncInv& FuncInv,
441 const Standard_Real P)
443 if (!done) {StdFail_NotDone::Raise();}
444 const Blend_Point& firstBP = line->Point(1);
445 const Blend_Point& lastBP = line->Point(line->NbPoints());
447 if (P < firstBP.Parameter()){
451 else if(P > lastBP.Parameter()){
456 param = previousP.Parameter();
457 previousP.ParametersOnS1(sol(1),sol(2));
458 previousP.ParametersOnS2(sol(3),sol(4));
460 InternalPerform(Func,FuncInv,P);
461 return Standard_True;
465 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
466 Blend_FuncInv& FuncInv,
467 const Standard_Real P,
468 const Standard_Boolean OnS1)
470 if (!done) {StdFail_NotDone::Raise();}
471 TheExtremity Ext1,Ext2;
473 Ext1 = line->StartPointOnFirst();
474 Ext2 = line->StartPointOnSecond();
475 if (OnS1 && Ext1.NbPointOnRst() == 0 ||
476 !OnS1 && Ext2.NbPointOnRst() == 0) {
477 return Standard_False;
479 previousP = line->Point(1);
484 Ext1 = line->EndPointOnFirst();
485 Ext2 = line->EndPointOnSecond();
486 if (OnS1 && Ext1.NbPointOnRst() == 0 ||
487 !OnS1 && Ext2.NbPointOnRst() == 0) {
488 return Standard_False;
490 previousP = line->Point(line->NbPoints());
493 Standard_Integer length = line->NbPoints();
494 param = previousP.Parameter();
495 previousP.ParametersOnS1(sol(1),sol(2));
496 previousP.ParametersOnS2(sol(3),sol(4));
498 if(OnS1) clasonS1 = Standard_False;
499 else clasonS2 = Standard_False;
501 InternalPerform(Func,FuncInv,P);
503 clasonS1 = Standard_True;
504 clasonS2 = Standard_True;
506 Standard_Integer newlength = line->NbPoints();
508 if (OnS1 && line->StartPointOnSecond().NbPointOnRst() == 0 ||
509 !OnS1 && line->StartPointOnFirst().NbPointOnRst() == 0) {
510 line->Remove(1,newlength-length);
511 line->SetStartPoints(Ext1,Ext2);
512 return Standard_False;
516 if (OnS1 && line->EndPointOnSecond().NbPointOnRst() == 0 ||
517 !OnS1 && line->EndPointOnFirst().NbPointOnRst() == 0) {
518 line->Remove(length,newlength);
519 line->SetEndPoints(Ext1,Ext2);
520 return Standard_False;
523 return Standard_True;
527 Standard_Boolean Blend_Walking::Complete(Blend_Function& Func,
528 Blend_FuncInv& FuncInv,
529 const Standard_Real Pmin)
531 if (!done) {StdFail_NotDone::Raise();}
532 if (iscomplete) {return Standard_True;}
535 previousP = line->Point(1);
538 previousP = line->Point(line->NbPoints());
543 param = previousP.Parameter();
544 previousP.ParametersOnS1(sol(1),sol(2));
545 previousP.ParametersOnS2(sol(3),sol(4));
547 InternalPerform(Func,FuncInv,Pmin);
550 // cout <<"Complete : "<<nbcomputedsection<<" sections calculees"<<endl;
551 // cout <<line->NbPoints()<<" sections gardees"<<endl;
554 iscomplete = Standard_True;
555 return Standard_True;
558 void Blend_Walking::ClassificationOnS1(const Standard_Boolean C)
563 void Blend_Walking::ClassificationOnS2(const Standard_Boolean C)
568 void Blend_Walking::Check2d(const Standard_Boolean C)
573 void Blend_Walking::Check(const Standard_Boolean C)