0024059: Eliminate compiler warning C4701 in MSVC++ with warning level 4
[occt.git] / src / Blend / Blend_Walking_4.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19static void evalpinit(math_Vector& parinit,
20 const Blend_Point& previousP,
21 const Standard_Real parprec,
22 const Standard_Real param,
23 const math_Vector& infbound,
24 const math_Vector& supbound,
25 const Standard_Boolean classonS1,
26 const Standard_Boolean classonS2)
27{
28 if(previousP.IsTangencyPoint()){
29 previousP.ParametersOnS1(parinit(1),parinit(2));
30 previousP.ParametersOnS2(parinit(3),parinit(4));
31 }
32 else {
33 Standard_Real u1,v1,u2,v2;
34 Standard_Real du1,dv1,du2,dv2;
35 Standard_Boolean Inside=Standard_True;
36 previousP.ParametersOnS1(u1,v1);
37 previousP.ParametersOnS2(u2,v2);
38 previousP.Tangent2dOnS1().Coord(du1,dv1);
39 previousP.Tangent2dOnS2().Coord(du2,dv2);
40 Standard_Real step = param - parprec;
41 u1+= step*du1;
42 v1+= step*dv1;
43 if ( classonS1 ) {
44 if ((u1<infbound(1)) || (u1>supbound(1))) Inside=Standard_False;
45 if ((v1<infbound(2)) || (v1>supbound(2))) Inside=Standard_False;
46 }
47 u2+= step*du2;
48 v2+= step*dv2;
49 if ( classonS2) {
50 if ((u2<infbound(3)) || (u2>supbound(3))) Inside=Standard_False;
51 if ((v2<infbound(4)) || (v2>supbound(4))) Inside=Standard_False;
52 }
53
54 if (Inside) {
55 parinit(1) = u1;
56 parinit(2) = v1;
57 parinit(3) = u2;
58 parinit(4) = v2;
59 }
60 else { // on ne joue pas au plus malin
61 previousP.ParametersOnS1(parinit(1),parinit(2));
62 previousP.ParametersOnS2(parinit(3),parinit(4));
63 }
64
65 }
66}
67
68
69
70void Blend_Walking::InternalPerform(Blend_Function& Func,
71 Blend_FuncInv& FuncInv,
72 const Standard_Real Bound)
73{
74
75 Standard_Real stepw = pasmax;
76 Standard_Integer nbp = line->NbPoints();
77 if(nbp >= 2){ //On reprend le dernier step s'il n est pas trop petit.
78 if(sens < 0.){
79 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
80 }
81 else{
82 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
83 }
84 stepw = Max(stepw,100.*tolgui);
85 }
86 Standard_Real parprec = param;
87
88 if (sens*(parprec - Bound) >= -tolgui) {
89 return;
90 }
91 Blend_Status State = Blend_OnRst12;
92 TopAbs_State situ1 =TopAbs_IN,situ2=TopAbs_IN;
93 Standard_Real w1,w2;
1d47d8d0 94 Standard_Integer Index1 = 0, Index2 = 0, nbarc;
7fd59977 95 Standard_Boolean Arrive,recad1,recad2, control;
1d47d8d0 96 Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False, echecrecad;
7fd59977 97 gp_Pnt2d p2d;
98 math_Vector tolerance(1,4),infbound(1,4),supbound(1,4),parinit(1,4);
99 math_Vector solrst1(1,4),solrst2(1,4);
100 TheVertex Vtx1,Vtx2;
101 TheExtremity Ext1,Ext2;
102
103 //IntSurf_Transition Tline,Tarc;
104
105 Func.GetTolerance(tolerance,tolesp);
106 Func.GetBounds(infbound,supbound);
107
108 math_FunctionSetRoot rsnld(Func,tolerance,30);
109 parinit = sol;
110
111 Arrive = Standard_False;
112 param = parprec + sens*stepw;
113 if(sens *(param - Bound) > 0.) {
114 stepw = sens*(Bound - parprec)*0.5;
115 param = parprec + sens*stepw;
116 }
117
118 evalpinit(parinit,previousP,parprec,param,
119 infbound,supbound, clasonS1, clasonS2);
120
121 while (!Arrive) {
122
123#ifdef DEB
124 sectioncalculee = 0;
125 nbcomputedsection++;
126#endif
127 Standard_Boolean bonpoint = 1;
128 Func.Set(param);
129 rsnld.Perform(Func,parinit,infbound,supbound);
130
131 if (!rsnld.IsDone()) {
132 State = Blend_StepTooLarge;
133 bonpoint = 0;
134 }
135 else {
136 rsnld.Root(sol);
137
138 if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
139 Min(tolerance(1),tolerance(2)),0);
140 else situ1 = TopAbs_IN;
141 if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
142 Min(tolerance(3),tolerance(4)),0);
143 else situ2 = TopAbs_IN;
144 }
145 if(bonpoint && line->NbPoints() == 1 && (situ1 != TopAbs_IN || situ2 != TopAbs_IN)){
146 State = Blend_StepTooLarge;
147 bonpoint = 0;
148 }
149 if(bonpoint){
150 w1 = w2 = Bound;
151 recad1 = Standard_False;
152 recad2 = Standard_False;
153 echecrecad = Standard_False;
154 control = Standard_False;
155
156 if (situ1 == TopAbs_OUT || situ1 == TopAbs_ON) {
157 // pb inverse sur surf1
158 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
159 //on a pris la mauvaise solution.
160 recad1 = Recadre(FuncInv,Standard_True,
161 sol,solrst1,Index1,Isvtx1,Vtx1);
162
163 if (recad1) {
164 Standard_Real wtemp;
165 wtemp = solrst1(2);
166 if ((param - wtemp)/sens>= -10*tolesp){
167 w1 = solrst1(2);
168 control = Standard_True;
169 }
170 else {
171 echecrecad = Standard_True;
172 recad1 = Standard_False;
173 State = Blend_StepTooLarge;
174 bonpoint = 0;
175 stepw = stepw/2.;
176 }
177 }
178 else {
179 echecrecad = Standard_True;
180 }
181 }
182 if (situ2 == TopAbs_OUT || situ2 == TopAbs_ON) {
183 // pb inverse sur surf2
184 //Si le recadrage s'effectue dans le sens de la progression a une tolerance pres,
185 //on a pris la mauvaise solution.
186 recad2 = Recadre(FuncInv,Standard_False,
187 sol,solrst2,Index2,Isvtx2,Vtx2);
188
189 if (recad2) {
190 Standard_Real wtemp;
191 wtemp = solrst2(2);
192 if ((param - wtemp)/sens>= -10*tolesp){
193 w2 = solrst2(2);
194 control = Standard_True;
195 }
196 else {
197 echecrecad = Standard_True;
198 recad2 = Standard_False;
199 State = Blend_StepTooLarge;
200 bonpoint = 0;
201 stepw = stepw/2.;
202 }
203 }
204 else {
205 echecrecad = Standard_True;
206 }
207 }
208
209 // Que faut il controler
210 if (recad1 && recad2) {
211 if (Abs(w1-w2) <= 10*tolgui) {
212 // pas besoin de controler les recadrage
213 // Le control pouvant se planter (cf model blend10)
214 // La tolerance est choisie grossse afin, de permetre au
215 // cheminement suivant, de poser quelques sections ...
216 control = Standard_False;
217 }
218 else if (sens*(w1-w2) < 0.) {
219 //sol sur 1 ?
220 recad2 = Standard_False;
221 }
222 else {
223 //sol sur 2 ?
224 recad1 = Standard_False;
225 }
226 }
227
228 // Controle effectif des recadrage
229 if (control) {
230 TopAbs_State situ;
231 if (recad1 && clasonS2) {
232 situ = recdomain2->Classify(gp_Pnt2d(solrst1(3),solrst1(4)),
233 Min(tolerance(3),tolerance(4)));
234 if (situ == TopAbs_OUT) {
235 recad1 = Standard_False;
236 echecrecad = Standard_True;
237 }
238 }
239 else if (recad2 && clasonS1) {
240 situ = recdomain1->Classify(gp_Pnt2d(solrst2(3),solrst2(4)),
241 Min(tolerance(1),tolerance(1)));
242 if (situ == TopAbs_OUT) {
243 recad2 = Standard_False;
244 echecrecad = Standard_True;
245 }
246 }
247 }
248
249 if(recad1 || recad2) echecrecad = Standard_False;
250
251 if (!echecrecad) {
252 if (recad1 && recad2) {
253 //sol sur 1 et 2 a la fois
254 // On passe par les arcs , pour ne pas avoir de probleme
255 // avec les surfaces periodiques.
256 State = Blend_OnRst12;
257 param = (w1+w2)/2;
258 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
259 sol(1) = p2d.X();
260 sol(2) = p2d.Y();
261 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
262 sol(3) = p2d.X();
263 sol(4) = p2d.Y();
264 }
265 else if (recad1) {
266 // sol sur 1
267 State = Blend_OnRst1;
268 param = w1;
269 recdomain1->Init();
270 nbarc = 1;
271 while (nbarc < Index1) {
272 nbarc++;
273 recdomain1->Next();
274 }
275 p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
276 sol(1) = p2d.X();
277 sol(2) = p2d.Y();
278 sol(3) = solrst1(3);
279 sol(4) = solrst1(4);
280 }
281 else if (recad2) {
282 //sol sur 2
283 State = Blend_OnRst2;
284 param = w2;
285
286 recdomain2->Init();
287 nbarc = 1;
288 while (nbarc < Index2) {
289 nbarc++;
290 recdomain2->Next();
291 }
292 p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
293 sol(1) = solrst2(3);
294 sol(2) = solrst2(4);
295 sol(3) = p2d.X();
296 sol(4) = p2d.Y();
297 }
298 else {
299 State = Blend_OK;
300 }
301
302 Standard_Boolean testdefl = 1;
303#ifdef DEB
304 testdefl = !Blend_GetcontextNOTESTDEFL();
305#endif
306 if (recad1 || recad2) {
307 Func.Set(param);
308 // Il vaut mieux un pas non orthodoxe que pas de recadrage!! PMN
309 State = TestArret(Func, State,
310 (testdefl && (Abs(stepw) > 3*tolgui)),
311 Standard_False, Standard_True);
312 }
313 else {
314 State = TestArret(Func, State, testdefl);
315 }
316 }
317 else {
318 // Ou bien le pas max est mal regle. On divise.
319// if(line->NbPoints() == 1) State = Blend_StepTooLarge;
320 if (stepw > 2*tolgui) State = Blend_StepTooLarge;
321 // Sinon echec recadrage. On sort avec PointsConfondus
322 else {
323#if DEB
324 cout << "Echec recadrage" << endl;
325#endif
326 State = Blend_SamePoints;
327 }
328 }
329 }
330
331#ifdef DEB
332 if (Blend_GettraceDRAWSECT()){
333 Drawsect(surf1,surf2,sol,param,Func, State);
334 }
335#endif
336 switch (State) {
337 case Blend_OK :
338 {
339 // Mettre a jour la ligne.
340 if (sens>0.) {
341 line->Append(previousP);
342 }
343 else {
344 line->Prepend(previousP);
345 }
346
347 parprec = param;
348
349 if (param == Bound) {
350 Arrive = Standard_True;
351 Ext1.SetValue(previousP.PointOnS1(),
352 sol(1),sol(2),
353 previousP.Parameter(), tolesp);
354 Ext2.SetValue(previousP.PointOnS2(),
355 sol(3),sol(4),
356 previousP.Parameter(), tolesp);
357 if (!previousP.IsTangencyPoint()) {
358 Ext1.SetTangent(previousP.TangentOnS1());
359 Ext2.SetTangent(previousP.TangentOnS2());
360 }
361
362 // Indiquer que fin sur Bound.
363 }
364 else {
365 param = param + sens*stepw;
366 if (sens*(param - Bound) > - tolgui) {
367 param = Bound;
368 }
369 }
370 evalpinit(parinit,previousP,parprec,param,
371 infbound,supbound, clasonS1, clasonS2);
372 }
373 break;
374
375 case Blend_StepTooLarge :
376 {
377 stepw = stepw/2.;
378 if (Abs(stepw) < tolgui) {
379 Ext1.SetValue(previousP.PointOnS1(),
380 sol(1),sol(2),
381 previousP.Parameter(),tolesp);
382 Ext2.SetValue(previousP.PointOnS2(),
383 sol(3),sol(4),
384 previousP.Parameter(),tolesp);
385 if (!previousP.IsTangencyPoint()) {
386 Ext1.SetTangent(previousP.TangentOnS1());
387 Ext2.SetTangent(previousP.TangentOnS2());
388 }
389 Arrive = Standard_True;
390 if (line->NbPoints()>=2) {
391 // Indiquer qu on s arrete en cours de cheminement
392 }
393// else {
394// line->Clear();
395// }
396 }
397 else {
398 param = parprec + sens*stepw; // on ne risque pas de depasser Bound.
399 evalpinit(parinit,previousP,parprec,param,
400 infbound,supbound, clasonS1, clasonS2);
401 }
402 }
403 break;
404
405 case Blend_StepTooSmall :
406 {
407 // Mettre a jour la ligne.
408 if (sens>0.) {
409 line->Append(previousP);
410 }
411 else {
412 line->Prepend(previousP);
413 }
414
415 parprec = param;
416
417 stepw = Min(1.5*stepw,pasmax);
418 if (param == Bound) {
419 Arrive = Standard_True;
420 Ext1.SetValue(previousP.PointOnS1(),
421 sol(1),sol(2),
422 previousP.Parameter(),tolesp);
423 Ext2.SetValue(previousP.PointOnS2(),
424 sol(3),sol(4),
425 previousP.Parameter(),tolesp);
426 if (!previousP.IsTangencyPoint()) {
427 Ext1.SetTangent(previousP.TangentOnS1());
428 Ext2.SetTangent(previousP.TangentOnS2());
429 }
430 // Indiquer que fin sur Bound.
431 }
432 else {
433 param = param + sens*stepw;
434 if (sens*(param - Bound) > - tolgui) {
435 param = Bound;
436 }
437 }
438 evalpinit(parinit,previousP,parprec,param,
439 infbound,supbound, clasonS1, clasonS2);
440 }
441 break;
442
443 case Blend_OnRst1 :
444 {
445 if (sens>0.) {
446 line->Append(previousP);
447 }
448 else {
449 line->Prepend(previousP);
450 }
451 MakeExtremity(Ext1,Standard_True,Index1,
452 solrst1(1),Isvtx1,Vtx1);
453 // On blinde le cas singulier ou un des recadrage a planter
454 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
455 Ext2.SetValue(previousP.PointOnS1(),
456 sol(3),sol(4),tolesp);
457 if (Isvtx1) MakeSingularExtremity(Ext2, Standard_False, Vtx1);
458 }
459 else {
460 Ext2.SetValue(previousP.PointOnS2(),
461 sol(3),sol(4),
462 previousP.Parameter(),tolesp);
463 }
464 Arrive = Standard_True;
465 }
466 break;
467
468 case Blend_OnRst2 :
469 {
470 if (sens>0.) {
471 line->Append(previousP);
472 }
473 else {
474 line->Prepend(previousP);
475 }
476 // On blinde le cas singulier ou un des recadrage a plante
477 if (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) {
478 Ext1.SetValue(previousP.PointOnS2(),
479 sol(1),sol(2),tolesp);
480 if (Isvtx2) MakeSingularExtremity(Ext1, Standard_True, Vtx2);
481 }
482 else {
483 Ext1.SetValue(previousP.PointOnS1(),
484 sol(1),sol(2),
485 previousP.Parameter(),tolesp);
486 }
487 MakeExtremity(Ext2,Standard_False,Index2,
488 solrst2(1),Isvtx2,Vtx2);
489 Arrive = Standard_True;
490 }
491 break;
492
493
494 case Blend_OnRst12 :
495 {
496 if (sens>0.) {
497 line->Append(previousP);
498 }
499 else {
500 line->Prepend(previousP);
501 }
502
503 if ( (Isvtx1 != Isvtx2) &&
504 (previousP.PointOnS1().IsEqual(previousP.PointOnS2(), 2*tolesp)) ) {
505 // On blinde le cas singulier ou un seul recadrage
506 // est reconnu comme vertex.
507 if (Isvtx1) {
508 Isvtx2 = Standard_True;
509 Vtx2 = Vtx1;
510 }
511 else {
512 Isvtx1 = Standard_True;
513 Vtx1 = Vtx2;
514 }
515 }
516
517 MakeExtremity(Ext1,Standard_True,Index1,
518 solrst1(1),Isvtx1,Vtx1);
519 MakeExtremity(Ext2,Standard_False,Index2,
520 solrst2(1),Isvtx2,Vtx2);
521 Arrive = Standard_True;
522 }
523 break;
524
525 case Blend_SamePoints :
526 {
527 // On arrete
528#if DEB
529 cout << " Points confondus dans le cheminement" << endl;
530#endif
531 Ext1.SetValue(previousP.PointOnS1(),
532 sol(1),sol(2),
533 previousP.Parameter(),tolesp);
534 Ext2.SetValue(previousP.PointOnS2(),
535 sol(3),sol(4),
536 previousP.Parameter(),tolesp);;
537 if (!previousP.IsTangencyPoint()) {
538 Ext1.SetTangent(previousP.TangentOnS1());
539 Ext2.SetTangent(previousP.TangentOnS2());
540 }
541 Arrive = Standard_True;
542 }
543 break;
544#ifndef DEB
545 default:
546 break;
547#endif
548 }
549 if (Arrive) {
550 if (sens > 0.) {
551 line->SetEndPoints(Ext1,Ext2);
552 }
553 else {
554 line->SetStartPoints(Ext1,Ext2);
555
556 }
557 }
558
559 }
560
561}