0028966: Coding Rules - remove Adaptor2d_HCurve2d, Adaptor3d_HCurve and Adaptor3d_HSu...
[occt.git] / src / Blend / Blend_Walking_4.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
73d0a668 15#include <gce_MakePln.hxx>
af99433e 16#include <Extrema_ExtPS.hxx>
17#include <Extrema_ExtPC.hxx>
18
1d54b807 19#ifdef DRAW
20#include <DrawTrSurf.hxx>
21#endif
22
23
d66bd706 24static const Standard_Real CosRef3D = 0.88;
25
af99433e 26static void RecadreIfPeriodic(Standard_Real& NewU,
27 Standard_Real& NewV,
28 const Standard_Real OldU,
29 const Standard_Real OldV,
30 const Standard_Real UPeriod,
31 const Standard_Real VPeriod)
32{
33 if (UPeriod > 0.)
34 {
35 Standard_Real sign = (NewU < OldU)? 1 : -1;
36 while (Abs(NewU - OldU) > UPeriod/2)
37 NewU += sign * UPeriod;
38 }
39 if (VPeriod > 0.)
40 {
41 Standard_Real sign = (NewV < OldV)? 1 : -1;
42 while (Abs(NewV - OldV) > VPeriod/2)
43 NewV += sign * VPeriod;
44 }
45}
73d0a668 46
7fd59977 47static void evalpinit(math_Vector& parinit,
48 const Blend_Point& previousP,
49 const Standard_Real parprec,
50 const Standard_Real param,
51 const math_Vector& infbound,
52 const math_Vector& supbound,
53 const Standard_Boolean classonS1,
54 const Standard_Boolean classonS2)
55{
56 if(previousP.IsTangencyPoint()){
57 previousP.ParametersOnS1(parinit(1),parinit(2));
58 previousP.ParametersOnS2(parinit(3),parinit(4));
59 }
60 else {
61 Standard_Real u1,v1,u2,v2;
62 Standard_Real du1,dv1,du2,dv2;
63 Standard_Boolean Inside=Standard_True;
64 previousP.ParametersOnS1(u1,v1);
65 previousP.ParametersOnS2(u2,v2);
66 previousP.Tangent2dOnS1().Coord(du1,dv1);
67 previousP.Tangent2dOnS2().Coord(du2,dv2);
68 Standard_Real step = param - parprec;
69 u1+= step*du1;
70 v1+= step*dv1;
71 if ( classonS1 ) {
72 if ((u1<infbound(1)) || (u1>supbound(1))) Inside=Standard_False;
73 if ((v1<infbound(2)) || (v1>supbound(2))) Inside=Standard_False;
74 }
75 u2+= step*du2;
76 v2+= step*dv2;
77 if ( classonS2) {
78 if ((u2<infbound(3)) || (u2>supbound(3))) Inside=Standard_False;
79 if ((v2<infbound(4)) || (v2>supbound(4))) Inside=Standard_False;
80 }
81
82 if (Inside) {
83 parinit(1) = u1;
84 parinit(2) = v1;
85 parinit(3) = u2;
86 parinit(4) = v2;
87 }
88 else { // on ne joue pas au plus malin
89 previousP.ParametersOnS1(parinit(1),parinit(2));
90 previousP.ParametersOnS2(parinit(3),parinit(4));
91 }
92
93 }
94}
95
96
97
98void Blend_Walking::InternalPerform(Blend_Function& Func,
99 Blend_FuncInv& FuncInv,
100 const Standard_Real Bound)
101{
d66bd706 102 Standard_Real Cosi = 0., Cosi2 = 0.;
7fd59977 103
104 Standard_Real stepw = pasmax;
105 Standard_Integer nbp = line->NbPoints();
106 if(nbp >= 2){ //On reprend le dernier step s'il n est pas trop petit.
107 if(sens < 0.){
108 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
109 }
110 else{
111 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
112 }
113 stepw = Max(stepw,100.*tolgui);
114 }
115 Standard_Real parprec = param;
d66bd706 116 gp_Vec TgOnGuide, PrevTgOnGuide;
117 gp_Pnt PtOnGuide;
118 hguide->D1(parprec, PtOnGuide, TgOnGuide);
119 PrevTgOnGuide = TgOnGuide;
7fd59977 120
121 if (sens*(parprec - Bound) >= -tolgui) {
122 return;
123 }
124 Blend_Status State = Blend_OnRst12;
125 TopAbs_State situ1 =TopAbs_IN,situ2=TopAbs_IN;
126 Standard_Real w1,w2;
1d47d8d0 127 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
7fd59977 128 Standard_Boolean Arrive,recad1,recad2, control;
1d47d8d0 129 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False, echecrecad;
7fd59977 130 gp_Pnt2d p2d;
131 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
132 math_Vector solrst1(1,4),solrst2(1,4);
133 TheVertex Vtx1,Vtx2;
134 TheExtremity Ext1,Ext2;
135
136 //IntSurf_Transition Tline,Tarc;
137
138 Func.GetTolerance(tolerance,tolesp);
139 Func.GetBounds(infbound,supbound);
140
141 math_FunctionSetRoot rsnld(Func,tolerance,30);
142 parinit = sol;
143
144 Arrive = Standard_False;
145 param = parprec + sens*stepw;
146 if(sens *(param - Bound) > 0.) {
147 stepw = sens*(Bound - parprec)*0.5;
148 param = parprec + sens*stepw;
149 }
150
151 evalpinit(parinit,previousP,parprec,param,
152 infbound,supbound, clasonS1, clasonS2);
153
154 while (!Arrive) {
155
0797d9d3 156#ifdef OCCT_DEBUG
7fd59977 157 sectioncalculee = 0;
158 nbcomputedsection++;
159#endif
d66bd706 160
161 hguide->D1(param, PtOnGuide, TgOnGuide);
162 //Check deflection on guide
163 Cosi = PrevTgOnGuide * TgOnGuide;
164 if (Cosi < gp::Resolution()) //angle>=pi/2 or null magnitude
165 Cosi2 = 0.;
166 else
167 Cosi2 = Cosi * Cosi / PrevTgOnGuide.SquareMagnitude() / TgOnGuide.SquareMagnitude();
168 if (Cosi2 < CosRef3D) //angle 3d too great
169 {
170 State = Blend_StepTooLarge;
171 stepw = stepw/2.;
172 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
173 if (Abs(stepw) < tolgui) {
174 Ext1.SetValue(previousP.PointOnS1(),
175 sol(1),sol(2),
176 previousP.Parameter(),tolesp);
177 Ext2.SetValue(previousP.PointOnS2(),
178 sol(3),sol(4),
179 previousP.Parameter(),tolesp);
180 if (!previousP.IsTangencyPoint()) {
181 Ext1.SetTangent(previousP.TangentOnS1());
182 Ext2.SetTangent(previousP.TangentOnS2());
183 }
184 Arrive = Standard_True;
185 }
186 continue;
187 }
188 PrevTgOnGuide = TgOnGuide;
189 //////////////////////////
190
7fd59977 191 Standard_Boolean bonpoint = 1;
192 Func.Set(param);
193 rsnld.Perform(Func,parinit,infbound,supbound);
194
195 if (!rsnld.IsDone()) {
196 State = Blend_StepTooLarge;
197 bonpoint = 0;
198 }
199 else {
200 rsnld.Root(sol);
201
202 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
203 Min(tolerance(1),tolerance(2)),0);
204 else situ1 = TopAbs_IN;
205 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
206 Min(tolerance(3),tolerance(4)),0);
207 else situ2 = TopAbs_IN;
208 }
209 if(bonpoint && line->NbPoints() == 1 && (situ1 != TopAbs_IN || situ2 != TopAbs_IN)){
210 State = Blend_StepTooLarge;
211 bonpoint = 0;
212 }
213 if(bonpoint){
214 w1 = w2 = Bound;
215 recad1 = Standard_False;
216 recad2 = Standard_False;
217 echecrecad = Standard_False;
218 control = Standard_False;
219
220 if (situ1 == TopAbs_OUT || situ1 == TopAbs_ON) {
221 // pb inverse sur surf1
222 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
223 //on a pris la mauvaise solution.
224 recad1 = Recadre(FuncInv,Standard_True,
225 sol,solrst1,Index1,Isvtx1,Vtx1);
226
227 if (recad1) {
228 Standard_Real wtemp;
229 wtemp = solrst1(2);
230 if ((param - wtemp)/sens>= -10*tolesp){
231 w1 = solrst1(2);
232 control = Standard_True;
233 }
234 else {
235 echecrecad = Standard_True;
236 recad1 = Standard_False;
237 State = Blend_StepTooLarge;
238 bonpoint = 0;
239 stepw = stepw/2.;
240 }
241 }
242 else {
243 echecrecad = Standard_True;
244 }
245 }
246 if (situ2 == TopAbs_OUT || situ2 == TopAbs_ON) {
247 // pb inverse sur surf2
248 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
249 //on a pris la mauvaise solution.
250 recad2 = Recadre(FuncInv,Standard_False,
251 sol,solrst2,Index2,Isvtx2,Vtx2);
252
253 if (recad2) {
254 Standard_Real wtemp;
255 wtemp = solrst2(2);
256 if ((param - wtemp)/sens>= -10*tolesp){
257 w2 = solrst2(2);
258 control = Standard_True;
259 }
260 else {
261 echecrecad = Standard_True;
262 recad2 = Standard_False;
263 State = Blend_StepTooLarge;
264 bonpoint = 0;
265 stepw = stepw/2.;
266 }
267 }
268 else {
269 echecrecad = Standard_True;
270 }
271 }
272
273 // Que faut il controler
274 if (recad1 && recad2) {
275 if (Abs(w1-w2) <= 10*tolgui) {
276 // pas besoin de controler les recadrage
277 // Le control pouvant se planter (cf model blend10)
278 // La tolerance est choisie grossse afin, de permetre au
279 // cheminement suivant, de poser quelques sections ...
280 control = Standard_False;
281 }
282 else if (sens*(w1-w2) < 0.) {
283 //sol sur 1 ?
284 recad2 = Standard_False;
285 }
286 else {
287 //sol sur 2 ?
288 recad1 = Standard_False;
289 }
290 }
291
292 // Controle effectif des recadrage
293 if (control) {
294 TopAbs_State situ;
295 if (recad1 && clasonS2) {
296 situ = recdomain2->Classify(gp_Pnt2d(solrst1(3),solrst1(4)),
297 Min(tolerance(3),tolerance(4)));
298 if (situ == TopAbs_OUT) {
299 recad1 = Standard_False;
300 echecrecad = Standard_True;
301 }
302 }
303 else if (recad2 && clasonS1) {
304 situ = recdomain1->Classify(gp_Pnt2d(solrst2(3),solrst2(4)),
305 Min(tolerance(1),tolerance(1)));
306 if (situ == TopAbs_OUT) {
307 recad2 = Standard_False;
308 echecrecad = Standard_True;
309 }
310 }
311 }
312
313 if(recad1 || recad2) echecrecad = Standard_False;
314
315 if (!echecrecad) {
316 if (recad1 && recad2) {
317 //sol sur 1 et 2 a la fois
318 // On passe par les arcs , pour ne pas avoir de probleme
319 // avec les surfaces periodiques.
320 State = Blend_OnRst12;
321 param = (w1+w2)/2;
73d0a668 322 gp_Pnt Pnt1, Pnt2;
7fd59977 323 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
324 sol(1) = p2d.X();
325 sol(2) = p2d.Y();
73d0a668 326 Pnt1 = TheSurfaceTool::Value(surf1,sol(1),sol(2));
7fd59977 327 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
328 sol(3) = p2d.X();
329 sol(4) = p2d.Y();
73d0a668 330 Pnt2 = TheSurfaceTool::Value(surf2,sol(3),sol(4));
af99433e 331 const Standard_Real TolProd = 1.e-5;
332 Standard_Real SavedParams [2];
333 Standard_Boolean SameDirs [2] = {Standard_False, Standard_False};
c22b52d6 334 ChFiDS_ElSpine& theElSpine = *hguide;
af99433e 335 SavedParams[0] = theElSpine.GetSavedFirstParameter();
336 SavedParams[1] = theElSpine.GetSavedLastParameter();
337 for (Standard_Integer ind = 0; ind < 2; ind++)
73d0a668 338 {
af99433e 339 if (!Precision::IsInfinite(SavedParams[ind]))
73d0a668 340 {
af99433e 341 //Check the original first and last parameters of guide curve
342 //for equality to found parameter <param>:
343 //check equality of tangent to guide curve and
344 //normal to plane built on 3 points:
345 //point on guide curve and points on restrictions of adjacent
346 //surfaces.
347 gp_Pnt Pnt0;
348 gp_Vec Dir0;
349 hguide->D1(SavedParams[ind], Pnt0, Dir0);
350 Standard_Real Length = Dir0.Magnitude();
351 if (Length <= gp::Resolution())
352 continue;
353 Dir0 /= Length;
354 gce_MakePln PlaneBuilder(Pnt0, Pnt1, Pnt2);
355 if (!PlaneBuilder.IsDone())
356 continue;
357 gp_Pln thePlane = PlaneBuilder.Value();
358 gp_Dir DirPlane = thePlane.Axis().Direction();
359 gp_Vec theProd = Dir0 ^ DirPlane;
360 Standard_Real ProdMod = theProd.Magnitude();
361 if (ProdMod <= TolProd)
362 SameDirs[ind] = Standard_True;
73d0a668 363 }
73d0a668 364 }
af99433e 365 Standard_Real theParam = Precision::Infinite();
366 //Choose the closest parameter
367 if (SameDirs[0] && SameDirs[1])
368 theParam = (Abs(param - SavedParams[0]) < Abs(param - SavedParams[1]))?
369 SavedParams[0] : SavedParams[1];
370 else if (SameDirs[0])
371 theParam = SavedParams[0];
372 else if (SameDirs[1])
373 theParam = SavedParams[1];
374
375 Standard_Real NewU, NewV, NewParam;
376 gp_Pnt NewPnt;
377 Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, Pnt1,
378 NewU, NewV, NewPnt, NewParam);
379 if (Corrected)
380 {
381 if (Abs(param - NewParam) < Abs(param - theParam))
382 theParam = NewParam;
383 }
384
385 if (!Precision::IsInfinite(theParam))
386 param = theParam;
7fd59977 387 }
388 else if (recad1) {
389 // sol sur 1
390 State = Blend_OnRst1;
391 param = w1;
392 recdomain1->Init();
393 nbarc = 1;
394 while (nbarc < Index1) {
395 nbarc++;
396 recdomain1->Next();
397 }
398 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
399 sol(1) = p2d.X();
400 sol(2) = p2d.Y();
401 sol(3) = solrst1(3);
402 sol(4) = solrst1(4);
af99433e 403 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,sol(1),sol(2));
404 Standard_Real NewU, NewV, NewParam;
405 gp_Pnt NewPnt;
406 Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, thePntOnRst,
407 NewU, NewV, NewPnt, NewParam);
408 if (Corrected)
409 {
410 param = NewParam;
411 sol(3) = NewU;
412 sol(4) = NewV;
413 }
7fd59977 414 }
415 else if (recad2) {
416 //sol sur 2
417 State = Blend_OnRst2;
418 param = w2;
419
420 recdomain2->Init();
421 nbarc = 1;
422 while (nbarc < Index2) {
423 nbarc++;
424 recdomain2->Next();
425 }
426 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
427 sol(1) = solrst2(3);
428 sol(2) = solrst2(4);
429 sol(3) = p2d.X();
430 sol(4) = p2d.Y();
af99433e 431 gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,sol(3),sol(4));
432 Standard_Real NewU, NewV, NewParam;
433 gp_Pnt NewPnt;
434 Standard_Boolean Corrected = CorrectExtremityOnOneRst(2, sol(1), sol(2), param, thePntOnRst,
435 NewU, NewV, NewPnt, NewParam);
436 if (Corrected)
437 {
438 param = NewParam;
439 sol(1) = NewU;
440 sol(2) = NewV;
441 }
7fd59977 442 }
443 else {
444 State = Blend_OK;
445 }
446
447 Standard_Boolean testdefl = 1;
0797d9d3 448#ifdef OCCT_DEBUG
7fd59977 449 testdefl = !Blend_GetcontextNOTESTDEFL();
450#endif
451 if (recad1 || recad2) {
452 Func.Set(param);
453 // Il vaut mieux un pas non orthodoxe que pas de recadrage!! PMN
454 State = TestArret(Func, State,
455 (testdefl && (Abs(stepw) > 3*tolgui)),
456 Standard_False, Standard_True);
457 }
458 else {
459 State = TestArret(Func, State, testdefl);
460 }
461 }
462 else {
463 // Ou bien le pas max est mal regle. On divise.
464// if(line->NbPoints() == 1) State = Blend_StepTooLarge;
465 if (stepw > 2*tolgui) State = Blend_StepTooLarge;
466 // Sinon echec recadrage. On sort avec PointsConfondus
467 else {
0797d9d3 468#ifdef OCCT_DEBUG
04232180 469 std::cout << "Echec recadrage" << std::endl;
7fd59977 470#endif
471 State = Blend_SamePoints;
472 }
473 }
474 }
475
0797d9d3 476#ifdef OCCT_DEBUG
7fd59977 477 if (Blend_GettraceDRAWSECT()){
478 Drawsect(surf1,surf2,sol,param,Func, State);
479 }
480#endif
481 switch (State) {
482 case Blend_OK :
483 {
484 // Mettre a jour la ligne.
485 if (sens>0.) {
486 line->Append(previousP);
487 }
488 else {
489 line->Prepend(previousP);
490 }
1d54b807 491#ifdef DRAW
492 Standard_Integer nbpts = line->NbPoints();
493 char name [100];
494 sprintf(name, "pg%d", nbpts);
495 DrawTrSurf::Set(name, PtOnGuide);
496 sprintf(name, "p1_%d", nbpts);
497 DrawTrSurf::Set(name, previousP.PointOnS1());
498 sprintf(name, "p2_%d", nbpts);
499 DrawTrSurf::Set(name, previousP.PointOnS2());
500#endif
7fd59977 501
502 parprec = param;
503
504 if (param == Bound) {
505 Arrive = Standard_True;
506 Ext1.SetValue(previousP.PointOnS1(),
507 sol(1),sol(2),
508 previousP.Parameter(), tolesp);
509 Ext2.SetValue(previousP.PointOnS2(),
510 sol(3),sol(4),
511 previousP.Parameter(), tolesp);
512 if (!previousP.IsTangencyPoint()) {
513 Ext1.SetTangent(previousP.TangentOnS1());
514 Ext2.SetTangent(previousP.TangentOnS2());
515 }
516
517 // Indiquer que fin sur Bound.
518 }
519 else {
520 param = param + sens*stepw;
521 if (sens*(param - Bound) > - tolgui) {
522 param = Bound;
523 }
524 }
525 evalpinit(parinit,previousP,parprec,param,
526 infbound,supbound, clasonS1, clasonS2);
527 }
528 break;
529
530 case Blend_StepTooLarge :
531 {
532 stepw = stepw/2.;
533 if (Abs(stepw) < tolgui) {
534 Ext1.SetValue(previousP.PointOnS1(),
535 sol(1),sol(2),
536 previousP.Parameter(),tolesp);
537 Ext2.SetValue(previousP.PointOnS2(),
538 sol(3),sol(4),
539 previousP.Parameter(),tolesp);
540 if (!previousP.IsTangencyPoint()) {
541 Ext1.SetTangent(previousP.TangentOnS1());
542 Ext2.SetTangent(previousP.TangentOnS2());
543 }
544 Arrive = Standard_True;
545 if (line->NbPoints()>=2) {
546 // Indiquer qu on s arrete en cours de cheminement
547 }
548// else {
549// line->Clear();
550// }
551 }
552 else {
553 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
554 evalpinit(parinit,previousP,parprec,param,
555 infbound,supbound, clasonS1, clasonS2);
556 }
557 }
558 break;
559
560 case Blend_StepTooSmall :
561 {
562 // Mettre a jour la ligne.
563 if (sens>0.) {
564 line->Append(previousP);
565 }
566 else {
567 line->Prepend(previousP);
568 }
1d54b807 569#ifdef DRAW
570 Standard_Integer nbpts = line->NbPoints();
571 char name [100];
572 sprintf(name, "pg%d", nbpts);
573 DrawTrSurf::Set(name, PtOnGuide);
574 sprintf(name, "p1_%d", nbpts);
575 DrawTrSurf::Set(name, previousP.PointOnS1());
576 sprintf(name, "p2_%d", nbpts);
577 DrawTrSurf::Set(name, previousP.PointOnS2());
578#endif
7fd59977 579
580 parprec = param;
581
582 stepw = Min(1.5*stepw,pasmax);
583 if (param == Bound) {
584 Arrive = Standard_True;
585 Ext1.SetValue(previousP.PointOnS1(),
586 sol(1),sol(2),
587 previousP.Parameter(),tolesp);
588 Ext2.SetValue(previousP.PointOnS2(),
589 sol(3),sol(4),
590 previousP.Parameter(),tolesp);
591 if (!previousP.IsTangencyPoint()) {
592 Ext1.SetTangent(previousP.TangentOnS1());
593 Ext2.SetTangent(previousP.TangentOnS2());
594 }
595 // Indiquer que fin sur Bound.
596 }
597 else {
598 param = param + sens*stepw;
599 if (sens*(param - Bound) > - tolgui) {
600 param = Bound;
601 }
602 }
603 evalpinit(parinit,previousP,parprec,param,
604 infbound,supbound, clasonS1, clasonS2);
605 }
606 break;
607
608 case Blend_OnRst1 :
609 {
610 if (sens>0.) {
611 line->Append(previousP);
612 }
613 else {
614 line->Prepend(previousP);
615 }
1d54b807 616#ifdef DRAW
617 Standard_Integer nbpts = line->NbPoints();
618 char name [100];
619 sprintf(name, "pg%d", nbpts);
620 DrawTrSurf::Set(name, PtOnGuide);
621 sprintf(name, "p1_%d", nbpts);
622 DrawTrSurf::Set(name, previousP.PointOnS1());
623 sprintf(name, "p2_%d", nbpts);
624 DrawTrSurf::Set(name, previousP.PointOnS2());
625#endif
626
7fd59977 627 MakeExtremity(Ext1,Standard_True,Index1,
628 solrst1(1),Isvtx1,Vtx1);
629 // On blinde le cas singulier ou un des recadrage a planter
630 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
631 Ext2.SetValue(previousP.PointOnS1(),
632 sol(3),sol(4),tolesp);
633 if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
634 }
635 else {
636 Ext2.SetValue(previousP.PointOnS2(),
637 sol(3),sol(4),
638 previousP.Parameter(),tolesp);
639 }
640 Arrive = Standard_True;
641 }
642 break;
643
644 case Blend_OnRst2 :
645 {
646 if (sens>0.) {
647 line->Append(previousP);
648 }
649 else {
650 line->Prepend(previousP);
651 }
1d54b807 652#ifdef DRAW
653 Standard_Integer nbpts = line->NbPoints();
654 char name [100];
655 sprintf(name, "pg%d", nbpts);
656 DrawTrSurf::Set(name, PtOnGuide);
657 sprintf(name, "p1_%d", nbpts);
658 DrawTrSurf::Set(name, previousP.PointOnS1());
659 sprintf(name, "p2_%d", nbpts);
660 DrawTrSurf::Set(name, previousP.PointOnS2());
661#endif
662
7fd59977 663 // On blinde le cas singulier ou un des recadrage a plante
664 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
665 Ext1.SetValue(previousP.PointOnS2(),
666 sol(1),sol(2),tolesp);
667 if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
668 }
669 else {
670 Ext1.SetValue(previousP.PointOnS1(),
671 sol(1),sol(2),
672 previousP.Parameter(),tolesp);
673 }
674 MakeExtremity(Ext2,Standard_False,Index2,
675 solrst2(1),Isvtx2,Vtx2);
676 Arrive = Standard_True;
677 }
678 break;
679
680
681 case Blend_OnRst12 :
682 {
683 if (sens>0.) {
684 line->Append(previousP);
685 }
686 else {
687 line->Prepend(previousP);
688 }
1d54b807 689#ifdef DRAW
690 Standard_Integer nbpts = line->NbPoints();
691 char name [100];
692 sprintf(name, "pg%d", nbpts);
693 DrawTrSurf::Set(name, PtOnGuide);
694 sprintf(name, "p1_%d", nbpts);
695 DrawTrSurf::Set(name, previousP.PointOnS1());
696 sprintf(name, "p2_%d", nbpts);
697 DrawTrSurf::Set(name, previousP.PointOnS2());
698#endif
7fd59977 699
700 if ( (Isvtx1 != Isvtx2) &&
701 (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) ) {
702 // On blinde le cas singulier ou un seul recadrage
703 // est reconnu comme vertex.
704 if (Isvtx1) {
705 Isvtx2 = Standard_True;
706 Vtx2 = Vtx1;
707 }
708 else {
709 Isvtx1 = Standard_True;
710 Vtx1 = Vtx2;
711 }
712 }
713
714 MakeExtremity(Ext1,Standard_True,Index1,
715 solrst1(1),Isvtx1,Vtx1);
716 MakeExtremity(Ext2,Standard_False,Index2,
717 solrst2(1),Isvtx2,Vtx2);
718 Arrive = Standard_True;
719 }
720 break;
721
722 case Blend_SamePoints :
723 {
724 // On arrete
0797d9d3 725#ifdef OCCT_DEBUG
04232180 726 std::cout << " Points confondus dans le cheminement" << std::endl;
7fd59977 727#endif
728 Ext1.SetValue(previousP.PointOnS1(),
729 sol(1),sol(2),
730 previousP.Parameter(),tolesp);
731 Ext2.SetValue(previousP.PointOnS2(),
732 sol(3),sol(4),
8c2d3314 733 previousP.Parameter(),tolesp);
7fd59977 734 if (!previousP.IsTangencyPoint()) {
735 Ext1.SetTangent(previousP.TangentOnS1());
736 Ext2.SetTangent(previousP.TangentOnS2());
737 }
738 Arrive = Standard_True;
739 }
740 break;
7fd59977 741 default:
742 break;
7fd59977 743 }
744 if (Arrive) {
745 if (sens > 0.) {
746 line->SetEndPoints(Ext1,Ext2);
747 }
748 else {
749 line->SetStartPoints(Ext1,Ext2);
750
751 }
752 }
753
754 }
755
756}
af99433e 757
758Standard_Boolean Blend_Walking::CorrectExtremityOnOneRst(const Standard_Integer IndexOfRst,
759 const Standard_Real theU,
760 const Standard_Real theV,
761 const Standard_Real theParam,
762 const gp_Pnt& thePntOnRst,
763 Standard_Real& NewU,
764 Standard_Real& NewV,
765 gp_Pnt& NewPoint,
766 Standard_Real& NewParam) const
767{
768 const Standard_Real TolAng = 0.001; //bug OCC25701
769
c22b52d6 770 ChFiDS_ElSpine& theElSpine = *hguide;
af99433e 771 if (theElSpine.NbVertices() == 0)
772 return Standard_False;
773
774 Handle(TheTopolTool) DomainOfRst = (IndexOfRst == 1)? recdomain1 : recdomain2;
775 TheSurface SurfOfRst = (IndexOfRst == 1)? surf1 : surf2;
776 TheSurface AnotherSurf = (IndexOfRst == 1)? surf2 : surf1;
777
778 //Correct point on surface 2
779 //First we find right <param>
780 Standard_Real Ends [2];
781 Ends[0] = TheArcTool::FirstParameter(DomainOfRst->Value());
782 Ends[1] = TheArcTool::LastParameter(DomainOfRst->Value());
783 Standard_Real GlobalMinSqDist = Precision::Infinite();
784 Standard_Real ParamOnGuide = 0;
785 gp_Pnt PointOnGuide;
786 for (Standard_Integer k = 0; k < 2; k++)
787 {
788 gp_Pnt2d P2dOnEnd = TheArcTool::Value(DomainOfRst->Value(), Ends[k]);
789 gp_Pnt PntOnEnd = TheSurfaceTool::Value(SurfOfRst, P2dOnEnd.X(), P2dOnEnd.Y());
790 Extrema_ExtPC projoncurv(PntOnEnd, theElSpine);
791 if (!projoncurv.IsDone())
792 continue;
793 Standard_Real MinSqDist = Precision::Infinite();
794 Standard_Integer imin = 0;
795 for (Standard_Integer ind = 1; ind <= projoncurv.NbExt(); ind++)
796 {
797 Standard_Real aSqDist = projoncurv.SquareDistance(ind);
798 if (aSqDist < MinSqDist)
799 {
800 MinSqDist = aSqDist;
801 imin = ind;
802 }
803 }
804 if (MinSqDist < GlobalMinSqDist)
805 {
806 GlobalMinSqDist = MinSqDist;
807 ParamOnGuide = projoncurv.Point(imin).Parameter();
808 PointOnGuide = projoncurv.Point(imin).Value();
809 }
810 }
811 NewParam = ParamOnGuide;
812 if (hguide->IsPeriodic())
813 {
814 Standard_Real Period = hguide->Period();
815 Standard_Real sign = (NewParam < theParam)? 1 : -1;
816 while (Abs(NewParam - theParam) > Period/2)
817 NewParam += sign *Period;
818 }
819
820 //Second we find right point and tangent on guide
821 GlobalMinSqDist = Precision::Infinite();
822 gp_Ax1 theAx1;
823 for (Standard_Integer ind = 1; ind <= theElSpine.NbVertices(); ind++)
824 {
825 const gp_Ax1& anAx1 = theElSpine.VertexWithTangent(ind);
826 gp_Pnt aPnt = anAx1.Location();
827 Standard_Real aSqDist = PointOnGuide.SquareDistance(aPnt);
828 if (aSqDist < GlobalMinSqDist)
829 {
830 GlobalMinSqDist = aSqDist;
831 theAx1 = anAx1;
832 }
833 }
834 const gp_Pnt& Pnt0 = theAx1.Location();
835 const gp_Dir& Dir0 = theAx1.Direction();
836 //Check new point: is it real solution?
837 gp_Pnt OldPonGuide = hguide->Value(theParam);
838 gp_Pnt PntOnSurf2 = TheSurfaceTool::Value(AnotherSurf,theU,theV); //old point
839 gce_MakePln PlaneBuilder(thePntOnRst, OldPonGuide, PntOnSurf2);
840 if (!PlaneBuilder.IsDone())
841 return Standard_False;
842 gp_Pln OldPlane = PlaneBuilder.Value();
843 gp_Dir OldDir = OldPlane.Axis().Direction();
844 Standard_Real Angle = OldDir.Angle(Dir0);
845 if (Angle > M_PI/2)
846 Angle = M_PI - Angle;
847 if (Angle > TolAng)
848 return Standard_False;
849 ///////////////////////////////////////
850 //Project the point(theU,theV) on the plane(Pnt0,Dir0)
851 gp_Vec aVec(Pnt0, PntOnSurf2);
852 gp_Vec aTranslation( (aVec.XYZ() * Dir0.XYZ()) * Dir0.XYZ() );
853 gp_Pnt PntOnPlane = PntOnSurf2.Translated(-aTranslation);
854
855 //Check new point again: does point on restriction belong to the plane?
856 PlaneBuilder = gce_MakePln(thePntOnRst, Pnt0, PntOnPlane);
857 if (!PlaneBuilder.IsDone())
858 return Standard_False;
859 gp_Pln NewPlane = PlaneBuilder.Value();
860 const gp_Dir& DirOfNewPlane = NewPlane.Axis().Direction();
861 Angle = Dir0.Angle(DirOfNewPlane);
862 if (Angle > M_PI/2)
863 Angle = M_PI - Angle;
864 if (Angle > TolAng)
865 return Standard_False;
866 ////////////////////////////////////////////////////////////////////////
867
868 //Project the point <PntOnPlane> on the surface 2
c22b52d6 869 Extrema_ExtPS projonsurf(PntOnPlane, *AnotherSurf,
af99433e 870 Precision::PConfusion(), Precision::PConfusion(),
871 Extrema_ExtFlag_MIN);
872 if (projonsurf.IsDone())
873 {
874 Standard_Real MinSqDist = Precision::Infinite();
875 Standard_Integer imin = 0;
876 for (Standard_Integer ind = 1; ind <= projonsurf.NbExt(); ind++)
877 {
878 Standard_Real aSqDist = projonsurf.SquareDistance(ind);
879 if (aSqDist < MinSqDist)
880 {
881 MinSqDist = aSqDist;
882 imin = ind;
883 }
884 }
885 if (imin)
886 {
887 Extrema_POnSurf NewPOnSurf2 = projonsurf.Point(imin);
888 NewPoint = NewPOnSurf2.Value();
889 NewPOnSurf2.Parameter(NewU, NewV);
890 Standard_Real uperiod = (AnotherSurf->IsUPeriodic())? AnotherSurf->UPeriod() : 0.;
891 Standard_Real vperiod = (AnotherSurf->IsVPeriodic())? AnotherSurf->VPeriod() : 0.;
892 RecadreIfPeriodic(NewU, NewV, theU, theV,
893 uperiod, vperiod);
894 return Standard_True;
895 }
896 }
897
898 return Standard_False;
899}