7fd59977 |
1 | Blend_Walking::Blend_Walking(const TheSurface& Surf1, |
2 | const TheSurface& Surf2, |
3 | const Handle(TheTopolTool)& Domain1, |
4 | const Handle(TheTopolTool)& Domain2): |
5 | sol(1,4),surf1(Surf1),surf2(Surf2), |
6 | done(Standard_False), |
7 | clasonS1(Standard_True),clasonS2(Standard_True), |
8 | check2d(Standard_True),check(Standard_True), |
9 | twistflag1(Standard_False),twistflag2(Standard_False) |
10 | |
11 | { |
12 | domain1 = Domain1; |
13 | domain2 = Domain2; |
14 | recdomain1 = Domain1; |
15 | recdomain2 = Domain2; |
16 | } |
17 | |
18 | void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1, |
19 | const Handle(TheTopolTool)& Domain2) |
20 | { |
21 | recdomain1 = Domain1; |
22 | recdomain2 = Domain2; |
23 | } |
24 | |
25 | void Blend_Walking::AddSingularPoint(const Blend_Point& P) |
26 | { |
27 | if (jalons.Length() == 0) { |
28 | jalons.Append(P); |
29 | } |
30 | else { |
31 | Standard_Integer ii, jj; |
32 | Standard_Real tp = P.Parameter(), |
33 | ti=jalons.First().Parameter(); |
34 | for (jj=1, ii=1; ii<=jalons.Length() && tp>ti; ii++) { |
35 | jj = ii; |
36 | ti = jalons.Value(jj).Parameter(); |
37 | } |
38 | if (tp > ti) jalons.InsertAfter(jj, P); |
39 | else jalons.InsertBefore(jj, P); |
40 | } |
41 | } |
42 | |
43 | void Blend_Walking::Perform(Blend_Function& Func, |
44 | Blend_FuncInv& FuncInv, |
45 | const Standard_Real Pdep, |
46 | const Standard_Real Pmax, |
47 | const Standard_Real MaxStep, |
48 | const Standard_Real TolGuide, |
49 | const math_Vector& ParDep, |
50 | const Standard_Real Tolesp, |
51 | const Standard_Real Fleche, |
52 | const Standard_Boolean Appro) |
53 | { |
54 | |
55 | done = Standard_False; |
56 | iscomplete = Standard_False; |
57 | comptra = Standard_False; |
58 | Standard_Boolean doextremities = 1; |
59 | if(line.IsNull()) line = new TheLine (); |
60 | else {line->Clear();doextremities = 0;} |
61 | tolesp = Abs(Tolesp); |
62 | tolgui = Abs(TolGuide); |
63 | fleche = Abs(Fleche); |
64 | rebrou = Standard_False; |
65 | pasmax = Abs(MaxStep); |
66 | if (Pmax-Pdep >= 0.) { |
67 | sens = 1.; |
68 | } |
69 | else { |
70 | sens = -1.; |
71 | } |
72 | |
73 | Blend_Status State; |
74 | TheExtremity ptf1,ptf2; |
75 | |
76 | param = Pdep; |
77 | Func.Set(param); |
78 | |
79 | if (Appro) { |
80 | |
81 | TopAbs_State situ1,situ2; |
82 | math_Vector tolerance(1,4),infbound(1,4),supbound(1,4); |
83 | Func.GetTolerance(tolerance,tolesp); |
84 | Func.GetBounds(infbound,supbound); |
85 | math_FunctionSetRoot rsnld(Func,tolerance,30); |
86 | |
87 | rsnld.Perform(Func,ParDep,infbound,supbound); |
88 | |
89 | if (!rsnld.IsDone()) { |
90 | return; |
91 | } |
92 | rsnld.Root(sol); |
93 | |
94 | if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)), |
95 | Min(tolerance(1),tolerance(2)),0); |
96 | else situ1 = TopAbs_IN; |
97 | if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)), |
98 | Min(tolerance(3),tolerance(4)),0); |
99 | else situ2 = TopAbs_IN; |
100 | |
101 | if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) { |
102 | return; |
103 | } |
104 | } |
105 | else { |
106 | sol = ParDep; |
107 | } |
108 | |
109 | #ifdef DEB |
110 | sectioncalculee = 0; |
111 | #endif |
112 | State = TestArret(Func, Blend_OK, Standard_False); |
113 | if (State!=Blend_OK) { |
114 | return; |
115 | } |
116 | #ifdef DEB |
117 | if (Blend_GettraceDRAWSECT()){ |
118 | Drawsect(surf1,surf2,sol,param,Func); |
119 | } |
120 | nbcomputedsection = 1; |
121 | #endif |
122 | // Mettre a jour la ligne. |
123 | line->Append(previousP); |
124 | |
125 | if(doextremities){ |
126 | TheExtremity ptf1 (previousP.PointOnS1(), |
127 | sol(1),sol(2),tolesp); |
128 | TheExtremity ptf2 (previousP.PointOnS2(), |
129 | sol(3),sol(4),tolesp); |
130 | if (!previousP.IsTangencyPoint()) { |
131 | ptf1.SetTangent(previousP.TangentOnS1()); |
132 | ptf2.SetTangent(previousP.TangentOnS2()); |
133 | } |
134 | |
135 | if (sens>0.) { |
136 | line->SetStartPoints(ptf1, ptf2); |
137 | } |
138 | else { |
139 | line->SetEndPoints(ptf1, ptf2); |
140 | } |
141 | } |
142 | |
143 | InternalPerform(Func,FuncInv,Pmax); |
144 | |
145 | #ifdef DEB |
146 | // cout <<"Perform : "<<nbcomputedsection<<" sections calculees"<<endl; |
147 | // cout <<line->NbPoints()<<" sections gardees"<<endl; |
148 | #endif |
149 | |
150 | done = Standard_True; |
151 | } |
152 | |
153 | |
154 | Standard_Boolean Blend_Walking::PerformFirstSection |
155 | (Blend_Function& Func, |
156 | const Standard_Real Pdep, |
157 | math_Vector& ParDep, |
158 | const Standard_Real Tolesp, |
159 | const Standard_Real TolGuide, |
160 | TopAbs_State& Pos1, |
161 | TopAbs_State& Pos2) |
162 | { |
163 | iscomplete = Standard_False; |
164 | comptra = Standard_False; |
165 | line = new TheLine (); |
166 | tolesp = Abs(Tolesp); |
167 | tolgui = Abs(TolGuide); |
168 | |
169 | Pos1 = Pos2 = TopAbs_UNKNOWN; |
170 | |
171 | Blend_Status State; |
172 | |
173 | param = Pdep; |
174 | Func.Set(param); |
175 | |
176 | math_Vector tolerance(1,4),infbound(1,4),supbound(1,4); |
177 | Func.GetTolerance(tolerance,tolesp); |
178 | Func.GetBounds(infbound,supbound); |
179 | math_FunctionSetRoot rsnld(Func,tolerance,30); |
180 | |
181 | rsnld.Perform(Func,ParDep,infbound,supbound); |
182 | |
183 | if (!rsnld.IsDone()) { |
184 | return Standard_False; |
185 | } |
186 | rsnld.Root(sol); |
187 | ParDep = sol; |
188 | Pos1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)), |
189 | Min(tolerance(1),tolerance(2)),0); |
190 | Pos2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)), |
191 | Min(tolerance(3),tolerance(4)),0); |
192 | if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN) { |
193 | return Standard_False; |
194 | } |
195 | |
196 | State = TestArret(Func, Blend_OK, Standard_False); |
197 | #ifdef DEB |
198 | if (Blend_GettraceDRAWSECT()){ |
199 | Drawsect(surf1,surf2,sol,param,Func); |
200 | } |
201 | #endif |
202 | return Standard_True; |
203 | } |
204 | |
205 | |
206 | Standard_Boolean Blend_Walking::PerformFirstSection |
207 | (Blend_Function& Func, |
208 | Blend_FuncInv& FuncInv, |
209 | const Standard_Real Pdep, |
210 | const Standard_Real Pmax, |
211 | const math_Vector& ParDep, |
212 | const Standard_Real Tolesp, |
213 | const Standard_Real TolGuide, |
214 | const Standard_Boolean RecOnS1, |
215 | const Standard_Boolean RecOnS2, |
216 | Standard_Real& Psol, |
217 | math_Vector& ParSol) |
218 | |
219 | { |
220 | iscomplete = Standard_False; |
221 | comptra = Standard_False; |
222 | line = new TheLine (); |
223 | |
224 | Standard_Real w1,w2, extrapol; |
225 | Standard_Boolean recad1,recad2; |
226 | |
227 | tolesp = Abs(Tolesp); |
228 | tolgui = Abs(TolGuide); |
229 | if (Pmax-Pdep >= 0.) { |
230 | sens = 1.; |
231 | } |
232 | else { |
233 | sens = -1.; |
234 | } |
235 | extrapol = Abs(Pmax-Pdep)/50; // 2% |
236 | |
237 | Blend_Status State; |
238 | |
239 | param = Pdep; |
240 | Func.Set(param); |
241 | |
242 | math_Vector tolerance(1,4),infbound(1,4),supbound(1,4); |
243 | math_Vector solrst1(1,4),solrst2(1,4); |
244 | TheExtremity Ext1,Ext2; |
245 | Standard_Integer Index1,Index2,nbarc; |
246 | Standard_Boolean Isvtx1,Isvtx2; |
247 | TheVertex Vtx1,Vtx2; |
248 | gp_Pnt2d p2d; |
249 | |
250 | Func.GetTolerance(tolerance,tolesp); |
251 | Func.GetBounds(infbound,supbound); |
252 | math_FunctionSetRoot rsnld(Func,tolerance,30); |
253 | |
254 | rsnld.Perform(Func,ParDep,infbound,supbound); |
255 | |
256 | if (!rsnld.IsDone()) { |
257 | return Standard_False; |
258 | } |
259 | rsnld.Root(sol); |
260 | |
261 | w1 = w2 = Pmax; |
262 | |
263 | recad1 = RecOnS1 && Recadre(FuncInv,Standard_True, |
264 | sol,solrst1,Index1,Isvtx1,Vtx1, extrapol); |
265 | if (recad1) { |
266 | w1 = solrst1(2); |
267 | } |
268 | |
269 | recad2 = RecOnS2 && Recadre(FuncInv,Standard_False, |
270 | sol,solrst2,Index2,Isvtx2,Vtx2, extrapol); |
271 | if (recad2) { |
272 | w2 = solrst2(2); |
273 | } |
274 | |
275 | if (!recad1 && !recad2) { |
276 | return Standard_False; |
277 | } |
278 | |
279 | if (recad1 && recad2) { |
280 | if (Abs(w1-w2) <= tolgui) { |
281 | //sol sur 1 et 2 a la fois |
282 | State = Blend_OnRst12; |
283 | param = w1; |
284 | ParSol(1) = solrst2(3); |
285 | ParSol(2) = solrst2(4); |
286 | ParSol(3) = solrst1(3); |
287 | ParSol(4) = solrst1(4); |
288 | } |
289 | else if (sens*(w2-w1) < 0.) { // on garde le plus grand |
290 | //sol sur 1 |
291 | State = Blend_OnRst1; |
292 | param = w1; |
293 | |
294 | recdomain1->Init(); |
295 | nbarc = 1; |
296 | while (nbarc < Index1) { |
297 | nbarc++; |
298 | recdomain1->Next(); |
299 | } |
300 | p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1)); |
301 | ParSol(1) = p2d.X(); |
302 | ParSol(2) = p2d.Y(); |
303 | ParSol(3) = solrst1(3); |
304 | ParSol(4) = solrst1(4); |
305 | |
306 | } |
307 | else { |
308 | //sol sur 2 |
309 | State = Blend_OnRst2; |
310 | param = w2; |
311 | |
312 | recdomain2->Init(); |
313 | nbarc = 1; |
314 | while (nbarc < Index2) { |
315 | nbarc++; |
316 | recdomain2->Next(); |
317 | } |
318 | p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1)); |
319 | ParSol(1) = solrst2(3); |
320 | ParSol(2) = solrst2(4); |
321 | ParSol(3) = p2d.X(); |
322 | ParSol(4) = p2d.Y(); |
323 | } |
324 | } |
325 | else if (recad1) { |
326 | // sol sur 1 |
327 | State = Blend_OnRst1; |
328 | param = w1; |
329 | recdomain1->Init(); |
330 | nbarc = 1; |
331 | while (nbarc < Index1) { |
332 | nbarc++; |
333 | recdomain1->Next(); |
334 | } |
335 | p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1)); |
336 | ParSol(1) = p2d.X(); |
337 | ParSol(2) = p2d.Y(); |
338 | ParSol(3) = solrst1(3); |
339 | ParSol(4) = solrst1(4); |
340 | } |
341 | else { //if (recad2) { |
342 | //sol sur 2 |
343 | State = Blend_OnRst2; |
344 | param = w2; |
345 | |
346 | recdomain2->Init(); |
347 | nbarc = 1; |
348 | while (nbarc < Index2) { |
349 | nbarc++; |
350 | recdomain2->Next(); |
351 | } |
352 | p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1)); |
353 | ParSol(1) = solrst2(3); |
354 | ParSol(2) = solrst2(4); |
355 | ParSol(3) = p2d.X(); |
356 | ParSol(4) = p2d.Y(); |
357 | } |
358 | |
359 | Psol = param; |
360 | sol = ParSol; |
361 | Func.Set(param); |
362 | State = TestArret(Func, State, Standard_False); |
363 | switch (State) { |
364 | case Blend_OnRst1 : |
365 | { |
366 | #ifdef DEB |
367 | if (Blend_GettraceDRAWSECT()){ |
368 | Drawsect(surf1,surf2,sol,param,Func); |
369 | } |
370 | #endif |
371 | MakeExtremity(Ext1,Standard_True,Index1, |
372 | solrst1(1),Isvtx1,Vtx1); |
373 | Ext2.SetValue(previousP.PointOnS2(), |
374 | sol(3),sol(4),tolesp); |
375 | } |
376 | break; |
377 | |
378 | case Blend_OnRst2 : |
379 | { |
380 | #ifdef DEB |
381 | if (Blend_GettraceDRAWSECT()){ |
382 | Drawsect(surf1,surf2,sol,param,Func); |
383 | } |
384 | #endif |
385 | Ext1.SetValue(previousP.PointOnS1(), |
386 | sol(1),sol(2),tolesp); |
387 | MakeExtremity(Ext2,Standard_False,Index2, |
388 | solrst2(1),Isvtx2,Vtx2); |
389 | } |
390 | break; |
391 | |
392 | case Blend_OnRst12 : |
393 | { |
394 | #ifdef DEB |
395 | if (Blend_GettraceDRAWSECT()){ |
396 | Drawsect(surf1,surf2,sol,param,Func); |
397 | } |
398 | #endif |
399 | MakeExtremity(Ext1,Standard_True,Index1, |
400 | solrst1(1),Isvtx1,Vtx1); |
401 | MakeExtremity(Ext2,Standard_False,Index2, |
402 | solrst2(1),Isvtx2,Vtx2); |
403 | } |
404 | break; |
405 | default: |
406 | { |
407 | Standard_Failure::Raise("Blend_Walking::PerformFirstSection : echec"); |
408 | } |
409 | } |
410 | if (sens < 0.) { |
411 | line->SetEndPoints(Ext1,Ext2); |
412 | } |
413 | else { |
414 | line->SetStartPoints(Ext1,Ext2); |
415 | } |
416 | return Standard_True; |
417 | } |
418 | |
419 | |
420 | |
421 | Standard_Boolean Blend_Walking::Continu(Blend_Function& Func, |
422 | Blend_FuncInv& FuncInv, |
423 | const Standard_Real P) |
424 | { |
425 | if (!done) {StdFail_NotDone::Raise();} |
426 | const Blend_Point& firstBP = line->Point(1); |
427 | const Blend_Point& lastBP = line->Point(line->NbPoints()); |
428 | |
429 | if (P < firstBP.Parameter()){ |
430 | sens = -1.; |
431 | previousP = firstBP; |
432 | } |
433 | else if(P > lastBP.Parameter()){ |
434 | sens = 1.; |
435 | previousP = lastBP; |
436 | } |
437 | |
438 | param = previousP.Parameter(); |
439 | previousP.ParametersOnS1(sol(1),sol(2)); |
440 | previousP.ParametersOnS2(sol(3),sol(4)); |
441 | |
442 | InternalPerform(Func,FuncInv,P); |
443 | return Standard_True; |
444 | } |
445 | |
446 | |
447 | Standard_Boolean Blend_Walking::Continu(Blend_Function& Func, |
448 | Blend_FuncInv& FuncInv, |
449 | const Standard_Real P, |
450 | const Standard_Boolean OnS1) |
451 | { |
452 | if (!done) {StdFail_NotDone::Raise();} |
453 | TheExtremity Ext1,Ext2; |
454 | if (sens < 0.) { |
455 | Ext1 = line->StartPointOnFirst(); |
456 | Ext2 = line->StartPointOnSecond(); |
457 | if (OnS1 && Ext1.NbPointOnRst() == 0 || |
458 | !OnS1 && Ext2.NbPointOnRst() == 0) { |
459 | return Standard_False; |
460 | } |
461 | previousP = line->Point(1); |
462 | |
463 | |
464 | } |
465 | else { |
466 | Ext1 = line->EndPointOnFirst(); |
467 | Ext2 = line->EndPointOnSecond(); |
468 | if (OnS1 && Ext1.NbPointOnRst() == 0 || |
469 | !OnS1 && Ext2.NbPointOnRst() == 0) { |
470 | return Standard_False; |
471 | } |
472 | previousP = line->Point(line->NbPoints()); |
473 | } |
474 | |
475 | Standard_Integer length = line->NbPoints(); |
476 | param = previousP.Parameter(); |
477 | previousP.ParametersOnS1(sol(1),sol(2)); |
478 | previousP.ParametersOnS2(sol(3),sol(4)); |
479 | |
480 | if(OnS1) clasonS1 = Standard_False; |
481 | else clasonS2 = Standard_False; |
482 | |
483 | InternalPerform(Func,FuncInv,P); |
484 | |
485 | clasonS1 = Standard_True; |
486 | clasonS2 = Standard_True; |
487 | |
488 | Standard_Integer newlength = line->NbPoints(); |
489 | if (sens <0.) { |
490 | if (OnS1 && line->StartPointOnSecond().NbPointOnRst() == 0 || |
491 | !OnS1 && line->StartPointOnFirst().NbPointOnRst() == 0) { |
492 | line->Remove(1,newlength-length); |
493 | line->SetStartPoints(Ext1,Ext2); |
494 | return Standard_False; |
495 | } |
496 | } |
497 | else { |
498 | if (OnS1 && line->EndPointOnSecond().NbPointOnRst() == 0 || |
499 | !OnS1 && line->EndPointOnFirst().NbPointOnRst() == 0) { |
500 | line->Remove(length,newlength); |
501 | line->SetEndPoints(Ext1,Ext2); |
502 | return Standard_False; |
503 | } |
504 | } |
505 | return Standard_True; |
506 | } |
507 | |
508 | |
509 | Standard_Boolean Blend_Walking::Complete(Blend_Function& Func, |
510 | Blend_FuncInv& FuncInv, |
511 | const Standard_Real Pmin) |
512 | { |
513 | if (!done) {StdFail_NotDone::Raise();} |
514 | if (iscomplete) {return Standard_True;} |
515 | |
516 | if (sens >0.) { |
517 | previousP = line->Point(1); |
518 | } |
519 | else { |
520 | previousP = line->Point(line->NbPoints()); |
521 | } |
522 | |
523 | sens = -sens; |
524 | |
525 | param = previousP.Parameter(); |
526 | previousP.ParametersOnS1(sol(1),sol(2)); |
527 | previousP.ParametersOnS2(sol(3),sol(4)); |
528 | |
529 | InternalPerform(Func,FuncInv,Pmin); |
530 | |
531 | #ifdef DEB |
532 | // cout <<"Complete : "<<nbcomputedsection<<" sections calculees"<<endl; |
533 | // cout <<line->NbPoints()<<" sections gardees"<<endl; |
534 | #endif |
535 | |
536 | iscomplete = Standard_True; |
537 | return Standard_True; |
538 | } |
539 | |
540 | void Blend_Walking::ClassificationOnS1(const Standard_Boolean C) |
541 | { |
542 | clasonS1 = C; |
543 | } |
544 | |
545 | void Blend_Walking::ClassificationOnS2(const Standard_Boolean C) |
546 | { |
547 | clasonS2 = C; |
548 | } |
549 | |
550 | void Blend_Walking::Check2d(const Standard_Boolean C) |
551 | { |
552 | check2d = C; |
553 | } |
554 | |
555 | void Blend_Walking::Check(const Standard_Boolean C) |
556 | { |
557 | check = C; |
558 | } |
559 | |