0024059: Eliminate compiler warning C4701 in MSVC++ with warning level 4
[occt.git] / src / Blend / Blend_Walking_3.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 19//26-04-1997 modified by pmn : Initialisation plus fine de la resolution
20
21Standard_Integer Blend_Walking::ArcToRecadre(const Standard_Boolean OnFirst,
22 const math_Vector& sol,
23 const Standard_Integer PrevIndex,
24 gp_Pnt2d& lastpt2d,
25 gp_Pnt2d& pt2d,
26 Standard_Real& ponarc)
27{
28 Standard_Integer IndexSol = 0, nbarc = 0;
29 Standard_Boolean ok = Standard_False;
30 Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
31 Standard_Real distmin = RealLast();
1d47d8d0 32 Standard_Real uprev = 0.,vprev = 0., prm = 0., dist = 0.;
7fd59977 33 Handle(TheTopolTool) Iter;
34
35 if (OnFirst) {
36 if(byinter) previousP.ParametersOnS1(uprev,vprev);
37 pt2d.SetCoord(sol(1),sol(2));
38 Iter = recdomain1;
39 }
40 else {
41 if(byinter) previousP.ParametersOnS2(uprev,vprev);
42 pt2d.SetCoord(sol(3),sol(4));
43 Iter = recdomain2;
44 }
45 lastpt2d.SetCoord(uprev,vprev);
46 Iter->Init();
47 while (Iter->More()) {
48 nbarc++; ok = 0;
49 if (OnFirst) {
50 if(byinter) {
51 ok = okinter = TheBlendTool::Inters(pt2d,lastpt2d,
52 surf1,Iter->Value(),prm,dist);
53 }
54 if(!ok) ok = TheBlendTool::Project(pt2d,surf1,Iter->Value(),prm,dist);
55 }
56 else {
57 if(byinter) {
58 ok = okinter = TheBlendTool::Inters(pt2d,lastpt2d,
59 surf2,Iter->Value(),prm,dist);
60 }
61 if(!ok) ok = TheBlendTool::Project(pt2d,surf2,Iter->Value(),prm,dist);
62 }
63 if (ok && (nbarc != PrevIndex) ) {
64 if (dist<distmin || okinter) {
65 distmin = dist;
66 ponarc = prm;
67 IndexSol = nbarc;
68 if(okinter && (PrevIndex==0)) break;
69 }
70 }
71 Iter->Next();
72 }
73 return IndexSol;
74}
75
76Standard_Boolean Blend_Walking::Recadre(Blend_FuncInv& FuncInv,
77 const Standard_Boolean OnFirst,
78 const math_Vector& sol,
79 math_Vector& solrst,
80 Standard_Integer& Indexsol,
81 Standard_Boolean& IsVtx,
82 TheVertex& Vtx,
83 const Standard_Real Extrap)
84
85{
86 Standard_Boolean jalons_Trouve = Standard_False;
87 Standard_Boolean recadre = Standard_True, ok;
88 Standard_Boolean byinter = (line->NbPoints() != 0);
7fd59977 89 Standard_Integer LeJalon = 0;
1d47d8d0 90
7fd59977 91 Standard_Integer nbarc;
92 Standard_Real dist,prm,pmin, vtol;
93 gp_Pnt2d pt2d, lastpt2d;
94
95 math_Vector toler(1,4),infb(1,4),supb(1,4),valsol(1,4);
96
97 Handle(Adaptor2d_HCurve2d) thecur;
98 Handle(TheTopolTool) Iter;
99
100 if (OnFirst) Iter = recdomain1;
101 else Iter = recdomain2;
102
103 Indexsol = ArcToRecadre(OnFirst, sol, 0,
104 lastpt2d, pt2d, pmin);
105 IsVtx = Standard_False;
106 if (Indexsol == 0) {
107 return Standard_False;
108 }
109
110 Iter->Init();
111 nbarc = 1;
112 while (nbarc < Indexsol) {
113 nbarc++;
114 Iter->Next();
115 }
116
117 TheArc thearc = Iter->Value();
118
119 if (OnFirst) {
120 thecur = TheBlendTool::CurveOnSurf(thearc,surf1);
121 }
122 else {
123 thecur = TheBlendTool::CurveOnSurf(thearc,surf2);
124 }
125
126// Le probleme a resoudre
127 FuncInv.Set(OnFirst,thecur);
128 FuncInv.GetBounds(infb,supb);
129 infb(2) -= Extrap;
130 supb(2) += Extrap;
131
132 FuncInv.GetTolerance(toler,tolesp/10);//Il vaut mieux garder un peu de marge
133 math_FunctionSetRoot rsnld(FuncInv,toler,35);
134 toler *= 10; // Mais on fait les tests correctements
135
136// Calcul d'un point d'init
137 Standard_Real ufirst,ulast;
138 TheBlendTool::Bounds(thecur, ufirst,ulast);
139 // Pour aider a trouver les coins singuliers on recadre eventuelement le paramtere
140 if (Abs(pmin-ufirst) < Abs(ulast-ufirst)/1000) {
141 pmin = ufirst;
142 }
143 if (Abs(pmin-ulast) < Abs(ulast-ufirst)/1000) {
144 pmin = ulast;
145 }
146
147 if (byinter) {
148 Standard_Real lastParam = previousP.Parameter();
149 // Verifie que le recadrage n'est pas un jalons
150 if (jalons.Length()!=0) {
151 Standard_Real t1, t2, t;
152 Standard_Boolean Cherche=Standard_True;
153 Standard_Integer ii;
154 if (lastParam < param) {
155 t1 = lastParam; t2 = param;
156 }
157 else {
158 t1 = param; t2 = lastParam;
159 }
160 for (ii=1; ii<=jalons.Length() && Cherche; ii++) {
161 t = jalons.Value(ii).Parameter();
162 if (((t1 < t) && (t2 > t)) || (t==param)) {
163 jalons_Trouve = Standard_True;
164 LeJalon = ii;
165 Cherche = Standard_False; //Ne marche que si l'on sort simultanement
166 }
167 else Cherche = t < t2; // On s'arrete si t>=t2;
168 }
169 }
170 if (!jalons_Trouve) {
171 //Initialisation par Interpolation
172 Standard_Real lambda, u, v;
173 gp_Pnt2d Pnt, Pnt1, Pnt2;//, POnC;
174 thecur->D0(pmin, Pnt);
175 if (OnFirst) {
176 previousP.ParametersOnS2(u,v);
177 Pnt1.SetCoord(u, v);
178 Pnt2.SetCoord(sol(3), sol(4));
179 }
180 else {
181 previousP.ParametersOnS1(u,v);
182 Pnt1.SetCoord(u, v);
183 Pnt2.SetCoord(sol(1), sol(2));
184 }
185
186 lambda = Pnt.Distance(lastpt2d);
187 if (lambda > 1.e-12) lambda /= Pnt.Distance(lastpt2d) + Pnt.Distance(pt2d);
188 else lambda = 0;
189 solrst(1) = pmin;
190 solrst(2) = (1-lambda)*lastParam + lambda*param;
191 solrst(3) = (1-lambda)*Pnt1.X() + lambda*Pnt2.X();
192 solrst(4) = (1-lambda)*Pnt1.Y() + lambda*Pnt2.Y();
193 }
194 }
195 else { // sinon on initialise par le dernier point calcule
196 solrst(1) = pmin;
197 solrst(2) = param;
198 if (OnFirst) {
199 solrst(3) = sol(3);
200 solrst(4) = sol(4);
201 }
202 else {
203 solrst(3) = sol(1);
204 solrst(4) = sol(2);
205 }
206 }
207
208 if (jalons_Trouve) { // On recupere le jalon
209 Blend_Point MonJalon;
210 Standard_Boolean periodic;
211 Standard_Real uperiod = 0, vperiod = 0;
212 gp_Pnt2d Pnt;
213 Standard_Real distaux;
214 MonJalon = jalons.Value(LeJalon);
215 solrst(2) = MonJalon.Parameter();
216 if (OnFirst) {
217 MonJalon.ParametersOnS2(solrst(3), solrst(4));
218 periodic = (surf2->IsUPeriodic() || surf2->IsVPeriodic());
219 }
220 else {
221 MonJalon.ParametersOnS1(solrst(3), solrst(4));
222 periodic = (surf1->IsUPeriodic() || surf1->IsVPeriodic());
223 }
224
225 // Recadrage eventuelle pour le cas periodique
226 if (periodic) {
227 Handle(Adaptor3d_HSurface) surf;
228 if (OnFirst) surf = surf2;
229 else surf = surf1;
230
231 lastpt2d = thecur->Value(pmin);
232
233 if (surf->IsUPeriodic()) {
234 uperiod = surf->UPeriod();
235 if (solrst(3)-lastpt2d.X() > uperiod*0.6) solrst(3) -= uperiod;
236 if (solrst(3)-lastpt2d.X() < -uperiod*0.6) solrst(3) += uperiod;
237 }
238 if (surf->IsVPeriodic()) {
239 vperiod = surf->VPeriod();
240 if (solrst(4)-lastpt2d.Y() > vperiod*0.6) solrst(4) -= vperiod;
241 if (solrst(4)-lastpt2d.Y() < -vperiod*0.6) solrst(4) += vperiod;
242 }
243 }
244
245 // Pour le parametre sur arc il faut projeter...
246 pt2d.SetCoord(solrst(3), solrst(4));
247 Pnt = thecur->Value(ufirst);
248 dist = pt2d.Distance(Pnt);
249 solrst(1) = ufirst;
250 Pnt = thecur->Value(ulast);
251 distaux = pt2d.Distance(Pnt);
252 if ( distaux < dist) {
253 solrst(1) = ulast;
254 dist = distaux;
255 }
256
257 if (dist>Precision::PConfusion()) {
258 prm = pmin;
259 if (OnFirst) {
260 ok = TheBlendTool::Project(pt2d,surf1,thearc,prm,distaux);
261 }
262 else {
263 ok = TheBlendTool::Project(pt2d,surf2,thearc,prm,distaux);
264 }
265 if (ok && (pt2d.Distance(thecur->Value(prm)) < dist)) solrst(1) = prm;
266 else solrst(1) = pmin;
267 }
268 // On verifie le jalon
269 jalons_Trouve = (FuncInv.IsSolution(solrst,tolesp));
270 }
271
272 if (!jalons_Trouve) {
273 // Resolution...
274 rsnld.Perform(FuncInv,solrst,infb,supb);
275 if (!rsnld.IsDone()) {
276 cout << "Walking::Recadre : RSNLD not done " << endl;
277 recadre = Standard_False;
278 }
279 else {
280 rsnld.Root(solrst);
281 recadre = FuncInv.IsSolution(solrst,tolesp);
282 }
283 }
284
285 // En cas d'echecs, on regarde si un autre arc
286 // peut faire l'affaire (cas des sorties a proximite d'un vertex)
287 dist = (ulast - ufirst)/100;
288 if ((!recadre) &&
289 ((Abs(pmin-ulast) < dist) || (Abs(pmin-ufirst) < dist)) ) {
290
291 Indexsol = ArcToRecadre(OnFirst, sol, Indexsol,
292 lastpt2d, pt2d, pmin);
293 if (Indexsol == 0) {
294 return Standard_False;
295 }
296
297 Iter->Init();
298 nbarc = 1;
299 while (nbarc < Indexsol) {
300 nbarc++;
301 Iter->Next();
302 }
303 thearc = Iter->Value();
304
305 if (OnFirst) {
306 thecur = TheBlendTool::CurveOnSurf(thearc,surf1);
307 }
308 else {
309 thecur = TheBlendTool::CurveOnSurf(thearc,surf2);
310 }
311 solrst(1) = pmin;
312 // Le probleme a resoudre
313 FuncInv.Set(OnFirst,thecur);
314 FuncInv.GetBounds(infb,supb);
315 FuncInv.GetTolerance(toler,tolesp/10);//Il vaut mieux garder un peu de marge
316 math_FunctionSetRoot rsnld(FuncInv,toler,35);
317 toler *= 10; // Mais on fait les tests correctements
318 // Resolution...
319 rsnld.Perform(FuncInv,solrst,infb,supb);
320
321 if (!rsnld.IsDone()) {
322 cout << "Walking::Recadre : RSNLD not done " << endl;
323 recadre = Standard_False;
324 }
325 else {
326 rsnld.Root(solrst);
327 recadre = FuncInv.IsSolution(solrst,tolesp);
328 }
329 }
330
331 if (recadre) {
332 // Classification topologique
333 if (OnFirst) {
334 thecur = TheBlendTool::CurveOnSurf(thearc,surf1);
335 }
336 else {
337 thecur = TheBlendTool::CurveOnSurf(thearc,surf2);
338 }
339 TheBlendTool::Bounds(thecur, ufirst,ulast);
340
341 Iter->Initialize(thearc);
342 Iter->InitVertexIterator();
343 IsVtx = !Iter->MoreVertex();
344 while (!IsVtx) {
345 Vtx = Iter->Vertex();
346 vtol = 0.4*Abs(ulast-ufirst); // Un majorant de la tolerance
347 if (vtol > Max(TheBlendTool::Tolerance(Vtx,thearc), toler(1)))
348 vtol = Max(TheBlendTool::Tolerance(Vtx,thearc), toler(1));
349 if (Abs(TheBlendTool::Parameter(Vtx,thearc)-solrst(1)) <= vtol) {
350 IsVtx = Standard_True; // On est dans la boule du vertex ou
351 // le vertex est dans la "boule" du recadrage
352 }
353 else {
354 Iter->NextVertex();
355 IsVtx = !Iter->MoreVertex();
356 }
357 }
358 if (!Iter->MoreVertex()) {
359 IsVtx = Standard_False;
360 }
361 return Standard_True;
362 }
363 return Standard_False;
364}
365
366
367void Blend_Walking::Transition(const Standard_Boolean OnFirst,
368 const TheArc& A,
369 const Standard_Real Param,
370 IntSurf_Transition& TLine,
371 IntSurf_Transition& TArc)
372{
373 Standard_Boolean computetranstionaveclacorde = 0;
374 gp_Vec tgline;
375 Blend_Point prevprev;
376
377 if(previousP.IsTangencyPoint()){
378 if(line->NbPoints() < 2) return;
379 computetranstionaveclacorde = 1;
380 if(sens < 0){
381 prevprev = line->Point(2);
382 }
383 else {
384 prevprev = line->Point(line->NbPoints() - 1);
385 }
386 }
387 gp_Pnt2d p2d;
388 gp_Vec2d dp2d;
389
390 gp_Pnt pbid;
391 gp_Vec d1u,d1v,normale,tgrst;
392 gp_Dir thenormal;
393 CSLib_NormalStatus stat;
394
395 TheArcTool::D1(A,Param,p2d,dp2d);
396 if (OnFirst) {
397 TheSurfaceTool::D1(surf1,p2d.X(),p2d.Y(),pbid,d1u,d1v);
398 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
399 else tgline = gp_Vec(prevprev.PointOnS1(),previousP.PointOnS1());
400 }
401 else {
402 TheSurfaceTool::D1(surf2,p2d.X(),p2d.Y(),pbid,d1u,d1v);
403 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
404 else tgline = gp_Vec(prevprev.PointOnS2(),previousP.PointOnS2());
405 }
406
407 tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
408
409 CSLib::Normal(d1u, d1v, 1.e-9, stat, thenormal);
410 if (stat == CSLib_Defined) normale.SetXYZ(thenormal.XYZ());
411 else {
412 Handle(Adaptor3d_HSurface) surf;
413 if (OnFirst) surf = surf1;
414 else surf = surf2;
415 Standard_Integer iu, iv;
416 TColgp_Array2OfVec Der(0, 2 , 0, 2);
417 TheSurfaceTool::D2(surf,p2d.X(),p2d.Y(),pbid, Der(1,0), Der(0,1),
418 Der(2,0), Der(0,2), Der(1,1));
419 Der(2,1) = TheSurfaceTool::DN(surf, p2d.X(), p2d.Y(), 2,1);
420 Der(1,2) = TheSurfaceTool::DN(surf,p2d.X(),p2d.Y(), 1,2);
421 Der(2,2) = TheSurfaceTool::DN(surf,p2d.X(),p2d.Y(), 2,2);
422 CSLib::Normal(2, Der, 1.e-9,
423 p2d.X(), p2d.Y(),
424 TheSurfaceTool::FirstUParameter(surf),
425 TheSurfaceTool::LastUParameter(surf),
426 TheSurfaceTool::FirstVParameter(surf),
427 TheSurfaceTool::LastVParameter(surf),
428 stat, thenormal, iu, iv);
429 normale.SetXYZ(thenormal.XYZ());
430#if DEB
431 if (stat == CSLib_InfinityOfSolutions)
432 cout << "Blend_Walking::Transition : Infinite de Normal" << endl;
433#endif
434 }
435
436 IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
437
438}
439
440
441void Blend_Walking::MakeExtremity(TheExtremity& Extrem,
442 const Standard_Boolean OnFirst,
443 const Standard_Integer Index,
444 const Standard_Real Param,
445 const Standard_Boolean IsVtx,
446 const TheVertex& Vtx)
447{
448
449 IntSurf_Transition Tline,Tarc;
450 Standard_Integer nbarc;
451 Handle(TheTopolTool) Iter;
452
453 if (OnFirst) {
454 Extrem.SetValue(previousP.PointOnS1(),
455 sol(1),sol(2),
456 previousP.Parameter(), tolesp);
457 if (!previousP.IsTangencyPoint())
458 Extrem.SetTangent(previousP.TangentOnS1());
459 Iter = recdomain1;
460 }
461 else {
462 Extrem.SetValue(previousP.PointOnS2(),
463 sol(3),sol(4),
464 previousP.Parameter(), tolesp);
465 if (!previousP.IsTangencyPoint())
466 Extrem.SetTangent(previousP.TangentOnS2());
467 Iter = recdomain2;
468 }
469
470 Iter->Init();
471 nbarc = 1;
472
473 while (nbarc < Index) {
474 nbarc++;
475 Iter->Next();
476 }
477
478 Transition(OnFirst,Iter->Value(),Param,Tline,Tarc);
479 Extrem.AddArc(Iter->Value(),Param,Tline,Tarc);
480 if (IsVtx) Extrem.SetVertex(Vtx);
481}
482
483void Blend_Walking::MakeSingularExtremity( TheExtremity& Extrem,
484 const Standard_Boolean OnFirst,
485 const TheVertex& Vtx)
486{
487 IntSurf_Transition Tline,Tarc;
488 Handle(TheTopolTool) Iter;
489 Standard_Real prm;
490
491 if (OnFirst) {
492 Iter = recdomain1;
493 if (!previousP.IsTangencyPoint())
494 Extrem.SetTangent(previousP.TangentOnS1());
495 }
496 else {
497 if (!previousP.IsTangencyPoint())
498 Extrem.SetTangent(previousP.TangentOnS2());
499 Iter = recdomain2;
500 }
501
502 Iter->Init();
503 Extrem.SetVertex(Vtx);
504 while (Iter->More()) {
505 TheArc arc = Iter->Value();
506 Iter->Initialize(arc);
507 Iter->InitVertexIterator();
508 while (Iter->MoreVertex()) {
509 if (Iter->Identical(Vtx,Iter->Vertex())) {
510 prm = TheBlendTool::Parameter(Vtx,arc);
511 Transition(OnFirst,arc,prm,Tline,Tarc);
512 Extrem.AddArc(arc,prm,Tline,Tarc);
513 }
514 Iter->NextVertex();
515 }
516 Iter->Next();
517 }
518}
519
520
521
522
523
524
525
526
527
528
529