Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/Blend_Walking_3.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 //26-04-1997 modified by pmn : Initialisation plus fine de la resolution
0016 
0017 Standard_Integer Blend_Walking::ArcToRecadre(const Standard_Boolean OnFirst,
0018                                              const math_Vector& theSol,
0019                                              const Standard_Integer PrevIndex,
0020                                              gp_Pnt2d& lastpt2d,
0021                                              gp_Pnt2d& pt2d,
0022                                              Standard_Real& ponarc)
0023 {
0024   Standard_Integer IndexSol = 0,  nbarc = 0;
0025   Standard_Boolean ok = Standard_False;
0026   Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
0027   Standard_Real distmin = RealLast();
0028   Standard_Real uprev = 0.,vprev = 0., prm = 0., dist = 0.;
0029   Handle(TheTopolTool) Iter;
0030 
0031   if (OnFirst) {
0032     if(byinter) previousP.ParametersOnS1(uprev,vprev);
0033     pt2d.SetCoord(theSol(1),theSol(2));
0034     Iter = recdomain1;
0035   }
0036   else {
0037     if(byinter) previousP.ParametersOnS2(uprev,vprev);
0038     pt2d.SetCoord(theSol(3),theSol(4));
0039     Iter = recdomain2;
0040   }
0041   lastpt2d.SetCoord(uprev,vprev);
0042   Iter->Init();
0043   while (Iter->More()) {
0044     nbarc++; ok = 0;
0045     if (OnFirst) {
0046       if(byinter) { 
0047         ok = okinter = TheBlendTool::Inters(pt2d,lastpt2d,
0048                                             surf1,Iter->Value(),prm,dist); 
0049       }
0050       if(!ok) ok = TheBlendTool::Project(pt2d,surf1,Iter->Value(),prm,dist);
0051     }
0052     else {
0053       if(byinter) { 
0054         ok = okinter = TheBlendTool::Inters(pt2d,lastpt2d,
0055                                             surf2,Iter->Value(),prm,dist); 
0056       }
0057       if(!ok) ok = TheBlendTool::Project(pt2d,surf2,Iter->Value(),prm,dist);
0058     }
0059     if (ok && (nbarc != PrevIndex) ) {
0060       if (dist<distmin || okinter) {
0061         distmin = dist;
0062         ponarc = prm;
0063         IndexSol = nbarc;
0064         if(okinter && (PrevIndex==0)) break;
0065       }
0066     }
0067     Iter->Next();
0068   }
0069   return IndexSol;
0070 }
0071 
0072 Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
0073                                         const Standard_Boolean OnFirst,
0074                                         const math_Vector& theSol,
0075                                         math_Vector& solrst,
0076                                         Standard_Integer& Indexsol,
0077                                         Standard_Boolean& IsVtx,
0078                                         TheVertex& Vtx,
0079                                         const Standard_Real Extrap)
0080 
0081 {
0082   Standard_Boolean jalons_Trouve = Standard_False;
0083   Standard_Boolean recadre = Standard_True, ok;
0084   Standard_Boolean byinter = (line->NbPoints() != 0);
0085   Standard_Integer LeJalon = 0;
0086 
0087   Standard_Integer nbarc;
0088   Standard_Real dist,prm,pmin, vtol;
0089   gp_Pnt2d pt2d, lastpt2d;
0090 
0091   math_Vector toler(1,4),infb(1,4),supb(1,4),valsol(1,4);
0092 
0093   Handle(Adaptor2d_Curve2d) thecur;
0094   Handle(TheTopolTool) Iter;
0095 
0096   if (OnFirst) Iter = recdomain1;
0097   else         Iter = recdomain2;
0098 
0099   Indexsol = ArcToRecadre(OnFirst, theSol, 0,
0100                           lastpt2d, pt2d, pmin);
0101   IsVtx = Standard_False;
0102   if (Indexsol == 0) {
0103     return Standard_False;
0104   }
0105 
0106   Iter->Init();
0107   nbarc = 1;
0108   while (nbarc < Indexsol) {
0109     nbarc++;
0110     Iter->Next();
0111   }
0112 
0113   TheArc thearc = Iter->Value();
0114 
0115   if (OnFirst) {
0116     thecur = TheBlendTool::CurveOnSurf(thearc,surf1);
0117   }
0118   else {
0119     thecur = TheBlendTool::CurveOnSurf(thearc,surf2);
0120   }
0121 
0122 // Le probleme a resoudre
0123   FuncInv.Set(OnFirst,thecur);
0124   FuncInv.GetBounds(infb,supb);
0125   infb(2) -= Extrap;
0126   supb(2) += Extrap;
0127   
0128   FuncInv.GetTolerance(toler,0.1 * tolpoint3d);//Il vaut mieux garder un peu de marge
0129   math_FunctionSetRoot rsnld(FuncInv,toler,35);
0130   toler *= 10; // Mais on fait les tests correctements
0131 
0132 // Calcul d'un point d'init
0133   Standard_Real ufirst,ulast;
0134   TheBlendTool::Bounds(thecur, ufirst,ulast);
0135   // Pour aider a trouver les coins singuliers on recadre eventuelement le paramtere
0136   if (Abs(pmin-ufirst) < Abs(ulast-ufirst)/1000) {
0137     pmin = ufirst;
0138   }
0139   if (Abs(pmin-ulast) < Abs(ulast-ufirst)/1000) {
0140     pmin = ulast;
0141   }
0142 
0143   if (byinter) { 
0144     Standard_Real lastParam = previousP.Parameter();
0145     // Verifie que le recadrage n'est pas un jalons
0146     if (jalons.Length()!=0) {
0147       Standard_Real t1, t2, t;
0148       Standard_Boolean Cherche=Standard_True;
0149       Standard_Integer ii;
0150       if (lastParam < param) {
0151         t1 = lastParam; t2 = param;
0152       }
0153       else {
0154         t1 = param; t2 = lastParam;
0155       }
0156       for (ii=1; ii<=jalons.Length() && Cherche; ii++) {
0157         t = jalons.Value(ii).Parameter();
0158         if  (((t1 < t) && (t2 > t)) || (t==param)) {
0159          jalons_Trouve = Standard_True;
0160          LeJalon = ii;
0161          Cherche = Standard_False; //Ne marche que si l'on sort simultanement
0162        }
0163         else Cherche = t < t2; // On s'arrete si t>=t2;
0164       }
0165     }
0166     if (!jalons_Trouve) {
0167       //Initialisation par Interpolation
0168       Standard_Real lambda, u, v;
0169       gp_Pnt2d Pnt, Pnt1, Pnt2;//,  POnC;
0170       thecur->D0(pmin, Pnt);    
0171       if (OnFirst) {
0172         previousP.ParametersOnS2(u,v);
0173         Pnt1.SetCoord(u, v);
0174         Pnt2.SetCoord(theSol(3), theSol(4));
0175       }
0176       else {
0177         previousP.ParametersOnS1(u,v);
0178         Pnt1.SetCoord(u, v);
0179         Pnt2.SetCoord(theSol(1), theSol(2));
0180       }
0181 
0182       lambda = Pnt.Distance(lastpt2d);
0183       if (lambda > 1.e-12) lambda /=  Pnt.Distance(lastpt2d) + Pnt.Distance(pt2d);
0184       else lambda = 0;
0185       solrst(1) = pmin;
0186       solrst(2) = (1-lambda)*lastParam + lambda*param;
0187       solrst(3) = (1-lambda)*Pnt1.X()  + lambda*Pnt2.X();
0188       solrst(4) = (1-lambda)*Pnt1.Y()  + lambda*Pnt2.Y();
0189     }
0190   }
0191   else { // sinon on initialise par le dernier point calcule
0192     solrst(1) = pmin;
0193     solrst(2) = param; 
0194     if (OnFirst) {
0195       solrst(3) = theSol(3);
0196       solrst(4) = theSol(4);
0197     }
0198     else {
0199       solrst(3) = theSol(1);
0200       solrst(4) = theSol(2);
0201     }
0202   }
0203 
0204   if (jalons_Trouve) { // On recupere le jalon
0205     Blend_Point MonJalon;
0206     Standard_Boolean periodic;
0207     Standard_Real uperiod = 0, vperiod = 0;
0208     gp_Pnt2d Pnt;
0209     Standard_Real distaux;
0210     MonJalon = jalons.Value(LeJalon);
0211     solrst(2) =  MonJalon.Parameter();
0212     if (OnFirst) {
0213       MonJalon.ParametersOnS2(solrst(3), solrst(4));
0214       periodic = (surf2->IsUPeriodic() || surf2->IsVPeriodic());
0215     }
0216     else  {
0217        MonJalon.ParametersOnS1(solrst(3), solrst(4));
0218        periodic = (surf1->IsUPeriodic() || surf1->IsVPeriodic());
0219      }
0220 
0221     // Recadrage eventuelle pour le cas periodique
0222     if (periodic) {
0223       Handle(Adaptor3d_Surface) surf;
0224       if (OnFirst) surf = surf2;
0225       else surf = surf1;
0226 
0227       lastpt2d = thecur->Value(pmin);      
0228 
0229       if (surf->IsUPeriodic()) {
0230         uperiod =  surf->UPeriod();
0231         if (solrst(3)-lastpt2d.X() >  uperiod*0.6) solrst(3) -= uperiod;
0232         if (solrst(3)-lastpt2d.X() < -uperiod*0.6) solrst(3) += uperiod;
0233       }
0234       if (surf->IsVPeriodic()) {
0235         vperiod =  surf->VPeriod();
0236         if (solrst(4)-lastpt2d.Y() >  vperiod*0.6) solrst(4) -= vperiod;
0237         if (solrst(4)-lastpt2d.Y() < -vperiod*0.6) solrst(4) += vperiod;
0238       } 
0239     }
0240 
0241     // Pour le parametre sur arc il faut projeter...
0242     pt2d.SetCoord(solrst(3), solrst(4));
0243     Pnt = thecur->Value(ufirst);
0244     dist = pt2d.Distance(Pnt);
0245     solrst(1) = ufirst;
0246     Pnt = thecur->Value(ulast);
0247     distaux = pt2d.Distance(Pnt);
0248     if ( distaux < dist) {
0249       solrst(1) = ulast;
0250       dist = distaux;
0251     }
0252 
0253     if (dist>Precision::PConfusion()) {
0254       prm = pmin;
0255       if (OnFirst) { 
0256         ok = TheBlendTool::Project(pt2d,surf1,thearc,prm,distaux);
0257       }
0258       else {
0259         ok = TheBlendTool::Project(pt2d,surf2,thearc,prm,distaux);
0260       }
0261       if (ok && (pt2d.Distance(thecur->Value(prm)) < dist)) solrst(1) = prm;
0262       else solrst(1) = pmin;
0263     }
0264     // On verifie le jalon
0265     jalons_Trouve = (FuncInv.IsSolution(solrst,tolpoint3d));
0266   }
0267 
0268   if (!jalons_Trouve) {
0269     // Resolution...
0270     rsnld.Perform(FuncInv,solrst,infb,supb);  
0271     if (!rsnld.IsDone()) {
0272 #ifdef OCCT_DEBUG
0273       std::cout << "Walking::Recadre : RSNLD not done " << std::endl;
0274 #endif
0275       recadre = Standard_False;
0276     }
0277     else {
0278       rsnld.Root(solrst);
0279       recadre = FuncInv.IsSolution(solrst,tolpoint3d);
0280     }
0281   }
0282 
0283   // En cas d'echecs, on regarde si un autre arc 
0284   // peut faire l'affaire (cas des sorties a proximite d'un vertex)
0285   dist = (ulast - ufirst)/100;
0286   if ((!recadre) && 
0287       ((Abs(pmin-ulast) < dist) || (Abs(pmin-ufirst) < dist)) ) {
0288 
0289     Indexsol =  ArcToRecadre(OnFirst, theSol, Indexsol,
0290                              lastpt2d, pt2d, pmin);
0291     if (Indexsol == 0) {
0292       return Standard_False;
0293     }
0294 
0295     Iter->Init();
0296     nbarc = 1;
0297     while (nbarc < Indexsol) {
0298       nbarc++;
0299       Iter->Next();
0300     }
0301     thearc = Iter->Value();
0302  
0303     if (OnFirst) {
0304       thecur = TheBlendTool::CurveOnSurf(thearc,surf1);
0305     }
0306     else {
0307       thecur = TheBlendTool::CurveOnSurf(thearc,surf2);
0308     }
0309     solrst(1) = pmin;
0310     // Le probleme a resoudre
0311     FuncInv.Set(OnFirst,thecur);
0312     FuncInv.GetBounds(infb,supb);
0313     FuncInv.GetTolerance(toler,0.1 * tolpoint3d);//Il vaut mieux garder un peu de marge
0314     math_FunctionSetRoot aRsnld(FuncInv,toler,35);
0315     toler *= 10; // Mais on fait les tests correctements
0316     // Resolution...
0317     aRsnld.Perform(FuncInv,solrst,infb,supb);
0318   
0319     if (!aRsnld.IsDone()) {
0320 #ifdef OCCT_DEBUG
0321       std::cout << "Walking::Recadre : RSNLD not done " << std::endl;
0322 #endif
0323       recadre = Standard_False;
0324     }
0325     else {
0326       aRsnld.Root(solrst);
0327       recadre = FuncInv.IsSolution(solrst,tolpoint3d);
0328     }
0329   }
0330 
0331   if (recadre) {
0332     // Classification topologique  
0333     if (OnFirst) {
0334       thecur = TheBlendTool::CurveOnSurf(thearc,surf1);
0335     }
0336     else {
0337       thecur = TheBlendTool::CurveOnSurf(thearc,surf2);
0338     }
0339     TheBlendTool::Bounds(thecur, ufirst,ulast);    
0340 
0341     Iter->Initialize(thearc);
0342     Iter->InitVertexIterator();
0343     IsVtx = !Iter->MoreVertex();
0344     while (!IsVtx) {
0345       Vtx = Iter->Vertex();
0346       vtol = 0.4*Abs(ulast-ufirst); // Un majorant de la tolerance
0347       if (vtol > Max(TheBlendTool::Tolerance(Vtx,thearc), toler(1)))
0348         vtol = Max(TheBlendTool::Tolerance(Vtx,thearc), toler(1));
0349       if (Abs(TheBlendTool::Parameter(Vtx,thearc)-solrst(1)) <= vtol) {
0350         IsVtx = Standard_True; // On est dans la boule du vertex ou 
0351                                // le vertex est dans la "boule" du recadrage
0352       }
0353       else {
0354         Iter->NextVertex();
0355         IsVtx = !Iter->MoreVertex();
0356       }
0357     }
0358     if (!Iter->MoreVertex()) {
0359       IsVtx = Standard_False;
0360     }
0361     return Standard_True;
0362   }
0363   return Standard_False;
0364 }
0365 
0366 
0367 void Blend_Walking::Transition(const Standard_Boolean OnFirst,
0368                                const TheArc& A,
0369                                const Standard_Real Param,
0370                                IntSurf_Transition& TLine,
0371                                IntSurf_Transition& TArc)
0372 {
0373   Standard_Boolean computetranstionaveclacorde = 0;
0374   gp_Vec tgline;
0375   Blend_Point prevprev;
0376 
0377   if(previousP.IsTangencyPoint()){
0378     if(line->NbPoints() < 2) return;
0379     computetranstionaveclacorde = 1;
0380     if(sens < 0){
0381       prevprev = line->Point(2);
0382     }
0383     else {
0384       prevprev = line->Point(line->NbPoints() - 1);
0385     }
0386   }
0387   gp_Pnt2d p2d;
0388   gp_Vec2d dp2d;
0389 
0390   gp_Pnt pbid;
0391   gp_Vec d1u,d1v,normale,tgrst;
0392   gp_Dir thenormal;
0393   CSLib_NormalStatus stat;
0394 
0395   TheArcTool::D1(A,Param,p2d,dp2d);
0396   if (OnFirst) {
0397     TheSurfaceTool::D1(surf1,p2d.X(),p2d.Y(),pbid,d1u,d1v);
0398     if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
0399     else tgline = gp_Vec(prevprev.PointOnS1(),previousP.PointOnS1());
0400   }
0401   else {
0402     TheSurfaceTool::D1(surf2,p2d.X(),p2d.Y(),pbid,d1u,d1v);
0403     if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
0404     else tgline = gp_Vec(prevprev.PointOnS2(),previousP.PointOnS2());
0405   }
0406 
0407   tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
0408 
0409   CSLib::Normal(d1u, d1v, 1.e-9, stat, thenormal);
0410   if (stat ==  CSLib_Defined) normale.SetXYZ(thenormal.XYZ());
0411   else {
0412     Handle(Adaptor3d_Surface) surf;
0413     if (OnFirst) surf = surf1;
0414     else         surf = surf2;
0415     Standard_Integer iu, iv;
0416     TColgp_Array2OfVec Der(0, 2 , 0, 2);
0417     TheSurfaceTool::D2(surf,p2d.X(),p2d.Y(),pbid, Der(1,0), Der(0,1), 
0418                        Der(2,0), Der(0,2), Der(1,1));
0419     Der(2,1) = TheSurfaceTool::DN(surf, p2d.X(), p2d.Y(), 2,1);
0420     Der(1,2) = TheSurfaceTool::DN(surf,p2d.X(),p2d.Y(), 1,2);
0421     Der(2,2) = TheSurfaceTool::DN(surf,p2d.X(),p2d.Y(), 2,2);
0422     CSLib::Normal(2, Der, 1.e-9,  
0423                   p2d.X(), p2d.Y(), 
0424                   TheSurfaceTool::FirstUParameter(surf),
0425                   TheSurfaceTool::LastUParameter(surf),
0426                   TheSurfaceTool::FirstVParameter(surf),
0427                   TheSurfaceTool::LastVParameter(surf),
0428                   stat, thenormal, iu, iv);
0429     normale.SetXYZ(thenormal.XYZ());
0430 #ifdef OCCT_DEBUG
0431     if (stat == CSLib_InfinityOfSolutions)
0432       std::cout << "Blend_Walking::Transition : Infinite de Normal" << std::endl;
0433 #endif 
0434   }
0435 
0436   IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
0437 
0438 }
0439 
0440 
0441 void Blend_Walking::MakeExtremity(TheExtremity& Extrem,
0442                                   const Standard_Boolean OnFirst,
0443                                   const Standard_Integer Index,
0444                                   const Standard_Real Param,
0445                                   const Standard_Boolean IsVtx,
0446                                   const TheVertex& Vtx)
0447 {
0448 
0449   IntSurf_Transition Tline,Tarc;
0450   Standard_Integer nbarc;
0451   Handle(TheTopolTool) Iter;
0452 
0453   if (OnFirst) {
0454     Extrem.SetValue(previousP.PointOnS1(),
0455                     sol(1),sol(2),
0456                     previousP.Parameter(), tolpoint3d);
0457     if (!previousP.IsTangencyPoint())  
0458       Extrem.SetTangent(previousP.TangentOnS1());
0459     Iter = recdomain1;
0460   }
0461   else {
0462     Extrem.SetValue(previousP.PointOnS2(),
0463                     sol(3),sol(4),
0464                     previousP.Parameter(), tolpoint3d);
0465     if (!previousP.IsTangencyPoint())  
0466       Extrem.SetTangent(previousP.TangentOnS2());
0467     Iter = recdomain2;
0468   }
0469 
0470   Iter->Init();
0471   nbarc = 1;
0472 
0473   while (nbarc < Index) {
0474     nbarc++;
0475     Iter->Next();
0476   }
0477 
0478   Transition(OnFirst,Iter->Value(),Param,Tline,Tarc);
0479   Extrem.AddArc(Iter->Value(),Param,Tline,Tarc);
0480   if (IsVtx) Extrem.SetVertex(Vtx);
0481 }
0482 
0483 void  Blend_Walking::MakeSingularExtremity( TheExtremity& Extrem,
0484                                            const Standard_Boolean OnFirst,
0485                                            const TheVertex& Vtx)
0486 {
0487   IntSurf_Transition Tline,Tarc;
0488   Handle(TheTopolTool) Iter;
0489   Standard_Real prm;
0490 
0491   if (OnFirst) {
0492     Iter = recdomain1;
0493     if (!previousP.IsTangencyPoint())
0494       Extrem.SetTangent(previousP.TangentOnS1());
0495   }
0496   else {
0497     if (!previousP.IsTangencyPoint()) 
0498       Extrem.SetTangent(previousP.TangentOnS2());
0499     Iter = recdomain2;
0500   }
0501   
0502   Iter->Init(); 
0503   Extrem.SetVertex(Vtx);
0504   while (Iter->More()) {
0505     TheArc arc = Iter->Value();
0506     Iter->Initialize(arc);
0507     Iter->InitVertexIterator();
0508     while (Iter->MoreVertex()) {
0509       if (Iter->Identical(Vtx,Iter->Vertex())) {
0510         prm = TheBlendTool::Parameter(Vtx,arc);
0511         Transition(OnFirst,arc,prm,Tline,Tarc);
0512         Extrem.AddArc(arc,prm,Tline,Tarc);
0513       }
0514       Iter->NextVertex();
0515     }
0516     Iter->Next();
0517   }   
0518 }
0519 
0520 
0521 
0522 
0523 
0524 
0525 
0526 
0527 
0528 
0529