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