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