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