Back to home page

EIC code displayed by LXR

 
 

    


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 }