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