Warning, /include/opencascade/Blend_Walking_4.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 #include <gce_MakePln.hxx>
0016 #include <Extrema_ExtPS.hxx>
0017 #include <Extrema_ExtPC.hxx>
0018
0019 #ifdef DRAW
0020 #include <DrawTrSurf.hxx>
0021 #endif
0022
0023
0024 static const Standard_Real CosRef3D = 0.88;
0025
0026 static void RecadreIfPeriodic(Standard_Real& NewU,
0027 Standard_Real& NewV,
0028 const Standard_Real OldU,
0029 const Standard_Real OldV,
0030 const Standard_Real UPeriod,
0031 const Standard_Real VPeriod)
0032 {
0033 if (UPeriod > 0.)
0034 {
0035 Standard_Real sign = (NewU < OldU)? 1 : -1;
0036 while (Abs(NewU - OldU) > UPeriod/2)
0037 NewU += sign * UPeriod;
0038 }
0039 if (VPeriod > 0.)
0040 {
0041 Standard_Real sign = (NewV < OldV)? 1 : -1;
0042 while (Abs(NewV - OldV) > VPeriod/2)
0043 NewV += sign * VPeriod;
0044 }
0045 }
0046
0047 static void evalpinit(math_Vector& parinit,
0048 const Blend_Point& previousP,
0049 const Standard_Real parprec,
0050 const Standard_Real param,
0051 const math_Vector& infbound,
0052 const math_Vector& supbound,
0053 const Standard_Boolean classonS1,
0054 const Standard_Boolean classonS2)
0055 {
0056 if(previousP.IsTangencyPoint()){
0057 previousP.ParametersOnS1(parinit(1),parinit(2));
0058 previousP.ParametersOnS2(parinit(3),parinit(4));
0059 }
0060 else {
0061 Standard_Real u1,v1,u2,v2;
0062 Standard_Real du1,dv1,du2,dv2;
0063 Standard_Boolean Inside=Standard_True;
0064 previousP.ParametersOnS1(u1,v1);
0065 previousP.ParametersOnS2(u2,v2);
0066 previousP.Tangent2dOnS1().Coord(du1,dv1);
0067 previousP.Tangent2dOnS2().Coord(du2,dv2);
0068 Standard_Real step = param - parprec;
0069 u1+= step*du1;
0070 v1+= step*dv1;
0071 if ( classonS1 ) {
0072 if ((u1<infbound(1)) || (u1>supbound(1))) Inside=Standard_False;
0073 if ((v1<infbound(2)) || (v1>supbound(2))) Inside=Standard_False;
0074 }
0075 u2+= step*du2;
0076 v2+= step*dv2;
0077 if ( classonS2) {
0078 if ((u2<infbound(3)) || (u2>supbound(3))) Inside=Standard_False;
0079 if ((v2<infbound(4)) || (v2>supbound(4))) Inside=Standard_False;
0080 }
0081
0082 if (Inside) {
0083 parinit(1) = u1;
0084 parinit(2) = v1;
0085 parinit(3) = u2;
0086 parinit(4) = v2;
0087 }
0088 else { // on ne joue pas au plus malin
0089 previousP.ParametersOnS1(parinit(1),parinit(2));
0090 previousP.ParametersOnS2(parinit(3),parinit(4));
0091 }
0092
0093 }
0094 }
0095
0096
0097
0098 void Blend_Walking::InternalPerform(Blend_Function& Func,
0099 Blend_FuncInv& FuncInv,
0100 const Standard_Real Bound)
0101 {
0102 Standard_Real Cosi = 0., Cosi2 = 0.;
0103
0104 Standard_Real stepw = pasmax;
0105 Standard_Integer nbp = line->NbPoints();
0106 if(nbp >= 2){ //On reprend le dernier step s'il n est pas trop petit.
0107 if(sens < 0.){
0108 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
0109 }
0110 else{
0111 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
0112 }
0113 stepw = Max(stepw,100.*tolgui);
0114 }
0115 Standard_Real parprec = param;
0116 gp_Vec TgOnGuide, PrevTgOnGuide;
0117 gp_Pnt PtOnGuide;
0118 hguide->D1(parprec, PtOnGuide, TgOnGuide);
0119 PrevTgOnGuide = TgOnGuide;
0120
0121 if (sens*(parprec - Bound) >= -tolgui) {
0122 return;
0123 }
0124 Blend_Status State = Blend_OnRst12;
0125 TopAbs_State situ1 =TopAbs_IN,situ2=TopAbs_IN;
0126 Standard_Real w1,w2;
0127 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
0128 Standard_Boolean Arrive,recad1,recad2, control;
0129 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False, echecrecad;
0130 gp_Pnt2d p2d;
0131 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
0132 math_Vector solrst1(1,4),solrst2(1,4);
0133 TheVertex Vtx1,Vtx2;
0134 TheExtremity Ext1,Ext2;
0135
0136 //IntSurf_Transition Tline,Tarc;
0137
0138 Func.GetTolerance(tolerance,tolpoint3d);
0139 Func.GetBounds(infbound,supbound);
0140
0141 math_FunctionSetRoot rsnld(Func,tolerance,30);
0142 parinit = sol;
0143
0144 Arrive = Standard_False;
0145 param = parprec + sens*stepw;
0146 if(sens *(param - Bound) > 0.) {
0147 stepw = sens*(Bound - parprec)*0.5;
0148 param = parprec + sens*stepw;
0149 }
0150
0151 evalpinit(parinit,previousP,parprec,param,
0152 infbound,supbound, clasonS1, clasonS2);
0153
0154 while (!Arrive) {
0155
0156 #ifdef OCCT_DEBUG
0157 sectioncalculee = 0;
0158 nbcomputedsection++;
0159 #endif
0160
0161 hguide->D1(param, PtOnGuide, TgOnGuide);
0162 //Check deflection on guide
0163 Cosi = PrevTgOnGuide * TgOnGuide;
0164 if (Cosi < gp::Resolution()) //angle>=pi/2 or null magnitude
0165 Cosi2 = 0.;
0166 else
0167 Cosi2 = Cosi * Cosi / PrevTgOnGuide.SquareMagnitude() / TgOnGuide.SquareMagnitude();
0168 if (Cosi2 < CosRef3D) //angle 3d too great
0169 {
0170 State = Blend_StepTooLarge;
0171 stepw = stepw/2.;
0172 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
0173 if (Abs(stepw) < tolgui) {
0174 Ext1.SetValue(previousP.PointOnS1(),
0175 sol(1),sol(2),
0176 previousP.Parameter(),tolpoint3d);
0177 Ext2.SetValue(previousP.PointOnS2(),
0178 sol(3),sol(4),
0179 previousP.Parameter(),tolpoint3d);
0180 if (!previousP.IsTangencyPoint()) {
0181 Ext1.SetTangent(previousP.TangentOnS1());
0182 Ext2.SetTangent(previousP.TangentOnS2());
0183 }
0184 Arrive = Standard_True;
0185 }
0186 continue;
0187 }
0188 PrevTgOnGuide = TgOnGuide;
0189 //////////////////////////
0190
0191 Standard_Boolean bonpoint = 1;
0192 Func.Set(param);
0193 rsnld.Perform(Func,parinit,infbound,supbound);
0194
0195 if (!rsnld.IsDone()) {
0196 State = Blend_StepTooLarge;
0197 bonpoint = 0;
0198 }
0199 else {
0200 rsnld.Root(sol);
0201
0202 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
0203 Min(tolerance(1),tolerance(2)),0);
0204 else situ1 = TopAbs_IN;
0205 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
0206 Min(tolerance(3),tolerance(4)),0);
0207 else situ2 = TopAbs_IN;
0208 }
0209 if(bonpoint && line->NbPoints() == 1 && (situ1 != TopAbs_IN || situ2 != TopAbs_IN)){
0210 State = Blend_StepTooLarge;
0211 bonpoint = 0;
0212 }
0213 if(bonpoint){
0214 w1 = w2 = Bound;
0215 recad1 = Standard_False;
0216 recad2 = Standard_False;
0217 echecrecad = Standard_False;
0218 control = Standard_False;
0219
0220 if (situ1 == TopAbs_OUT || situ1 == TopAbs_ON) {
0221 // pb inverse sur surf1
0222 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
0223 //on a pris la mauvaise solution.
0224 recad1 = Recadre(FuncInv,Standard_True,
0225 sol,solrst1,Index1,Isvtx1,Vtx1);
0226
0227 if (recad1) {
0228 Standard_Real wtemp;
0229 wtemp = solrst1(2);
0230 if ((param - wtemp)/sens>= -10*tolgui){
0231 w1 = solrst1(2);
0232 control = Standard_True;
0233 }
0234 else {
0235 echecrecad = Standard_True;
0236 recad1 = Standard_False;
0237 State = Blend_StepTooLarge;
0238 bonpoint = 0;
0239 stepw = stepw/2.;
0240 }
0241 }
0242 else {
0243 echecrecad = Standard_True;
0244 }
0245 }
0246 if (situ2 == TopAbs_OUT || situ2 == TopAbs_ON) {
0247 // pb inverse sur surf2
0248 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
0249 //on a pris la mauvaise solution.
0250 recad2 = Recadre(FuncInv,Standard_False,
0251 sol,solrst2,Index2,Isvtx2,Vtx2);
0252
0253 if (recad2) {
0254 Standard_Real wtemp;
0255 wtemp = solrst2(2);
0256 if ((param - wtemp)/sens>= -10*tolgui){
0257 w2 = solrst2(2);
0258 control = Standard_True;
0259 }
0260 else {
0261 echecrecad = Standard_True;
0262 recad2 = Standard_False;
0263 State = Blend_StepTooLarge;
0264 bonpoint = 0;
0265 stepw = stepw/2.;
0266 }
0267 }
0268 else {
0269 echecrecad = Standard_True;
0270 }
0271 }
0272
0273 // Que faut il controler
0274 if (recad1 && recad2) {
0275 if (Abs(w1-w2) <= 10*tolgui) {
0276 // pas besoin de controler les recadrage
0277 // Le control pouvant se planter (cf model blend10)
0278 // La tolerance est choisie grossse afin, de permetre au
0279 // cheminement suivant, de poser quelques sections ...
0280 control = Standard_False;
0281 }
0282 else if (sens*(w1-w2) < 0.) {
0283 //sol sur 1 ?
0284 recad2 = Standard_False;
0285 }
0286 else {
0287 //sol sur 2 ?
0288 recad1 = Standard_False;
0289 }
0290 }
0291
0292 // Controle effectif des recadrage
0293 if (control) {
0294 TopAbs_State situ;
0295 if (recad1 && clasonS2) {
0296 situ = recdomain2->Classify(gp_Pnt2d(solrst1(3),solrst1(4)),
0297 Min(tolerance(3),tolerance(4)));
0298 if (situ == TopAbs_OUT) {
0299 recad1 = Standard_False;
0300 echecrecad = Standard_True;
0301 }
0302 }
0303 else if (recad2 && clasonS1) {
0304 situ = recdomain1->Classify(gp_Pnt2d(solrst2(3),solrst2(4)),
0305 Min(tolerance(1),tolerance(1)));
0306 if (situ == TopAbs_OUT) {
0307 recad2 = Standard_False;
0308 echecrecad = Standard_True;
0309 }
0310 }
0311 }
0312
0313 if(recad1 || recad2) echecrecad = Standard_False;
0314
0315 if (!echecrecad) {
0316 if (recad1 && recad2) {
0317 //sol sur 1 et 2 a la fois
0318 // On passe par les arcs , pour ne pas avoir de probleme
0319 // avec les surfaces periodiques.
0320 State = Blend_OnRst12;
0321 param = (w1+w2)/2;
0322 gp_Pnt Pnt1, Pnt2;
0323 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
0324 sol(1) = p2d.X();
0325 sol(2) = p2d.Y();
0326 Pnt1 = TheSurfaceTool::Value(surf1,sol(1),sol(2));
0327 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
0328 sol(3) = p2d.X();
0329 sol(4) = p2d.Y();
0330 Pnt2 = TheSurfaceTool::Value(surf2,sol(3),sol(4));
0331 const Standard_Real TolProd = 1.e-5;
0332 Standard_Real SavedParams [2];
0333 Standard_Boolean SameDirs [2] = {Standard_False, Standard_False};
0334 ChFiDS_ElSpine& theElSpine = *hguide;
0335 SavedParams[0] = theElSpine.GetSavedFirstParameter();
0336 SavedParams[1] = theElSpine.GetSavedLastParameter();
0337 for (Standard_Integer ind = 0; ind < 2; ind++)
0338 {
0339 if (!Precision::IsInfinite(SavedParams[ind]))
0340 {
0341 //Check the original first and last parameters of guide curve
0342 //for equality to found parameter <param>:
0343 //check equality of tangent to guide curve and
0344 //normal to plane built on 3 points:
0345 //point on guide curve and points on restrictions of adjacent
0346 //surfaces.
0347 gp_Pnt Pnt0;
0348 gp_Vec Dir0;
0349 hguide->D1(SavedParams[ind], Pnt0, Dir0);
0350 Standard_Real Length = Dir0.Magnitude();
0351 if (Length <= gp::Resolution())
0352 continue;
0353 Dir0 /= Length;
0354 gce_MakePln PlaneBuilder(Pnt0, Pnt1, Pnt2);
0355 if (!PlaneBuilder.IsDone())
0356 continue;
0357 gp_Pln thePlane = PlaneBuilder.Value();
0358 gp_Dir DirPlane = thePlane.Axis().Direction();
0359 gp_Vec theProd = Dir0 ^ DirPlane;
0360 Standard_Real ProdMod = theProd.Magnitude();
0361 if (ProdMod <= TolProd)
0362 SameDirs[ind] = Standard_True;
0363 }
0364 }
0365 Standard_Real theParam = Precision::Infinite();
0366 //Choose the closest parameter
0367 if (SameDirs[0] && SameDirs[1])
0368 theParam = (Abs(param - SavedParams[0]) < Abs(param - SavedParams[1]))?
0369 SavedParams[0] : SavedParams[1];
0370 else if (SameDirs[0])
0371 theParam = SavedParams[0];
0372 else if (SameDirs[1])
0373 theParam = SavedParams[1];
0374
0375 Standard_Real NewU, NewV, NewParam;
0376 gp_Pnt NewPnt;
0377 Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, Pnt1,
0378 NewU, NewV, NewPnt, NewParam);
0379 if (Corrected)
0380 {
0381 if (Abs(param - NewParam) < Abs(param - theParam))
0382 theParam = NewParam;
0383 }
0384
0385 if (!Precision::IsInfinite(theParam))
0386 param = theParam;
0387 }
0388 else if (recad1) {
0389 // sol sur 1
0390 State = Blend_OnRst1;
0391 param = w1;
0392 recdomain1->Init();
0393 nbarc = 1;
0394 while (nbarc < Index1) {
0395 nbarc++;
0396 recdomain1->Next();
0397 }
0398 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
0399 sol(1) = p2d.X();
0400 sol(2) = p2d.Y();
0401 sol(3) = solrst1(3);
0402 sol(4) = solrst1(4);
0403 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,sol(1),sol(2));
0404 Standard_Real NewU, NewV, NewParam;
0405 gp_Pnt NewPnt;
0406 Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, thePntOnRst,
0407 NewU, NewV, NewPnt, NewParam);
0408 if (Corrected)
0409 {
0410 param = NewParam;
0411 sol(3) = NewU;
0412 sol(4) = NewV;
0413 }
0414 }
0415 else if (recad2) {
0416 //sol sur 2
0417 State = Blend_OnRst2;
0418 param = w2;
0419
0420 recdomain2->Init();
0421 nbarc = 1;
0422 while (nbarc < Index2) {
0423 nbarc++;
0424 recdomain2->Next();
0425 }
0426 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
0427 sol(1) = solrst2(3);
0428 sol(2) = solrst2(4);
0429 sol(3) = p2d.X();
0430 sol(4) = p2d.Y();
0431 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,sol(3),sol(4));
0432 Standard_Real NewU, NewV, NewParam;
0433 gp_Pnt NewPnt;
0434 Standard_Boolean Corrected = CorrectExtremityOnOneRst(2, sol(1), sol(2), param, thePntOnRst,
0435 NewU, NewV, NewPnt, NewParam);
0436 if (Corrected)
0437 {
0438 param = NewParam;
0439 sol(1) = NewU;
0440 sol(2) = NewV;
0441 }
0442 }
0443 else {
0444 State = Blend_OK;
0445 }
0446
0447 Standard_Boolean testdefl = 1;
0448 #ifdef OCCT_DEBUG
0449 testdefl = !Blend_GetcontextNOTESTDEFL();
0450 #endif
0451 if (recad1 || recad2) {
0452 Func.Set(param);
0453 // Il vaut mieux un pas non orthodoxe que pas de recadrage!! PMN
0454 State = TestArret(Func, State,
0455 (testdefl && (Abs(stepw) > 3*tolgui)),
0456 Standard_False, Standard_True);
0457 }
0458 else {
0459 State = TestArret(Func, State, testdefl);
0460 }
0461 }
0462 else {
0463 // Ou bien le pas max est mal regle. On divise.
0464 // if(line->NbPoints() == 1) State = Blend_StepTooLarge;
0465 if (stepw > 2*tolgui) State = Blend_StepTooLarge;
0466 // Sinon echec recadrage. On sort avec PointsConfondus
0467 else {
0468 #ifdef OCCT_DEBUG
0469 std::cout << "Echec recadrage" << std::endl;
0470 #endif
0471 State = Blend_SamePoints;
0472 }
0473 }
0474 }
0475
0476 #ifdef OCCT_DEBUG
0477 if (Blend_GettraceDRAWSECT()){
0478 Drawsect(surf1,surf2,sol,param,Func, State);
0479 }
0480 #endif
0481 switch (State) {
0482 case Blend_OK :
0483 {
0484 // Mettre a jour la ligne.
0485 if (sens>0.) {
0486 line->Append(previousP);
0487 }
0488 else {
0489 line->Prepend(previousP);
0490 }
0491 #ifdef DRAW
0492 Standard_Integer nbpts = line->NbPoints();
0493 char name [100];
0494 sprintf(name, "pg%d", nbpts);
0495 DrawTrSurf::Set(name, PtOnGuide);
0496 sprintf(name, "p1_%d", nbpts);
0497 DrawTrSurf::Set(name, previousP.PointOnS1());
0498 sprintf(name, "p2_%d", nbpts);
0499 DrawTrSurf::Set(name, previousP.PointOnS2());
0500 #endif
0501
0502 parprec = param;
0503
0504 if (param == Bound) {
0505 Arrive = Standard_True;
0506 Ext1.SetValue(previousP.PointOnS1(),
0507 sol(1),sol(2),
0508 previousP.Parameter(), tolpoint3d);
0509 Ext2.SetValue(previousP.PointOnS2(),
0510 sol(3),sol(4),
0511 previousP.Parameter(), tolpoint3d);
0512 if (!previousP.IsTangencyPoint()) {
0513 Ext1.SetTangent(previousP.TangentOnS1());
0514 Ext2.SetTangent(previousP.TangentOnS2());
0515 }
0516
0517 // Indiquer que fin sur Bound.
0518 }
0519 else {
0520 param = param + sens*stepw;
0521 if (sens*(param - Bound) > - tolgui) {
0522 param = Bound;
0523 }
0524 }
0525 evalpinit(parinit,previousP,parprec,param,
0526 infbound,supbound, clasonS1, clasonS2);
0527 }
0528 break;
0529
0530 case Blend_StepTooLarge :
0531 {
0532 stepw = stepw/2.;
0533 if (Abs(stepw) < tolgui) {
0534 Ext1.SetValue(previousP.PointOnS1(),
0535 sol(1),sol(2),
0536 previousP.Parameter(),tolpoint3d);
0537 Ext2.SetValue(previousP.PointOnS2(),
0538 sol(3),sol(4),
0539 previousP.Parameter(),tolpoint3d);
0540 if (!previousP.IsTangencyPoint()) {
0541 Ext1.SetTangent(previousP.TangentOnS1());
0542 Ext2.SetTangent(previousP.TangentOnS2());
0543 }
0544 Arrive = Standard_True;
0545 if (line->NbPoints()>=2) {
0546 // Indiquer qu on s arrete en cours de cheminement
0547 }
0548 // else {
0549 // line->Clear();
0550 // }
0551 }
0552 else {
0553 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
0554 evalpinit(parinit,previousP,parprec,param,
0555 infbound,supbound, clasonS1, clasonS2);
0556 }
0557 }
0558 break;
0559
0560 case Blend_StepTooSmall :
0561 {
0562 // Mettre a jour la ligne.
0563 if (sens>0.) {
0564 line->Append(previousP);
0565 }
0566 else {
0567 line->Prepend(previousP);
0568 }
0569 #ifdef DRAW
0570 Standard_Integer nbpts = line->NbPoints();
0571 char name [100];
0572 sprintf(name, "pg%d", nbpts);
0573 DrawTrSurf::Set(name, PtOnGuide);
0574 sprintf(name, "p1_%d", nbpts);
0575 DrawTrSurf::Set(name, previousP.PointOnS1());
0576 sprintf(name, "p2_%d", nbpts);
0577 DrawTrSurf::Set(name, previousP.PointOnS2());
0578 #endif
0579
0580 parprec = param;
0581
0582 stepw = Min(1.5*stepw,pasmax);
0583 if (param == Bound) {
0584 Arrive = Standard_True;
0585 Ext1.SetValue(previousP.PointOnS1(),
0586 sol(1),sol(2),
0587 previousP.Parameter(),tolpoint3d);
0588 Ext2.SetValue(previousP.PointOnS2(),
0589 sol(3),sol(4),
0590 previousP.Parameter(),tolpoint3d);
0591 if (!previousP.IsTangencyPoint()) {
0592 Ext1.SetTangent(previousP.TangentOnS1());
0593 Ext2.SetTangent(previousP.TangentOnS2());
0594 }
0595 // Indiquer que fin sur Bound.
0596 }
0597 else {
0598 param = param + sens*stepw;
0599 if (sens*(param - Bound) > - tolgui) {
0600 param = Bound;
0601 }
0602 }
0603 evalpinit(parinit,previousP,parprec,param,
0604 infbound,supbound, clasonS1, clasonS2);
0605 }
0606 break;
0607
0608 case Blend_OnRst1 :
0609 {
0610 if (sens>0.) {
0611 line->Append(previousP);
0612 }
0613 else {
0614 line->Prepend(previousP);
0615 }
0616 #ifdef DRAW
0617 Standard_Integer nbpts = line->NbPoints();
0618 char name [100];
0619 sprintf(name, "pg%d", nbpts);
0620 DrawTrSurf::Set(name, PtOnGuide);
0621 sprintf(name, "p1_%d", nbpts);
0622 DrawTrSurf::Set(name, previousP.PointOnS1());
0623 sprintf(name, "p2_%d", nbpts);
0624 DrawTrSurf::Set(name, previousP.PointOnS2());
0625 #endif
0626
0627 MakeExtremity(Ext1,Standard_True,Index1,
0628 solrst1(1),Isvtx1,Vtx1);
0629 // On blinde le cas singulier ou un des recadrage a planter
0630 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2.0 * tolpoint3d)) {
0631 Ext2.SetValue(previousP.PointOnS1(),
0632 sol(3),sol(4),tolpoint3d);
0633 if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
0634 }
0635 else {
0636 Ext2.SetValue(previousP.PointOnS2(),
0637 sol(3),sol(4),
0638 previousP.Parameter(),tolpoint3d);
0639 }
0640 Arrive = Standard_True;
0641 }
0642 break;
0643
0644 case Blend_OnRst2 :
0645 {
0646 if (sens>0.) {
0647 line->Append(previousP);
0648 }
0649 else {
0650 line->Prepend(previousP);
0651 }
0652 #ifdef DRAW
0653 Standard_Integer nbpts = line->NbPoints();
0654 char name [100];
0655 sprintf(name, "pg%d", nbpts);
0656 DrawTrSurf::Set(name, PtOnGuide);
0657 sprintf(name, "p1_%d", nbpts);
0658 DrawTrSurf::Set(name, previousP.PointOnS1());
0659 sprintf(name, "p2_%d", nbpts);
0660 DrawTrSurf::Set(name, previousP.PointOnS2());
0661 #endif
0662
0663 // On blinde le cas singulier ou un des recadrage a plante
0664 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2.0 * tolpoint3d)) {
0665 Ext1.SetValue(previousP.PointOnS2(),
0666 sol(1),sol(2),tolpoint3d);
0667 if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
0668 }
0669 else {
0670 Ext1.SetValue(previousP.PointOnS1(),
0671 sol(1),sol(2),
0672 previousP.Parameter(),tolpoint3d);
0673 }
0674 MakeExtremity(Ext2,Standard_False,Index2,
0675 solrst2(1),Isvtx2,Vtx2);
0676 Arrive = Standard_True;
0677 }
0678 break;
0679
0680
0681 case Blend_OnRst12 :
0682 {
0683 if (sens>0.) {
0684 line->Append(previousP);
0685 }
0686 else {
0687 line->Prepend(previousP);
0688 }
0689 #ifdef DRAW
0690 Standard_Integer nbpts = line->NbPoints();
0691 char name [100];
0692 sprintf(name, "pg%d", nbpts);
0693 DrawTrSurf::Set(name, PtOnGuide);
0694 sprintf(name, "p1_%d", nbpts);
0695 DrawTrSurf::Set(name, previousP.PointOnS1());
0696 sprintf(name, "p2_%d", nbpts);
0697 DrawTrSurf::Set(name, previousP.PointOnS2());
0698 #endif
0699
0700 if ( (Isvtx1 != Isvtx2) &&
0701 (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2.0 * tolpoint3d)) ) {
0702 // On blinde le cas singulier ou un seul recadrage
0703 // est reconnu comme vertex.
0704 if (Isvtx1) {
0705 Isvtx2 = Standard_True;
0706 Vtx2 = Vtx1;
0707 }
0708 else {
0709 Isvtx1 = Standard_True;
0710 Vtx1 = Vtx2;
0711 }
0712 }
0713
0714 MakeExtremity(Ext1,Standard_True,Index1,
0715 solrst1(1),Isvtx1,Vtx1);
0716 MakeExtremity(Ext2,Standard_False,Index2,
0717 solrst2(1),Isvtx2,Vtx2);
0718 Arrive = Standard_True;
0719 }
0720 break;
0721
0722 case Blend_SamePoints :
0723 {
0724 // On arrete
0725 #ifdef OCCT_DEBUG
0726 std::cout << " Points confondus dans le cheminement" << std::endl;
0727 #endif
0728 Ext1.SetValue(previousP.PointOnS1(),
0729 sol(1),sol(2),
0730 previousP.Parameter(),tolpoint3d);
0731 Ext2.SetValue(previousP.PointOnS2(),
0732 sol(3),sol(4),
0733 previousP.Parameter(),tolpoint3d);
0734 if (!previousP.IsTangencyPoint()) {
0735 Ext1.SetTangent(previousP.TangentOnS1());
0736 Ext2.SetTangent(previousP.TangentOnS2());
0737 }
0738 Arrive = Standard_True;
0739 }
0740 break;
0741 default:
0742 break;
0743 }
0744 if (Arrive) {
0745 if (sens > 0.) {
0746 line->SetEndPoints(Ext1,Ext2);
0747 }
0748 else {
0749 line->SetStartPoints(Ext1,Ext2);
0750
0751 }
0752 }
0753
0754 }
0755
0756 }
0757
0758 Standard_Boolean Blend_Walking::CorrectExtremityOnOneRst(const Standard_Integer IndexOfRst,
0759 const Standard_Real theU,
0760 const Standard_Real theV,
0761 const Standard_Real theParam,
0762 const gp_Pnt& thePntOnRst,
0763 Standard_Real& NewU,
0764 Standard_Real& NewV,
0765 gp_Pnt& NewPoint,
0766 Standard_Real& NewParam) const
0767 {
0768 const Standard_Real TolAng = 0.001; //bug OCC25701
0769
0770 ChFiDS_ElSpine& theElSpine = *hguide;
0771 if (theElSpine.NbVertices() == 0)
0772 return Standard_False;
0773
0774 Handle(TheTopolTool) DomainOfRst = (IndexOfRst == 1)? recdomain1 : recdomain2;
0775 TheSurface SurfOfRst = (IndexOfRst == 1)? surf1 : surf2;
0776 TheSurface AnotherSurf = (IndexOfRst == 1)? surf2 : surf1;
0777
0778 //Correct point on surface 2
0779 //First we find right <param>
0780 Standard_Real Ends [2];
0781 Ends[0] = TheArcTool::FirstParameter(DomainOfRst->Value());
0782 Ends[1] = TheArcTool::LastParameter(DomainOfRst->Value());
0783 Standard_Real GlobalMinSqDist = Precision::Infinite();
0784 Standard_Real ParamOnGuide = 0;
0785 gp_Pnt PointOnGuide;
0786 for (Standard_Integer k = 0; k < 2; k++)
0787 {
0788 gp_Pnt2d P2dOnEnd = TheArcTool::Value(DomainOfRst->Value(), Ends[k]);
0789 gp_Pnt PntOnEnd = TheSurfaceTool::Value(SurfOfRst, P2dOnEnd.X(), P2dOnEnd.Y());
0790 Extrema_ExtPC projoncurv(PntOnEnd, theElSpine);
0791 if (!projoncurv.IsDone())
0792 continue;
0793 Standard_Real MinSqDist = Precision::Infinite();
0794 Standard_Integer imin = 0;
0795 for (Standard_Integer ind = 1; ind <= projoncurv.NbExt(); ind++)
0796 {
0797 Standard_Real aSqDist = projoncurv.SquareDistance(ind);
0798 if (aSqDist < MinSqDist)
0799 {
0800 MinSqDist = aSqDist;
0801 imin = ind;
0802 }
0803 }
0804 if (MinSqDist < GlobalMinSqDist)
0805 {
0806 GlobalMinSqDist = MinSqDist;
0807 ParamOnGuide = projoncurv.Point(imin).Parameter();
0808 PointOnGuide = projoncurv.Point(imin).Value();
0809 }
0810 }
0811 NewParam = ParamOnGuide;
0812 if (hguide->IsPeriodic())
0813 {
0814 Standard_Real Period = hguide->Period();
0815 Standard_Real sign = (NewParam < theParam)? 1 : -1;
0816 while (Abs(NewParam - theParam) > Period/2)
0817 NewParam += sign *Period;
0818 }
0819
0820 //Second we find right point and tangent on guide
0821 GlobalMinSqDist = Precision::Infinite();
0822 gp_Ax1 theAx1;
0823 for (Standard_Integer ind = 1; ind <= theElSpine.NbVertices(); ind++)
0824 {
0825 const gp_Ax1& anAx1 = theElSpine.VertexWithTangent(ind);
0826 gp_Pnt aPnt = anAx1.Location();
0827 Standard_Real aSqDist = PointOnGuide.SquareDistance(aPnt);
0828 if (aSqDist < GlobalMinSqDist)
0829 {
0830 GlobalMinSqDist = aSqDist;
0831 theAx1 = anAx1;
0832 }
0833 }
0834 const gp_Pnt& Pnt0 = theAx1.Location();
0835 const gp_Dir& Dir0 = theAx1.Direction();
0836 //Check new point: is it real solution?
0837 gp_Pnt OldPonGuide = hguide->Value(theParam);
0838 gp_Pnt PntOnSurf2 = TheSurfaceTool::Value(AnotherSurf,theU,theV); //old point
0839 gce_MakePln PlaneBuilder(thePntOnRst, OldPonGuide, PntOnSurf2);
0840 if (!PlaneBuilder.IsDone())
0841 return Standard_False;
0842 gp_Pln OldPlane = PlaneBuilder.Value();
0843 gp_Dir OldDir = OldPlane.Axis().Direction();
0844 Standard_Real Angle = OldDir.Angle(Dir0);
0845 if (Angle > M_PI/2)
0846 Angle = M_PI - Angle;
0847 if (Angle > TolAng)
0848 return Standard_False;
0849 ///////////////////////////////////////
0850 //Project the point(theU,theV) on the plane(Pnt0,Dir0)
0851 gp_Vec aVec(Pnt0, PntOnSurf2);
0852 gp_Vec aTranslation( (aVec.XYZ() * Dir0.XYZ()) * Dir0.XYZ() );
0853 gp_Pnt PntOnPlane = PntOnSurf2.Translated(-aTranslation);
0854
0855 //Check new point again: does point on restriction belong to the plane?
0856 PlaneBuilder = gce_MakePln(thePntOnRst, Pnt0, PntOnPlane);
0857 if (!PlaneBuilder.IsDone())
0858 return Standard_False;
0859 gp_Pln NewPlane = PlaneBuilder.Value();
0860 const gp_Dir& DirOfNewPlane = NewPlane.Axis().Direction();
0861 Angle = Dir0.Angle(DirOfNewPlane);
0862 if (Angle > M_PI/2)
0863 Angle = M_PI - Angle;
0864 if (Angle > TolAng)
0865 return Standard_False;
0866 ////////////////////////////////////////////////////////////////////////
0867
0868 //Project the point <PntOnPlane> on the surface 2
0869 Extrema_ExtPS projonsurf(PntOnPlane, *AnotherSurf,
0870 Precision::PConfusion(), Precision::PConfusion(),
0871 Extrema_ExtFlag_MIN);
0872 if (projonsurf.IsDone())
0873 {
0874 Standard_Real MinSqDist = Precision::Infinite();
0875 Standard_Integer imin = 0;
0876 for (Standard_Integer ind = 1; ind <= projonsurf.NbExt(); ind++)
0877 {
0878 Standard_Real aSqDist = projonsurf.SquareDistance(ind);
0879 if (aSqDist < MinSqDist)
0880 {
0881 MinSqDist = aSqDist;
0882 imin = ind;
0883 }
0884 }
0885 if (imin)
0886 {
0887 Extrema_POnSurf NewPOnSurf2 = projonsurf.Point(imin);
0888 NewPoint = NewPOnSurf2.Value();
0889 NewPOnSurf2.Parameter(NewU, NewV);
0890 Standard_Real uperiod = (AnotherSurf->IsUPeriodic())? AnotherSurf->UPeriod() : 0.;
0891 Standard_Real vperiod = (AnotherSurf->IsVPeriodic())? AnotherSurf->VPeriod() : 0.;
0892 RecadreIfPeriodic(NewU, NewV, theU, theV,
0893 uperiod, vperiod);
0894 return Standard_True;
0895 }
0896 }
0897
0898 return Standard_False;
0899 }