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