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