0024750: Replace instantiations of TCollection generic classes by NCollection templat...
[occt.git] / src / ChFiDS / ChFiDS_FilSpine.cxx
CommitLineData
b311480e 1// Created on: 1995-04-24
2// Created by: Modelistation
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <ChFiDS_FilSpine.ixx>
18#include <ChFiDS_ListIteratorOfListOfHElSpine.hxx>
19#include <Precision.hxx>
20#include <TColStd_HArray1OfBoolean.hxx>
21#include <TColStd_Array1OfInteger.hxx>
22#include <gp_XY.hxx>
23#include <TColgp_Array1OfPnt2d.hxx>
24#include <ElCLib.hxx>
25#include <Law_ListIteratorOfLaws.hxx>
26#include <Law_Constant.hxx>
27#include <Law_S.hxx>
28#include <Law_Interpol.hxx>
29#include <Standard_DomainError.hxx>
ec357c5c 30#include <Law_Composite.hxx>
7fd59977 31
32//=======================================================================
33//function : ChFiDS_FilSpine
34//purpose :
35//=======================================================================
36
37ChFiDS_FilSpine::ChFiDS_FilSpine() {}
38
39ChFiDS_FilSpine::ChFiDS_FilSpine(const Standard_Real Tol) :
40ChFiDS_Spine(Tol)
41{}
42
43//=======================================================================
44//function : Reset
45//purpose :
46//=======================================================================
47
48void ChFiDS_FilSpine::Reset(const Standard_Boolean AllData)
49{
50 ChFiDS_Spine::Reset(AllData);
51 laws.Clear();
52 if(AllData)
53 parandrad.Clear();
54 else //Complete parandrad
55 {
56 Standard_Real spinedeb = FirstParameter();
57 Standard_Real spinefin = LastParameter();
58
59 gp_XY FirstUandR = parandrad.First();
60 gp_XY LastUandR = parandrad.Last();
61 if (Abs( spinedeb - FirstUandR.X() ) > gp::Resolution())
62 {
63 FirstUandR.SetX( spinedeb );
64 parandrad.Prepend( FirstUandR );
65 }
66 if (Abs( spinefin - LastUandR.X() ) > gp::Resolution())
67 {
68 LastUandR.SetX( spinefin );
69 parandrad.Append( LastUandR );
70 }
71
72 if (IsPeriodic())
73 parandrad(parandrad.Length()).SetY( parandrad(1).Y() );
74 }
75}
76
77//=======================================================================
78//function : SetRadius
79//purpose :
80//=======================================================================
81
82void ChFiDS_FilSpine::SetRadius(const Standard_Real Radius,
83 const TopoDS_Edge& E)
84{
85 splitdone = Standard_False;
86 Standard_Integer IE = Index(E);
87 gp_XY FirstUandR( 0., Radius ), LastUandR( 1., Radius );
88 SetRadius( FirstUandR, IE );
89 SetRadius( LastUandR, IE );
90}
91
92//=======================================================================
93//function : UnSetRadius
94//purpose :
95//=======================================================================
96
97void ChFiDS_FilSpine::UnSetRadius(const TopoDS_Edge& E)
98{
99 splitdone = Standard_False;
100 Standard_Integer IE = Index(E);
101
102 Standard_Real Uf = FirstParameter(IE);
103 Standard_Real Ul = LastParameter(IE);
104 Standard_Integer ifirst = 0, ilast = 0;
105 for (Standard_Integer i = 1; i <= parandrad.Length(); i++)
106 {
107 if (Abs(parandrad(i).X()-Uf) <= gp::Resolution())
108 ifirst = i;
109 if (Abs(parandrad(i).X()-Ul) <= gp::Resolution())
110 ilast = i;
111 }
112 if (ifirst != 0 && ilast != 0)
113 parandrad.Remove( ifirst, ilast );
114}
115
116//=======================================================================
117//function : SetRadius
118//purpose :
119//=======================================================================
120
121void ChFiDS_FilSpine::SetRadius(const Standard_Real Radius,
122 const TopoDS_Vertex& V)
123{
124 Standard_Real npar = Absc(V);
125 gp_XY UandR( npar, Radius );
126 SetRadius( UandR, 0 );
127}
128
129//=======================================================================
130//function : SetRadius
131//purpose :
132//=======================================================================
133
134void ChFiDS_FilSpine::SetRadius(const Standard_Real Radius)
135{
136 parandrad.Clear();
137 gp_XY FirstUandR( FirstParameter(), Radius );
138 gp_XY LastUandR( LastParameter(), Radius );
139 SetRadius( FirstUandR, 0 );
140 SetRadius( LastUandR, 0 );
141}
142
143//=======================================================================
144//function : SetRadius
145//purpose :
146//=======================================================================
147
148void ChFiDS_FilSpine::SetRadius(const gp_XY& UandR,
149 const Standard_Integer IinC)
150{
151 Standard_Real W;
152 if (IinC == 0)
153 W = UandR.X();
154 else
155 {
156 Standard_Real Uf = FirstParameter(IinC);
157 Standard_Real Ul = LastParameter(IinC);
158 W = Uf + UandR.X()*( Ul - Uf );
159 }
160
161 gp_XY pr( W, UandR.Y() );
162 Standard_Integer i;
163 for(i = 1; i <= parandrad.Length(); i++){
164 if(parandrad.Value(i).X() == W) {
165 parandrad.ChangeValue(i).SetY( UandR.Y() );
166 if (!splitdone) return;
167 else break;
168 }
169 else if(parandrad.Value(i).X() > W) {
170 parandrad.InsertBefore(i,pr);
171 if (!splitdone) return;
172 else break;
173 }
174 }
175 if (i == parandrad.Length()+1) parandrad.Append(pr);
176
177 //si le split est done il faut rejouer la law
178 //correspondant au parametre W
179 if (splitdone) {
180 ChFiDS_ListIteratorOfListOfHElSpine It(elspines);
181 Law_ListIteratorOfLaws Itl(laws);
182 Handle(ChFiDS_HElSpine) Els = It.Value();
183 if (Els->IsPeriodic()) Itl.Value() = ComputeLaw(Els);
184 else{
7fd59977 185 for (; It.More(); It.Next(), Itl.Next()) {
186 Els = It.Value();
187 Standard_Real uf = Els->FirstParameter();
188 Standard_Real ul = Els->LastParameter();
189 if(uf <= W && W <= ul) {
190 Itl.Value() = ComputeLaw(Els);
191 }
192 }
193 }
194 }
195}
196
197//=======================================================================
198//function : UnSetRadius
199//purpose :
200//=======================================================================
201
202void ChFiDS_FilSpine::UnSetRadius(const TopoDS_Vertex& V)
203{
204 Standard_Real npar = Absc(V);
205 for(Standard_Integer i = 1; i <= parandrad.Length(); i++){
206 if(parandrad.Value(i).X() == npar) {
207 parandrad.Remove(i);
208 break;
209 }
210 }
211}
212
213//=======================================================================
214//function : SetRadius
215//purpose :
216//=======================================================================
217
218void ChFiDS_FilSpine::SetRadius(const Handle(Law_Function)& C,
35e08fe8 219 const Standard_Integer /*IinC*/)
7fd59977 220{
221 splitdone = Standard_False;
222 Handle(Law_Composite) prout = new Law_Composite();
223 Law_Laws& lst = prout->ChangeLaws();
224 lst.Append(C);
225 parandrad.Clear();
226}
227
228
229//=======================================================================
230//function : IsConstant
231//purpose :
232//=======================================================================
233
234Standard_Boolean ChFiDS_FilSpine::IsConstant()const
235{
236 if (parandrad.IsEmpty())
237 return Standard_False;
238
239 Standard_Boolean isconst = Standard_True;
240 Standard_Real Radius = parandrad(1).Y();
241 for (Standard_Integer i = 2; i <= parandrad.Length(); i++)
242 if (Abs( Radius - parandrad(i).Y() ) > Precision::Confusion())
243 {
244 isconst = Standard_False;
245 break;
246 }
247 return isconst;
248}
249
250//=======================================================================
251//function : IsConstant
252//purpose :
253//=======================================================================
254
255Standard_Boolean ChFiDS_FilSpine::IsConstant(const Standard_Integer IE)const
256{
257 Standard_Real Uf = FirstParameter(IE);
258 Standard_Real Ul = LastParameter(IE);
259
d20d815b 260 Standard_Real StartRad = 0.0, par, rad;
7fd59977 261 Standard_Integer i;
262 for (i = 1; i < parandrad.Length(); i++)
263 {
264 par = parandrad(i).X();
265 rad = parandrad(i).Y();
266 Standard_Real nextpar = parandrad(i+1).X();
267 if (Abs( Uf-par ) <= gp::Resolution() ||
0ebaa4db 268 (par < Uf && Uf < nextpar && nextpar-Uf > gp::Resolution()))
269 {
270 StartRad = rad;
271 break;
272 }
7fd59977 273 }
274 for (i++; i <= parandrad.Length(); i++)
275 {
276 par = parandrad(i).X();
277 rad = parandrad(i).Y();
278 if (Abs( rad-StartRad ) > Precision::Confusion())
279 return Standard_False;
280 if (Abs( Ul-par ) <= gp::Resolution())
281 return Standard_True;
282 if (par > Ul)
283 return Standard_True;
284 }
285 return Standard_True;
286}
287
288//=======================================================================
289//function : Radius
290//purpose :
291//=======================================================================
292
293Standard_Real ChFiDS_FilSpine::Radius(const TopoDS_Edge& E)const
294{
295 Standard_Integer IE = Index(E);
296 return Radius(IE);
297}
298
299//=======================================================================
300//function : Radius
301//purpose :
302//=======================================================================
303
304Standard_Real ChFiDS_FilSpine::Radius(const Standard_Integer IE)const
305{
306 Standard_Real Uf = FirstParameter(IE);
307 Standard_Real Ul = LastParameter(IE);
308
1d47d8d0 309 Standard_Real StartRad = 0., par, rad;
7fd59977 310 Standard_Integer i;
311 for (i = 1; i < parandrad.Length(); i++)
312 {
313 par = parandrad(i).X();
314 rad = parandrad(i).Y();
315 Standard_Real nextpar = parandrad(i+1).X();
316 if (Abs( Uf-par ) <= gp::Resolution() ||
0ebaa4db 317 (par < Uf && Uf < nextpar && nextpar-Uf > gp::Resolution()))
318 {
319 StartRad = rad;
320 break;
321 }
7fd59977 322 }
323 for (i++; i <= parandrad.Length(); i++)
324 {
325 par = parandrad(i).X();
326 rad = parandrad(i).Y();
327 if (Abs( rad-StartRad ) > Precision::Confusion())
81bba717 328 Standard_DomainError::Raise("Edge is not constant");
7fd59977 329 if (Abs( Ul-par ) <= gp::Resolution())
330 return StartRad;
331 if (par > Ul)
332 return StartRad;
333 }
334 return StartRad;
335}
336
337//=======================================================================
338//function : Radius
339//purpose :
340//=======================================================================
341
342Standard_Real ChFiDS_FilSpine::Radius()const
343{
81bba717 344 if (!IsConstant()) Standard_DomainError::Raise("Spine is not constant");
7fd59977 345 return parandrad(1).Y();
346}
347
348//=======================================================================
349//function : AppendElSpine
350//purpose :
351//=======================================================================
352
353void ChFiDS_FilSpine::AppendElSpine(const Handle(ChFiDS_HElSpine)& Els)
354{
355 ChFiDS_Spine::AppendElSpine(Els);
356 AppendLaw(Els);
357}
358
359//=======================================================================
360//function : AppendLaw
361//purpose :
362//=======================================================================
363
364void ChFiDS_FilSpine::AppendLaw(const Handle(ChFiDS_HElSpine)& Els)
365{
366 Handle(Law_Composite) l = ComputeLaw(Els);
367 laws.Append(l);
368}
369
370static void mklaw(Law_Laws& res,
371 const TColgp_SequenceOfXY& pr,
372 const Standard_Real curdeb,
373 const Standard_Real curfin,
374 const Standard_Real Rdeb,
375 const Standard_Real Rfin,
376 const Standard_Boolean recadre,
377 const Standard_Real deb,
378 const Standard_Real fin,
379 const Standard_Real tol3d)
380{
381 TColgp_SequenceOfXY npr;
382 Standard_Real rad = Rdeb, raf = Rfin;
383 Standard_Boolean yaunpointsurledeb = Standard_False;
384 Standard_Boolean yaunpointsurlefin = Standard_False;
385 if(!pr.IsEmpty()){
386 for (Standard_Integer i = 1; i <= pr.Length(); i++){
387 const gp_XY& cur = pr.Value(i);
388 Standard_Real wcur = cur.X();
389 if(recadre) wcur = ElCLib::InPeriod(wcur,deb,fin);
390 if( curdeb - tol3d <= wcur && wcur <= curfin + tol3d) {
391 if(wcur - curdeb < tol3d) {
392 yaunpointsurledeb = Standard_True;
393 gp_XY ncur = cur;
394 if(Rdeb < 0.) rad = cur.Y();
395 ncur.SetCoord(curdeb,rad);
396 npr.Append(ncur);
397 }
398 else if(curfin - wcur < tol3d) {
399 yaunpointsurlefin = Standard_True;
400 gp_XY ncur = cur;
401 if(Rfin < 0.) raf = cur.Y();
402 ncur.SetCoord(curfin,raf);
403 npr.Append(ncur);
404 }
405 else npr.Append(gp_XY(wcur,cur.Y()));
406 }
407 }
408 }
409
410 if(npr.IsEmpty()){
411 if( Rdeb < 0. && Rfin <0. )
81bba717 412 Standard_DomainError::Raise("Impossible to create the law");
7fd59977 413 else if(Rdeb < 0. || Rfin <0.){
414 Standard_Real r = (Rfin<0.)? Rdeb : Rfin;
415 Handle(Law_Constant) loi = new Law_Constant();
416 loi->Set(r,curdeb,curfin);
417 res.Append(loi);
418 }
419 else{
420 Handle(Law_S) loi = new Law_S();
421 loi->Set(curdeb,Rdeb,curfin,Rfin);
422 res.Append(loi);
423 }
424 }
425 else{
7fd59977 426 if(!yaunpointsurledeb && Rdeb >= 0.) npr.Append(gp_XY(curdeb,Rdeb));
427 if(!yaunpointsurlefin && Rfin >= 0.) npr.Append(gp_XY(curfin,Rfin));
428 Standard_Integer nbp = npr.Length();
429// for(Standard_Integer i = 1; i < nbp; i++){
430 Standard_Integer i;
431 for(i = 1; i < nbp; i++){
432 for(Standard_Integer j = i + 1; j <= nbp; j++){
433 if(npr.Value(i).X() > npr.Value(j).X()){
434 gp_XY temp = npr.Value(i);
435 npr.ChangeValue(i) = npr.Value(j);
436 npr.ChangeValue(j) = temp;
437 }
438 }
439 }
81bba717 440 //Duplicates are removed.
7fd59977 441 Standard_Boolean fini = (nbp <= 1);
442 i = 1;
443 while (!fini) {
444 if(fabs(npr.Value(i).X() - npr.Value(i+1).X()) < tol3d) {
445 npr.Remove(i);
446 nbp--;
447 }
448 else i++;
449 fini = (i >= nbp);
450 }
451
452 if(rad < 0.) {
453 Handle(Law_Constant) loi = new Law_Constant();
454 loi->Set(npr.First().Y(),curdeb,npr.First().X());
455 res.Append(loi);
456 }
457 if(nbp > 1){
458 TColgp_Array1OfPnt2d tpr(1,nbp);
459 for (Standard_Integer l = 1; l <= nbp; l++) {
460 tpr(l).SetXY(npr.Value(l));
461 }
462 Handle(Law_Interpol) curloi = new Law_Interpol();
463 curloi->Set(tpr,0.,0.,Standard_False);
464 res.Append(curloi);
465 }
466 if(raf < 0.) {
467 Handle(Law_Constant) loi = new Law_Constant();
468 loi->Set(npr.Last().Y(),npr.Last().X(),curfin);
469 res.Append(loi);
470 }
471 }
472}
473
474//=======================================================================
475//function : ComputeLaw
476//purpose :
477//=======================================================================
478
479Handle(Law_Composite) ChFiDS_FilSpine::ComputeLaw
480(const Handle(ChFiDS_HElSpine)& Els)
481{
482 Standard_Real tol3d = Precision::Confusion();
483 Standard_Real deb,fin,curdeb,curfin;
484 curdeb = deb = Els->FirstParameter();
485 curfin = fin = Els->LastParameter();
486 Standard_Integer ideb = Index(deb,Standard_True);
487 Standard_Integer ifin = Index(fin,Standard_False);
488 Standard_Integer len = NbEdges();
81bba717 489 // if the spine is periodic, attention to the index and parameters
7fd59977 490 Standard_Real spinedeb = FirstParameter();
491 Standard_Real spinefin = LastParameter();
492
493 Standard_Integer nbed = ifin - ideb + 1;
494 Standard_Integer biddeb = ideb, bidfin = ifin;
495
496 Handle(Law_Composite) loi = new Law_Composite();
497 Law_Laws& list = loi->ChangeLaws();
7fd59977 498 Standard_Real Rdeb = 0., Rfin = 0., Rcur;
7fd59977 499 Standard_Integer icur = 1;
500 Handle(Law_S) sl;
501 Handle(Law_Constant) lastloi;
502 Standard_Boolean lawencours = Standard_False;
503
504
505 if(IsPeriodic()){
506 if(deb < 0 && ideb > ifin) bidfin += len;
507 else if(fin > LastParameter(len) && ideb > ifin) bidfin += len;
508 nbed = bidfin - biddeb + 1;
509 }
510 TColStd_Array1OfInteger ind(1,nbed);
511 Standard_Integer j = 1;
512 for(Standard_Integer i = biddeb; i <= bidfin; i++){
513 ind(j++) = ((i - 1)%len) + 1;
514 }
515
516 if(Els->IsPeriodic()){
81bba717 517 // A pereodic composite is created at range, which is eventually
518 // offset relatively to the elspine, to avoid a single point at
519 // origin.
7fd59977 520 loi->SetPeriodic();
81bba717 521 //Is there a constant edge?
7fd59977 522// for(Standard_Integer k = 1; k <= len; k++){
523 Standard_Integer k;
524 for( k = 1; k <= len; k++){
81bba717 525 if (IsConstant(k)){ // yes !
7fd59977 526 spinedeb = deb = curdeb = FirstParameter(k);
527 spinefin = fin = deb + Period();
528 for(Standard_Integer l = 1; l <= len; l++){
529 ind(l) = ((k + l -2)%len) + 1;
530 }
531 Rdeb = Rfin = Radius(k);
532 icur++;
81bba717 533 if(len == 1) curfin = LastParameter(k);//because InPeriod will make 0.!!!
7fd59977 534 else curfin = ElCLib::InPeriod(LastParameter(k),spinedeb,spinefin);
535 Handle(Law_Constant) curloi = new Law_Constant();
536 curloi->Set(Rdeb,curdeb,curfin);
537 list.Append(curloi);
538 curdeb = curfin;
539 break;
540 }
541 }
81bba717 542 if(k > len){ // no !
7fd59977 543 if(parandrad.IsEmpty())
81bba717 544 Standard_DomainError::Raise("Radius not defined");
7fd59977 545 Standard_Integer nbp = parandrad.Length();
546 if(nbp > 1){
547 deb = parandrad.First().X();
548 fin = deb + Period();
549 if(parandrad.Last().X() - fin < - tol3d) nbp++;
550 }
551 else nbp++;
552 TColgp_Array1OfPnt2d pr(1,nbp);
553 for (Standard_Integer l = 1; l < nbp; l++) {
554 pr(l).SetXY(parandrad(l));
555 }
556 pr(nbp).SetCoord(fin,pr(1).Y());
557 Handle(Law_Interpol) curloi = new Law_Interpol();
558 curloi->Set(pr,Standard_True);
559 list.Append(curloi);
560 return loi;
561 }
562 }
563 else if(IsPeriodic()){
81bba717 564 // start radius.
7fd59977 565 if (IsConstant(ind(1))) {
566 Rdeb = Radius(ind(1));
567 curfin = LastParameter(ind(1));
568 curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d);
569 curfin = Min(fin,curfin);
570 Handle(Law_Constant) curloi = new Law_Constant();
571 curloi->Set(Rdeb,curdeb,curfin);
572 list.Append(curloi);
573 curdeb = curfin;
574 icur++;
575 }
576 else{
81bba717 577 // There is inevitably kpart right before!
7fd59977 578 Standard_Integer iprec = (ind(1) - 1);
579 if(iprec == 0) iprec = len;
580 if (IsConstant(iprec)){
581 Rdeb = Radius(iprec);
582 }
81bba717 583 else Standard_DomainError::Raise("AppendLaw : previous constant is missing!");
7fd59977 584 lawencours = Standard_True;
585 }
81bba717 586 // the raduis at end.
7fd59977 587 if (IsConstant(ind(nbed))) Rfin = Radius(ind(nbed));
588 else{
81bba717 589 // There is inevitably kpart right after!
7fd59977 590 Standard_Integer isuiv = (ind(nbed) + 1);
591 if(isuiv == len + 1) isuiv = 1;
592 if (IsConstant(isuiv)) {
593 Rfin = Radius(isuiv);
594 }
81bba717 595 else Standard_DomainError::Raise("AppendLaw : next constant is missing!");
7fd59977 596 }
597 }
598 else{
81bba717 599 // the radius at start.
7fd59977 600 if (IsConstant(ind(1))) {
601 Rdeb = Radius(ind(1));
602 curfin = Min(fin,LastParameter(ind(1)));
603 Handle(Law_Constant) curloi = new Law_Constant();
604 curloi->Set(Rdeb,curdeb,curfin);
605 list.Append(curloi);
606 curdeb = curfin;
607 icur++;
608 }
609 else{
610 if(ind(1) > 1){
611 if (IsConstant(ind(1) - 1)){
612 Rdeb = Radius(ind(1) - 1);
613 }
81bba717 614 else Standard_DomainError::Raise("AppendLaw : previous constant is missing");
7fd59977 615 }
616 else if(parandrad.IsEmpty()){
81bba717 617 Standard_DomainError::Raise("AppendLaw : no radius on vertex");
7fd59977 618 }
619 else Rdeb = -1.;
620 lawencours = Standard_True;
621 }
81bba717 622 // the radius at end.
7fd59977 623 if (IsConstant(ind(nbed))) Rfin = Radius(ind(nbed));
624 else{
625 if(ind(nbed) < len){
626 if (IsConstant(ind(nbed) + 1)) Rfin = Radius(ind(nbed) + 1);
81bba717 627 else Standard_DomainError::Raise("AppendLaw : next constant is missing");
7fd59977 628 }
629 else if(parandrad.IsEmpty()){
81bba717 630 Standard_DomainError::Raise("AppendLaw : no radius on vertex");
7fd59977 631 }
632 else Rfin = -1.;
633 }
634 }
635
81bba717 636 // There are infos on the extremities of the elspine,
637 // all edges are parsed
7fd59977 638 for(; icur <= nbed; icur++){
639 if (IsConstant(ind(icur))) {
640 Rcur = Radius(ind(icur));
641 if(lawencours){
642 Law_Laws temp;
643 mklaw(temp,parandrad,curdeb,curfin,Rdeb,Rcur,
644 IsPeriodic(),spinedeb,spinefin,tol3d);
645 list.Append(temp);
646 lawencours = Standard_False;
647 curdeb = curfin;
648 }
649 curfin = LastParameter(ind(icur));
650 if(IsPeriodic()){
651 curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d);
652 if(ind(icur) == ind(nbed)){
81bba717 653 // Attention the curfin can be wrong if the last edge passes
654 // above the origin periodic spline.
7fd59977 655 Standard_Real biddeb = FirstParameter(ind(icur));
656 biddeb = ElCLib::InPeriod(biddeb,spinedeb + tol3d, spinefin + tol3d);
657 if(biddeb >= curfin) curfin = fin;
658 else curfin = Min(fin,curfin);
659 }
660 else curfin = Min(fin,curfin);
661 }
662 if((curfin - curdeb) > tol3d){
663 Rdeb = Rcur;
664 Handle(Law_Constant) curloi = new Law_Constant();
665 curloi->Set(Rdeb,curdeb,curfin);
666 list.Append(curloi);
667 curdeb = curfin;
668 }
669 }
670 else {
671 curfin = LastParameter(ind(icur));
672 if(IsPeriodic())
673 curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d);
674 curfin = Min(fin,curfin);
675 lawencours = Standard_True;
676 if(ind(icur) == ind(nbed)){
81bba717 677 // Attention the curfin can be wrong if the last edge passes
678 // above the origin periodic spline.
7fd59977 679 if(IsPeriodic()) {
680 Standard_Real biddeb = FirstParameter(ind(icur));
681 curfin = LastParameter(ind(icur));
682 biddeb = ElCLib::InPeriod(biddeb,spinedeb + tol3d, spinefin + tol3d);
683 curfin = ElCLib::InPeriod(curfin,spinedeb + tol3d, spinefin + tol3d);
684 if(biddeb >= curfin) curfin = fin;
685 else curfin = Min(fin,curfin);
686 }
81bba717 687 // or if it is the end of spine with extension.
7fd59977 688 else if(ind(icur) == len) curfin = fin;
689 Law_Laws temp;
690 mklaw(temp,parandrad,curdeb,curfin,Rdeb,Rfin,
691 IsPeriodic(),spinedeb,spinefin,tol3d);
692 list.Append(temp);
693 }
694 }
695 }
696 if(!lastloi.IsNull()) list.Append(lastloi);
697 return loi;
698}
699
700//=======================================================================
701//function : Law
702//purpose :
703//=======================================================================
704
705Handle(Law_Composite) ChFiDS_FilSpine::Law(const Handle(ChFiDS_HElSpine)& Els) const
706{
707 ChFiDS_ListIteratorOfListOfHElSpine Itsp(elspines);
708 Law_ListIteratorOfLaws Itl(laws);
709 for(; Itsp.More(); Itsp.Next(), Itl.Next()){
710 if(Els == Itsp.Value()){
711 return Handle(Law_Composite)::DownCast(Itl.Value());
712 }
713 }
714 return Handle(Law_Composite)();
715}
716
717//=======================================================================
718//function : Law
719//purpose :
720//=======================================================================
721
722Handle(Law_Function)& ChFiDS_FilSpine::ChangeLaw(const TopoDS_Edge& E)
723{
724 if(!SplitDone()) {
81bba717 725 Standard_DomainError::Raise("ChFiDS_FilSpine::ChangeLaw : the limits are not up-to-date");
7fd59977 726 }
727 Standard_Integer IE = Index(E);
728 if (IsConstant(IE)) {
81bba717 729 Standard_DomainError::Raise("ChFiDS_FilSpine::ChangeLaw : no law on constant edges");
7fd59977 730 }
731 Handle(ChFiDS_HElSpine) hsp = ElSpine(IE);
732 Standard_Real w = 0.5*(FirstParameter(IE) + LastParameter(IE));
733 Handle(Law_Composite) lc = Law(hsp);
734 return lc->ChangeElementaryLaw(w);
735}
736
737
738//=======================================================================
739//function : Radius
740//purpose :
741//=======================================================================
742
743Standard_Real ChFiDS_FilSpine::MaxRadFromSeqAndLaws()const
744{
745 Standard_Real MaxRad = 0.;
746
747 for (Standard_Integer i = 1; i <= parandrad.Length(); i++)
748 if (parandrad(i).Y() > MaxRad)
749 MaxRad = parandrad(i).Y();
750
751 Law_ListIteratorOfLaws itl( laws );
752 for (; itl.More(); itl.Next())
753 {
754 Handle(Law_Function) law = itl.Value();
755 Standard_Real fpar, lpar, par, delta, rad;
756 law->Bounds( fpar, lpar );
757 delta = (lpar - fpar)*0.2;
758 for (Standard_Integer i = 0; i <= 4; i++)
759 {
760 par = fpar + i*delta;
761 rad = law->Value(par);
762 if (rad > MaxRad)
763 MaxRad = rad;
764 }
765 rad = law->Value(lpar);
766 if (rad > MaxRad)
767 MaxRad = rad;
768 }
769
770 return MaxRad;
771}