Warning, /include/opencascade/Blend_Walking_1.gxx is written in an unsupported language. File is not indexed.
0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014
0015 Blend_Walking::Blend_Walking(const TheSurface& Surf1,
0016 const TheSurface& Surf2,
0017 const Handle(TheTopolTool)& Domain1,
0018 const Handle(TheTopolTool)& Domain2,
0019 const Handle(ChFiDS_ElSpine)& HGuide):
0020 sol(1,4),surf1(Surf1),surf2(Surf2),
0021 ToCorrectOnRst1(Standard_False),ToCorrectOnRst2(Standard_False),
0022 done(Standard_False),
0023 clasonS1(Standard_True),clasonS2(Standard_True),
0024 check2d(Standard_True),check(Standard_True),
0025 twistflag1(Standard_False),twistflag2(Standard_False)
0026
0027 {
0028 domain1 = Domain1;
0029 domain2 = Domain2;
0030 recdomain1 = Domain1;
0031 recdomain2 = Domain2;
0032 hguide = HGuide;
0033 }
0034
0035 void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1,
0036 const Handle(TheTopolTool)& Domain2)
0037 {
0038 recdomain1 = Domain1;
0039 recdomain2 = Domain2;
0040 }
0041
0042 void Blend_Walking::AddSingularPoint(const Blend_Point& P)
0043 {
0044 if (jalons.Length() == 0) {
0045 jalons.Append(P);
0046 }
0047 else {
0048 Standard_Integer ii, jj;
0049 Standard_Real tp = P.Parameter(),
0050 ti=jalons.First().Parameter();
0051 for (jj=1, ii=1; ii<=jalons.Length() && tp>ti; ii++) {
0052 jj = ii;
0053 ti = jalons.Value(jj).Parameter();
0054 }
0055 if (tp > ti) jalons.InsertAfter(jj, P);
0056 else jalons.InsertBefore(jj, P);
0057 }
0058 }
0059
0060 void Blend_Walking::Perform(Blend_Function& Func,
0061 Blend_FuncInv& FuncInv,
0062 const Standard_Real Pdep,
0063 const Standard_Real Pmax,
0064 const Standard_Real MaxStep,
0065 const Standard_Real Tol3d,
0066 const Standard_Real TolGuide,
0067 const math_Vector& ParDep,
0068 const Standard_Real Fleche,
0069 const Standard_Boolean Appro)
0070 {
0071
0072 done = Standard_False;
0073 iscomplete = Standard_False;
0074 comptra = Standard_False;
0075 Standard_Boolean doextremities = 1;
0076 if(line.IsNull()) line = new TheLine ();
0077 else {line->Clear();doextremities = 0;}
0078 tolpoint3d = Tol3d;
0079 tolgui = Abs(TolGuide);
0080 fleche = Abs(Fleche);
0081 rebrou = Standard_False;
0082 pasmax = Abs(MaxStep);
0083 if (Pmax-Pdep >= 0.) {
0084 sens = 1.;
0085 }
0086 else {
0087 sens = -1.;
0088 }
0089
0090 Blend_Status State;
0091
0092 param = Pdep;
0093 Func.Set(param);
0094
0095 if (Appro) {
0096
0097 TopAbs_State situ1,situ2;
0098 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
0099 Func.GetTolerance(tolerance,tolpoint3d);
0100 Func.GetBounds(infbound,supbound);
0101 math_FunctionSetRoot rsnld(Func,tolerance,30);
0102
0103 rsnld.Perform(Func,ParDep,infbound,supbound);
0104
0105 if (!rsnld.IsDone()) {
0106 return;
0107 }
0108 rsnld.Root(sol);
0109
0110 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
0111 Min(tolerance(1),tolerance(2)),0);
0112 else situ1 = TopAbs_IN;
0113 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
0114 Min(tolerance(3),tolerance(4)),0);
0115 else situ2 = TopAbs_IN;
0116
0117 if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) {
0118 return;
0119 }
0120 }
0121 else {
0122 sol = ParDep;
0123 }
0124
0125 #ifdef OCCT_DEBUG
0126 sectioncalculee = 0;
0127 #endif
0128 State = TestArret(Func, Blend_OK, Standard_False);
0129 if (State!=Blend_OK) {
0130 return;
0131 }
0132 #ifdef OCCT_DEBUG
0133 if (Blend_GettraceDRAWSECT()){
0134 Drawsect(surf1,surf2,sol,param,Func);
0135 }
0136 nbcomputedsection = 1;
0137 #endif
0138 // Mettre a jour la ligne.
0139 //Correct first parameter if needed
0140 if (ToCorrectOnRst1 || ToCorrectOnRst2)
0141 previousP.SetParameter(CorrectedParam);
0142 line->Append(previousP);
0143
0144 if(doextremities){
0145 TheExtremity ptf1 (previousP.PointOnS1(),
0146 sol(1),sol(2),tolpoint3d);
0147 TheExtremity ptf2 (previousP.PointOnS2(),
0148 sol(3),sol(4),tolpoint3d);
0149 if (!previousP.IsTangencyPoint()) {
0150 ptf1.SetTangent(previousP.TangentOnS1());
0151 ptf2.SetTangent(previousP.TangentOnS2());
0152 }
0153
0154 if (sens>0.) {
0155 line->SetStartPoints(ptf1, ptf2);
0156 }
0157 else {
0158 line->SetEndPoints(ptf1, ptf2);
0159 }
0160 }
0161
0162 InternalPerform(Func,FuncInv,Pmax);
0163
0164 done = Standard_True;
0165 }
0166
0167
0168 Standard_Boolean Blend_Walking::PerformFirstSection(Blend_Function& Func,
0169 const Standard_Real Pdep,
0170 math_Vector& ParDep,
0171 const Standard_Real Tol3d,
0172 const Standard_Real TolGuide,
0173 TopAbs_State& Pos1,
0174 TopAbs_State& Pos2)
0175 {
0176 iscomplete = Standard_False;
0177 comptra = Standard_False;
0178 line = new TheLine ();
0179 tolpoint3d = Tol3d;
0180 tolgui = Abs(TolGuide);
0181
0182 Pos1 = Pos2 = TopAbs_UNKNOWN;
0183
0184 param = Pdep;
0185 Func.Set(param);
0186
0187 math_Vector tolerance(1, 4),infbound(1, 4),supbound(1, 4);
0188 Func.GetTolerance(tolerance, tolpoint3d);
0189 Func.GetBounds(infbound, supbound);
0190 math_FunctionSetRoot rsnld(Func, tolerance, 30);
0191
0192 rsnld.Perform(Func, ParDep, infbound, supbound);
0193
0194 if (!rsnld.IsDone())
0195 {
0196 return Standard_False;
0197 }
0198 rsnld.Root(sol);
0199 ParDep = sol;
0200 Pos1 = domain1->Classify(gp_Pnt2d(sol(1), sol(2)), Min(tolerance(1), tolerance(2)), 0);
0201 Pos2 = domain2->Classify(gp_Pnt2d(sol(3), sol(4)), Min(tolerance(3), tolerance(4)), 0);
0202 if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN)
0203 {
0204 return Standard_False;
0205 }
0206
0207 TestArret(Func, Blend_OK, Standard_False);
0208 #ifdef OCCT_DEBUG
0209 if (Blend_GettraceDRAWSECT())
0210 {
0211 Drawsect(surf1, surf2, sol, param, Func);
0212 }
0213 #endif
0214 return Standard_True;
0215 }
0216
0217
0218 Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func,
0219 Blend_FuncInv& FuncInv,
0220 const Standard_Real Pdep,
0221 const Standard_Real Pmax,
0222 const math_Vector& ParDep,
0223 const Standard_Real Tol3d,
0224 const Standard_Real TolGuide,
0225 const Standard_Boolean RecOnS1,
0226 const Standard_Boolean RecOnS2,
0227 Standard_Real& Psol,
0228 math_Vector& ParSol)
0229
0230 {
0231 iscomplete = Standard_False;
0232 comptra = Standard_False;
0233 line = new TheLine ();
0234
0235 Standard_Real w1, w2, extrapol;
0236 Standard_Boolean recad1, recad2;
0237
0238 tolpoint3d = Tol3d;
0239 tolgui = Abs(TolGuide);
0240 if (Pmax - Pdep >= 0.0)
0241 {
0242 sens = 1.;
0243 }
0244 else
0245 {
0246 sens = -1.;
0247 }
0248 extrapol = Abs(Pmax - Pdep) / 50.0; // 2%
0249
0250 Blend_Status State;
0251
0252 param = Pdep;
0253 Func.Set(param);
0254
0255 math_Vector tolerance(1, 4),infbound(1, 4),supbound(1, 4);
0256 math_Vector solrst1(1, 4),solrst2(1, 4);
0257 TheExtremity Ext1, Ext2;
0258 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
0259 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False;
0260 TheVertex Vtx1, Vtx2;
0261 gp_Pnt2d p2d;
0262 Standard_Real CorrectedU = 0., CorrectedV = 0.;
0263 gp_Pnt CorrectedPnt;
0264
0265 Func.GetTolerance(tolerance, tolpoint3d);
0266 Func.GetBounds(infbound, supbound);
0267 math_FunctionSetRoot rsnld(Func, tolerance, 30);
0268
0269 rsnld.Perform(Func, ParDep, infbound, supbound);
0270
0271 if (!rsnld.IsDone())
0272 {
0273 return Standard_False;
0274 }
0275 rsnld.Root(sol);
0276
0277 w1 = w2 = Pmax;
0278
0279 recad1 = RecOnS1 && Recadre(FuncInv, Standard_True, sol, solrst1,
0280 Index1, Isvtx1, Vtx1, extrapol);
0281 if (recad1)
0282 {
0283 w1 = solrst1(2);
0284 }
0285
0286 recad2 = RecOnS2 && Recadre(FuncInv, Standard_False, sol, solrst2,
0287 Index2, Isvtx2, Vtx2, extrapol);
0288 if (recad2)
0289 {
0290 w2 = solrst2(2);
0291 }
0292
0293 if (!recad1 && !recad2)
0294 {
0295 return Standard_False;
0296 }
0297
0298 if (recad1 && recad2)
0299 {
0300 if (Abs(w1 - w2) <= tolgui)
0301 {
0302 //sol sur 1 et 2 a la fois
0303 State = Blend_OnRst12;
0304 param = w1;
0305 ParSol(1) = solrst2(3);
0306 ParSol(2) = solrst2(4);
0307 ParSol(3) = solrst1(3);
0308 ParSol(4) = solrst1(4);
0309 }
0310 else if (sens * (w2 - w1) < 0.0)
0311 { // on garde le plus grand
0312 //sol sur 1
0313 State = Blend_OnRst1;
0314 param = w1;
0315
0316 recdomain1->Init();
0317 nbarc = 1;
0318 while (nbarc < Index1)
0319 {
0320 nbarc++;
0321 recdomain1->Next();
0322 }
0323 p2d = TheArcTool::Value(recdomain1->Value(), solrst1(1));
0324 ParSol(1) = p2d.X();
0325 ParSol(2) = p2d.Y();
0326 ParSol(3) = solrst1(3);
0327 ParSol(4) = solrst1(4);
0328
0329 }
0330 else
0331 {
0332 //sol sur 2
0333 State = Blend_OnRst2;
0334 param = w2;
0335
0336 recdomain2->Init();
0337 nbarc = 1;
0338 while (nbarc < Index2)
0339 {
0340 nbarc++;
0341 recdomain2->Next();
0342 }
0343 p2d = TheArcTool::Value(recdomain2->Value(), solrst2(1));
0344 ParSol(1) = solrst2(3);
0345 ParSol(2) = solrst2(4);
0346 ParSol(3) = p2d.X();
0347 ParSol(4) = p2d.Y();
0348 }
0349 }
0350 else if (recad1)
0351 {
0352 // sol sur 1
0353 State = Blend_OnRst1;
0354 param = w1;
0355 recdomain1->Init();
0356 nbarc = 1;
0357 while (nbarc < Index1)
0358 {
0359 nbarc++;
0360 recdomain1->Next();
0361 }
0362 p2d = TheArcTool::Value(recdomain1->Value(), solrst1(1));
0363 ParSol(1) = p2d.X();
0364 ParSol(2) = p2d.Y();
0365 ParSol(3) = solrst1(3);
0366 ParSol(4) = solrst1(4);
0367 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,ParSol(1),ParSol(2));
0368 if (CorrectExtremityOnOneRst(1, ParSol(3), ParSol(4), param, thePntOnRst,
0369 CorrectedU,CorrectedV,CorrectedPnt,CorrectedParam))
0370 ToCorrectOnRst1 = Standard_True;
0371 }
0372 else
0373 { //if (recad2) {
0374 //sol sur 2
0375 State = Blend_OnRst2;
0376 param = w2;
0377
0378 recdomain2->Init();
0379 nbarc = 1;
0380 while (nbarc < Index2)
0381 {
0382 nbarc++;
0383 recdomain2->Next();
0384 }
0385 p2d = TheArcTool::Value(recdomain2->Value(), solrst2(1));
0386 ParSol(1) = solrst2(3);
0387 ParSol(2) = solrst2(4);
0388 ParSol(3) = p2d.X();
0389 ParSol(4) = p2d.Y();
0390 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,ParSol(3),ParSol(4));
0391 if (CorrectExtremityOnOneRst(2, ParSol(1), ParSol(2), param, thePntOnRst,
0392 CorrectedU,CorrectedV,CorrectedPnt,CorrectedParam))
0393 ToCorrectOnRst2 = Standard_True;
0394 }
0395
0396 Psol = param;
0397 sol = ParSol;
0398 Func.Set(param);
0399 State = TestArret(Func, State, Standard_False);
0400 switch (State)
0401 {
0402 case Blend_OnRst1:
0403 {
0404 #ifdef OCCT_DEBUG
0405 if (Blend_GettraceDRAWSECT())
0406 {
0407 Drawsect(surf1, surf2, sol, param, Func);
0408 }
0409 #endif
0410 MakeExtremity(Ext1, Standard_True, Index1, solrst1(1), Isvtx1, Vtx1);
0411 if (ToCorrectOnRst1)
0412 Ext2.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolpoint3d);
0413 else
0414 Ext2.SetValue(previousP.PointOnS2(), sol(3), sol(4), tolpoint3d);
0415 }
0416 break;
0417
0418 case Blend_OnRst2:
0419 {
0420 #ifdef OCCT_DEBUG
0421 if (Blend_GettraceDRAWSECT())
0422 {
0423 Drawsect(surf1, surf2, sol, param, Func);
0424 }
0425 #endif
0426 if (ToCorrectOnRst2)
0427 Ext1.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolpoint3d);
0428 else
0429 Ext1.SetValue(previousP.PointOnS1(), sol(1), sol(2), tolpoint3d);
0430 MakeExtremity(Ext2, Standard_False, Index2, solrst2(1), Isvtx2, Vtx2);
0431 }
0432 break;
0433
0434 case Blend_OnRst12 :
0435 {
0436 #ifdef OCCT_DEBUG
0437 if (Blend_GettraceDRAWSECT())
0438 {
0439 Drawsect(surf1, surf2, sol, param, Func);
0440 }
0441 #endif
0442 MakeExtremity(Ext1, Standard_True , Index1, solrst1(1), Isvtx1, Vtx1);
0443 MakeExtremity(Ext2, Standard_False, Index2, solrst2(1), Isvtx2, Vtx2);
0444 }
0445 break;
0446 default:
0447 {
0448 throw Standard_Failure("Blend_Walking::PerformFirstSection : echec");
0449 }
0450 }
0451 if (sens < 0.0)
0452 {
0453 line->SetEndPoints(Ext1, Ext2);
0454 }
0455 else
0456 {
0457 line->SetStartPoints(Ext1, Ext2);
0458 }
0459 return Standard_True;
0460 }
0461
0462
0463
0464 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
0465 Blend_FuncInv& FuncInv,
0466 const Standard_Real P)
0467 {
0468 if (!done) {throw StdFail_NotDone();}
0469 const Blend_Point& firstBP = line->Point(1);
0470 const Blend_Point& lastBP = line->Point(line->NbPoints());
0471
0472 if (P < firstBP.Parameter()){
0473 sens = -1.;
0474 previousP = firstBP;
0475 }
0476 else if(P > lastBP.Parameter()){
0477 sens = 1.;
0478 previousP = lastBP;
0479 }
0480
0481 param = previousP.Parameter();
0482 previousP.ParametersOnS1(sol(1),sol(2));
0483 previousP.ParametersOnS2(sol(3),sol(4));
0484
0485 InternalPerform(Func,FuncInv,P);
0486 return Standard_True;
0487 }
0488
0489
0490 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
0491 Blend_FuncInv& FuncInv,
0492 const Standard_Real P,
0493 const Standard_Boolean OnS1)
0494 {
0495 if (!done) {throw StdFail_NotDone();}
0496 TheExtremity Ext1,Ext2;
0497 if (sens < 0.) {
0498 Ext1 = line->StartPointOnFirst();
0499 Ext2 = line->StartPointOnSecond();
0500 if ((OnS1 && Ext1.NbPointOnRst() == 0) ||
0501 (!OnS1 && Ext2.NbPointOnRst() == 0)) {
0502 return Standard_False;
0503 }
0504 previousP = line->Point(1);
0505
0506
0507 }
0508 else {
0509 Ext1 = line->EndPointOnFirst();
0510 Ext2 = line->EndPointOnSecond();
0511 if ((OnS1 && Ext1.NbPointOnRst() == 0) ||
0512 (!OnS1 && Ext2.NbPointOnRst() == 0)) {
0513 return Standard_False;
0514 }
0515 previousP = line->Point(line->NbPoints());
0516 }
0517
0518 Standard_Integer length = line->NbPoints();
0519 param = previousP.Parameter();
0520 previousP.ParametersOnS1(sol(1),sol(2));
0521 previousP.ParametersOnS2(sol(3),sol(4));
0522
0523 if(OnS1) clasonS1 = Standard_False;
0524 else clasonS2 = Standard_False;
0525
0526 InternalPerform(Func,FuncInv,P);
0527
0528 clasonS1 = Standard_True;
0529 clasonS2 = Standard_True;
0530
0531 Standard_Integer newlength = line->NbPoints();
0532 if (sens <0.) {
0533 if ((OnS1 && line->StartPointOnSecond().NbPointOnRst() == 0) ||
0534 (!OnS1 && line->StartPointOnFirst().NbPointOnRst() == 0)) {
0535 line->Remove(1,newlength-length);
0536 line->SetStartPoints(Ext1,Ext2);
0537 return Standard_False;
0538 }
0539 }
0540 else {
0541 if ((OnS1 && line->EndPointOnSecond().NbPointOnRst() == 0) ||
0542 (!OnS1 && line->EndPointOnFirst().NbPointOnRst() == 0)) {
0543 line->Remove(length,newlength);
0544 line->SetEndPoints(Ext1,Ext2);
0545 return Standard_False;
0546 }
0547 }
0548 return Standard_True;
0549 }
0550
0551
0552 Standard_Boolean Blend_Walking::Complete(Blend_Function& Func,
0553 Blend_FuncInv& FuncInv,
0554 const Standard_Real Pmin)
0555 {
0556 if (!done) {throw StdFail_NotDone();}
0557 if (iscomplete) {return Standard_True;}
0558
0559 if (sens >0.) {
0560 previousP = line->Point(1);
0561 }
0562 else {
0563 previousP = line->Point(line->NbPoints());
0564 }
0565
0566 sens = -sens;
0567
0568 param = previousP.Parameter();
0569 previousP.ParametersOnS1(sol(1),sol(2));
0570 previousP.ParametersOnS2(sol(3),sol(4));
0571
0572 InternalPerform(Func,FuncInv,Pmin);
0573
0574 iscomplete = Standard_True;
0575 return Standard_True;
0576 }
0577
0578 void Blend_Walking::ClassificationOnS1(const Standard_Boolean C)
0579 {
0580 clasonS1 = C;
0581 }
0582
0583 void Blend_Walking::ClassificationOnS2(const Standard_Boolean C)
0584 {
0585 clasonS2 = C;
0586 }
0587
0588 void Blend_Walking::Check2d(const Standard_Boolean C)
0589 {
0590 check2d = C;
0591 }
0592
0593 void Blend_Walking::Check(const Standard_Boolean C)
0594 {
0595 check = C;
0596 }