1 static void evalpinit(math_Vector& parinit,
2 const Blend_Point& previousP,
3 const Standard_Real parprec,
4 const Standard_Real param,
5 const math_Vector& infbound,
6 const math_Vector& supbound,
7 const Standard_Boolean classonS1,
8 const Standard_Boolean classonS2)
10 if(previousP.IsTangencyPoint()){
11 previousP.ParametersOnS1(parinit(1),parinit(2));
12 previousP.ParametersOnS2(parinit(3),parinit(4));
15 Standard_Real u1,v1,u2,v2;
16 Standard_Real du1,dv1,du2,dv2;
17 Standard_Boolean Inside=Standard_True;
18 previousP.ParametersOnS1(u1,v1);
19 previousP.ParametersOnS2(u2,v2);
20 previousP.Tangent2dOnS1().Coord(du1,dv1);
21 previousP.Tangent2dOnS2().Coord(du2,dv2);
22 Standard_Real step = param - parprec;
26 if ((u1<infbound(1)) || (u1>supbound(1))) Inside=Standard_False;
27 if ((v1<infbound(2)) || (v1>supbound(2))) Inside=Standard_False;
32 if ((u2<infbound(3)) || (u2>supbound(3))) Inside=Standard_False;
33 if ((v2<infbound(4)) || (v2>supbound(4))) Inside=Standard_False;
42 else { // on ne joue pas au plus malin
43 previousP.ParametersOnS1(parinit(1),parinit(2));
44 previousP.ParametersOnS2(parinit(3),parinit(4));
52 void Blend_Walking::InternalPerform(Blend_Function& Func,
53 Blend_FuncInv& FuncInv,
54 const Standard_Real Bound)
57 Standard_Real stepw = pasmax;
58 Standard_Integer nbp = line->NbPoints();
59 if(nbp >= 2){ //On reprend le dernier step s'il n est pas trop petit.
61 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
64 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
66 stepw = Max(stepw,100.*tolgui);
68 Standard_Real parprec = param;
70 if (sens*(parprec - Bound) >= -tolgui) {
73 Blend_Status State = Blend_OnRst12;
74 TopAbs_State situ1 =TopAbs_IN,situ2=TopAbs_IN;
76 Standard_Integer Index1,Index2,nbarc;
77 Standard_Boolean Arrive,recad1,recad2, control;
78 Standard_Boolean Isvtx1,Isvtx2,echecrecad;
80 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
81 math_Vector solrst1(1,4),solrst2(1,4);
83 TheExtremity Ext1,Ext2;
85 //IntSurf_Transition Tline,Tarc;
87 Func.GetTolerance(tolerance,tolesp);
88 Func.GetBounds(infbound,supbound);
90 math_FunctionSetRoot rsnld(Func,tolerance,30);
93 Arrive = Standard_False;
94 param = parprec + sens*stepw;
95 if(sens *(param - Bound) > 0.) {
96 stepw = sens*(Bound - parprec)*0.5;
97 param = parprec + sens*stepw;
100 evalpinit(parinit,previousP,parprec,param,
101 infbound,supbound, clasonS1, clasonS2);
109 Standard_Boolean bonpoint = 1;
111 rsnld.Perform(Func,parinit,infbound,supbound);
113 if (!rsnld.IsDone()) {
114 State = Blend_StepTooLarge;
120 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
121 Min(tolerance(1),tolerance(2)),0);
122 else situ1 = TopAbs_IN;
123 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
124 Min(tolerance(3),tolerance(4)),0);
125 else situ2 = TopAbs_IN;
127 if(bonpoint && line->NbPoints() == 1 && (situ1 != TopAbs_IN || situ2 != TopAbs_IN)){
128 State = Blend_StepTooLarge;
133 recad1 = Standard_False;
134 recad2 = Standard_False;
135 echecrecad = Standard_False;
136 control = Standard_False;
138 if (situ1 == TopAbs_OUT || situ1 == TopAbs_ON) {
139 // pb inverse sur surf1
140 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
141 //on a pris la mauvaise solution.
142 recad1 = Recadre(FuncInv,Standard_True,
143 sol,solrst1,Index1,Isvtx1,Vtx1);
148 if ((param - wtemp)/sens>= -10*tolesp){
150 control = Standard_True;
153 echecrecad = Standard_True;
154 recad1 = Standard_False;
155 State = Blend_StepTooLarge;
161 echecrecad = Standard_True;
164 if (situ2 == TopAbs_OUT || situ2 == TopAbs_ON) {
165 // pb inverse sur surf2
166 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
167 //on a pris la mauvaise solution.
168 recad2 = Recadre(FuncInv,Standard_False,
169 sol,solrst2,Index2,Isvtx2,Vtx2);
174 if ((param - wtemp)/sens>= -10*tolesp){
176 control = Standard_True;
179 echecrecad = Standard_True;
180 recad2 = Standard_False;
181 State = Blend_StepTooLarge;
187 echecrecad = Standard_True;
191 // Que faut il controler
192 if (recad1 && recad2) {
193 if (Abs(w1-w2) <= 10*tolgui) {
194 // pas besoin de controler les recadrage
195 // Le control pouvant se planter (cf model blend10)
196 // La tolerance est choisie grossse afin, de permetre au
197 // cheminement suivant, de poser quelques sections ...
198 control = Standard_False;
200 else if (sens*(w1-w2) < 0.) {
202 recad2 = Standard_False;
206 recad1 = Standard_False;
210 // Controle effectif des recadrage
213 if (recad1 && clasonS2) {
214 situ = recdomain2->Classify(gp_Pnt2d(solrst1(3),solrst1(4)),
215 Min(tolerance(3),tolerance(4)));
216 if (situ == TopAbs_OUT) {
217 recad1 = Standard_False;
218 echecrecad = Standard_True;
221 else if (recad2 && clasonS1) {
222 situ = recdomain1->Classify(gp_Pnt2d(solrst2(3),solrst2(4)),
223 Min(tolerance(1),tolerance(1)));
224 if (situ == TopAbs_OUT) {
225 recad2 = Standard_False;
226 echecrecad = Standard_True;
231 if(recad1 || recad2) echecrecad = Standard_False;
234 if (recad1 && recad2) {
235 //sol sur 1 et 2 a la fois
236 // On passe par les arcs , pour ne pas avoir de probleme
237 // avec les surfaces periodiques.
238 State = Blend_OnRst12;
240 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
243 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
249 State = Blend_OnRst1;
253 while (nbarc < Index1) {
257 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
265 State = Blend_OnRst2;
270 while (nbarc < Index2) {
274 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
284 Standard_Boolean testdefl = 1;
286 testdefl = !Blend_GetcontextNOTESTDEFL();
288 if (recad1 || recad2) {
290 // Il vaut mieux un pas non orthodoxe que pas de recadrage!! PMN
291 State = TestArret(Func, State,
292 (testdefl && (Abs(stepw) > 3*tolgui)),
293 Standard_False, Standard_True);
296 State = TestArret(Func, State, testdefl);
300 // Ou bien le pas max est mal regle. On divise.
301 // if(line->NbPoints() == 1) State = Blend_StepTooLarge;
302 if (stepw > 2*tolgui) State = Blend_StepTooLarge;
303 // Sinon echec recadrage. On sort avec PointsConfondus
306 cout << "Echec recadrage" << endl;
308 State = Blend_SamePoints;
314 if (Blend_GettraceDRAWSECT()){
315 Drawsect(surf1,surf2,sol,param,Func, State);
321 // Mettre a jour la ligne.
323 line->Append(previousP);
326 line->Prepend(previousP);
331 if (param == Bound) {
332 Arrive = Standard_True;
333 Ext1.SetValue(previousP.PointOnS1(),
335 previousP.Parameter(), tolesp);
336 Ext2.SetValue(previousP.PointOnS2(),
338 previousP.Parameter(), tolesp);
339 if (!previousP.IsTangencyPoint()) {
340 Ext1.SetTangent(previousP.TangentOnS1());
341 Ext2.SetTangent(previousP.TangentOnS2());
344 // Indiquer que fin sur Bound.
347 param = param + sens*stepw;
348 if (sens*(param - Bound) > - tolgui) {
352 evalpinit(parinit,previousP,parprec,param,
353 infbound,supbound, clasonS1, clasonS2);
357 case Blend_StepTooLarge :
360 if (Abs(stepw) < tolgui) {
361 Ext1.SetValue(previousP.PointOnS1(),
363 previousP.Parameter(),tolesp);
364 Ext2.SetValue(previousP.PointOnS2(),
366 previousP.Parameter(),tolesp);
367 if (!previousP.IsTangencyPoint()) {
368 Ext1.SetTangent(previousP.TangentOnS1());
369 Ext2.SetTangent(previousP.TangentOnS2());
371 Arrive = Standard_True;
372 if (line->NbPoints()>=2) {
373 // Indiquer qu on s arrete en cours de cheminement
380 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
381 evalpinit(parinit,previousP,parprec,param,
382 infbound,supbound, clasonS1, clasonS2);
387 case Blend_StepTooSmall :
389 // Mettre a jour la ligne.
391 line->Append(previousP);
394 line->Prepend(previousP);
399 stepw = Min(1.5*stepw,pasmax);
400 if (param == Bound) {
401 Arrive = Standard_True;
402 Ext1.SetValue(previousP.PointOnS1(),
404 previousP.Parameter(),tolesp);
405 Ext2.SetValue(previousP.PointOnS2(),
407 previousP.Parameter(),tolesp);
408 if (!previousP.IsTangencyPoint()) {
409 Ext1.SetTangent(previousP.TangentOnS1());
410 Ext2.SetTangent(previousP.TangentOnS2());
412 // Indiquer que fin sur Bound.
415 param = param + sens*stepw;
416 if (sens*(param - Bound) > - tolgui) {
420 evalpinit(parinit,previousP,parprec,param,
421 infbound,supbound, clasonS1, clasonS2);
428 line->Append(previousP);
431 line->Prepend(previousP);
433 MakeExtremity(Ext1,Standard_True,Index1,
434 solrst1(1),Isvtx1,Vtx1);
435 // On blinde le cas singulier ou un des recadrage a planter
436 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
437 Ext2.SetValue(previousP.PointOnS1(),
438 sol(3),sol(4),tolesp);
439 if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
442 Ext2.SetValue(previousP.PointOnS2(),
444 previousP.Parameter(),tolesp);
446 Arrive = Standard_True;
453 line->Append(previousP);
456 line->Prepend(previousP);
458 // On blinde le cas singulier ou un des recadrage a plante
459 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
460 Ext1.SetValue(previousP.PointOnS2(),
461 sol(1),sol(2),tolesp);
462 if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
465 Ext1.SetValue(previousP.PointOnS1(),
467 previousP.Parameter(),tolesp);
469 MakeExtremity(Ext2,Standard_False,Index2,
470 solrst2(1),Isvtx2,Vtx2);
471 Arrive = Standard_True;
479 line->Append(previousP);
482 line->Prepend(previousP);
485 if ( (Isvtx1 != Isvtx2) &&
486 (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) ) {
487 // On blinde le cas singulier ou un seul recadrage
488 // est reconnu comme vertex.
490 Isvtx2 = Standard_True;
494 Isvtx1 = Standard_True;
499 MakeExtremity(Ext1,Standard_True,Index1,
500 solrst1(1),Isvtx1,Vtx1);
501 MakeExtremity(Ext2,Standard_False,Index2,
502 solrst2(1),Isvtx2,Vtx2);
503 Arrive = Standard_True;
507 case Blend_SamePoints :
511 cout << " Points confondus dans le cheminement" << endl;
513 Ext1.SetValue(previousP.PointOnS1(),
515 previousP.Parameter(),tolesp);
516 Ext2.SetValue(previousP.PointOnS2(),
518 previousP.Parameter(),tolesp);;
519 if (!previousP.IsTangencyPoint()) {
520 Ext1.SetTangent(previousP.TangentOnS1());
521 Ext2.SetTangent(previousP.TangentOnS2());
523 Arrive = Standard_True;
533 line->SetEndPoints(Ext1,Ext2);
536 line->SetStartPoints(Ext1,Ext2);