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