Integration of OCCT 6.5.0 from SVN
[occt.git] / src / ChFiDS / ChFiDS_Spine.cxx
CommitLineData
7fd59977 1// File: ChFiDS_Spine.cxx
2// Created: Thu Nov 18 12:36:53 1993
3// Author: Isabelle GRIGNON
4// <isg@zerox>
5// Modified by isg, Thu Mar 17 09:21:31 1994
6
7
8#include <ChFiDS_Spine.ixx>
9#include <ChFiDS_HElSpine.hxx>
10#include <ChFiDS_ErrorStatus.hxx>
11#include <ChFiDS_ListIteratorOfListOfHElSpine.hxx>
12#include <GCPnts_AbscissaPoint.hxx>
13#include <TopExp.hxx>
14#include <BRep_Tool.hxx>
15#include <ElCLib.hxx>
16#include <Precision.hxx>
17
18//=======================================================================
19//function : ChFiDS_Spine
20//purpose :
21//=======================================================================
22
23ChFiDS_Spine::ChFiDS_Spine():
24 splitdone(Standard_False),
25 tolesp(Precision::Confusion()),
26 firstprolon(Standard_False),
27 lastprolon(Standard_False),
28 firstistgt(Standard_False),
29 lastistgt(Standard_False),
30 hasfirsttgt(Standard_False),
31 haslasttgt(Standard_False),
32 hasref(Standard_False)
33{
34}
35
36ChFiDS_Spine::ChFiDS_Spine(const Standard_Real Tol):
37 splitdone(Standard_False),
38 tolesp(Tol),
39 firstprolon(Standard_False),
40 lastprolon(Standard_False),
41 firstistgt(Standard_False),
42 lastistgt(Standard_False),
43 hasfirsttgt(Standard_False),
44 haslasttgt(Standard_False),
45 hasref(Standard_False)
46{
47}
48
49//=======================================================================
50//function : AppendElSpine
51//purpose :
52//=======================================================================
53
54void ChFiDS_Spine::AppendElSpine(const Handle(ChFiDS_HElSpine)& Els)
55{
56 elspines.Append(Els);
57}
58
59//=======================================================================
60//function : ElSpine
61//purpose :
62//=======================================================================
63
64Handle(ChFiDS_HElSpine) ChFiDS_Spine::ElSpine(const TopoDS_Edge& E) const
65{
66 return ElSpine(Index(E));
67}
68
69Handle(ChFiDS_HElSpine) ChFiDS_Spine::ElSpine(const Standard_Integer IE) const
70{
71 Standard_Real wmil = 0.5 * (FirstParameter(IE) + LastParameter(IE));
72 if(IsPeriodic()) wmil = ElCLib::InPeriod(wmil,FirstParameter(),LastParameter());
73 return ElSpine(wmil);
74}
75
76Handle(ChFiDS_HElSpine) ChFiDS_Spine::ElSpine(const Standard_Real W) const
77{
78 ChFiDS_ListIteratorOfListOfHElSpine It(elspines);
79 for (; It.More(); It.Next()) {
80 Handle(ChFiDS_HElSpine) cur = It.Value();
81 Standard_Real uf = cur->FirstParameter();
82 Standard_Real ul = cur->LastParameter();
83 if(uf <= W && W <= ul) return cur;
84 }
85 return Handle(ChFiDS_HElSpine)();
86}
87
88//=======================================================================
89//function : ChangeElSpines
90//purpose :
91//=======================================================================
92
93ChFiDS_ListOfHElSpine& ChFiDS_Spine::ChangeElSpines()
94{
95 return elspines;
96}
97
98//=======================================================================
99//function : SplitDone
100//purpose :
101//=======================================================================
102
103void ChFiDS_Spine::SplitDone(const Standard_Boolean B)
104{
105 splitdone = B;
106}
107
108//=======================================================================
109//function : SplitDone
110//purpose :
111//=======================================================================
112
113Standard_Boolean ChFiDS_Spine::SplitDone() const
114{
115 return splitdone;
116}
117
118//=======================================================================
119//function : Reset
120//purpose :
121//=======================================================================
122
123void ChFiDS_Spine::Reset(const Standard_Boolean AllData)
124{
125 splitdone = Standard_False;
126 //if(AllData && !isconstant.IsNull()) isconstant->ChangeArray1().Init(0);
127 elspines.Clear();
128 if(AllData){
129 firstparam = 0.;
130 lastparam = abscissa->Value(abscissa->Upper());
131 firstprolon = lastprolon = Standard_False;
132 }
133}
134
135//=======================================================================
136//function : FirstParameter
137//purpose :
138//=======================================================================
139
140Standard_Real ChFiDS_Spine::FirstParameter() const
141{
142 if(firstprolon) return firstparam;
143 return 0.;
144}
145
146
147//=======================================================================
148//function : LastParameter
149//purpose :
150//=======================================================================
151
152Standard_Real ChFiDS_Spine::LastParameter() const
153{
154 if(lastprolon) return lastparam;
155 return abscissa->Value(abscissa->Upper());
156}
157
158//=======================================================================
159//function : SetFirstParameter
160//purpose :
161//=======================================================================
162
163void ChFiDS_Spine::SetFirstParameter(const Standard_Real Par)
164{
165#ifdef DEB
166 if(Par >= Precision::Confusion())
167 cout<<"Prolongement interieur en debut de ligne guide"<<endl;
168 if(IsPeriodic())
169 cout<<"WARNING!!! Prolongement sur ligne guide periodique."<<endl;
170#endif
171 firstprolon = Standard_True;
172 firstparam = Par;
173}
174
175
176//=======================================================================
177//function : SetLastParameter
178//purpose :
179//=======================================================================
180
181void ChFiDS_Spine::SetLastParameter(const Standard_Real Par)
182{
183#ifdef DEB
184 Standard_Real lll = abscissa->Value(abscissa->Upper());
185 if((Par - lll) <= -Precision::Confusion())
186 cout<<"Prolongement interieur en fin de ligne guide"<<endl;
187 if(IsPeriodic())
188 cout<<"WARNING!!! Prolongement sur ligne guide periodique."<<endl;
189#endif
190 lastprolon = Standard_True;
191 lastparam = Par;
192}
193
194//=======================================================================
195//function : FirstParameter
196//purpose :
197//=======================================================================
198
199Standard_Real ChFiDS_Spine::FirstParameter
200(const Standard_Integer IndexSpine) const
201{
202 if (IndexSpine==1) return 0.;
203 return abscissa->Value(IndexSpine-1);
204}
205
206//=======================================================================
207//function : LastParameter
208//purpose :
209//=======================================================================
210
211Standard_Real ChFiDS_Spine::LastParameter
212(const Standard_Integer IndexSpine) const
213{
214 return abscissa->Value(IndexSpine);
215}
216
217//=======================================================================
218//function : Length
219//purpose :
220//=======================================================================
221
222Standard_Real ChFiDS_Spine::Length
223(const Standard_Integer IndexSpine) const
224{
225 if (IndexSpine==1) return abscissa->Value(IndexSpine);
226 return abscissa->Value(IndexSpine) - abscissa->Value(IndexSpine-1);
227}
228
229//=======================================================================
230//function : IsPeriodic
231//purpose :
232//=======================================================================
233
234Standard_Boolean ChFiDS_Spine::IsPeriodic() const
235{
236 return (firstState == ChFiDS_Closed);
237}
238
239
240//=======================================================================
241//function : IsClosed
242//purpose :
243//=======================================================================
244
245Standard_Boolean ChFiDS_Spine::IsClosed() const
246{
247 return (FirstVertex().IsSame(LastVertex()));
248}
249
250
251//=======================================================================
252//function : FirstVertex
253//purpose :
254//=======================================================================
255
256TopoDS_Vertex ChFiDS_Spine::FirstVertex() const
257{
258 TopoDS_Edge E = TopoDS::Edge(spine.First());
259 if(E.Orientation() == TopAbs_FORWARD) return TopExp::FirstVertex(E);
260 return TopExp::LastVertex(E);
261}
262
263
264//=======================================================================
265//function : LastVertex
266//purpose :
267//=======================================================================
268
269TopoDS_Vertex ChFiDS_Spine::LastVertex() const
270{
271 TopoDS_Edge E = TopoDS::Edge(spine.Last());
272 if(E.Orientation() == TopAbs_FORWARD) return TopExp::LastVertex(E);
273 return TopExp::FirstVertex(E);
274}
275
276
277//=======================================================================
278//function : Absc
279//purpose :
280//=======================================================================
281
282Standard_Real ChFiDS_Spine::Absc(const TopoDS_Vertex& V) const
283{
284 TopoDS_Vertex d,f;
285 TopoDS_Edge E;
286 for(Standard_Integer i = 1; i<=spine.Length(); i++){
287 E = TopoDS::Edge(spine.Value(i));
288 TopExp::Vertices(E,d,f);
289 if(d.IsSame(V) && E.Orientation() == TopAbs_FORWARD){
290 return FirstParameter(i);
291 }
292 if(d.IsSame(V) && E.Orientation() == TopAbs_REVERSED){
293 return LastParameter(i);
294 }
295 if(f.IsSame(V) && E.Orientation() == TopAbs_FORWARD){
296 return LastParameter(i);
297 }
298 if(f.IsSame(V) && E.Orientation() == TopAbs_REVERSED){
299 return FirstParameter(i);
300 }
301 }
302 return -1.;
303}
304
305
306//=======================================================================
307//function : Period
308//purpose :
309//=======================================================================
310
311Standard_Real ChFiDS_Spine::Period() const
312{
313 if(!IsPeriodic()) Standard_Failure::Raise("Spine non periodique");
314 return abscissa->Value(abscissa->Upper());
315}
316
317
318//=======================================================================
319//function : Resolution
320//purpose :
321//=======================================================================
322
323Standard_Real ChFiDS_Spine::Resolution(const Standard_Real R3d) const
324{
325 return R3d;
326}
327
328
329//=======================================================================
330//function : SetFirstTgt
331//purpose :
332//=======================================================================
333
334void ChFiDS_Spine::SetFirstTgt(const Standard_Real W)
335{
336 if(IsPeriodic()) Standard_Failure::Raise
337 ("Pas de prolongement par tangente sur les contours periodiques");
338#ifdef DEB
339 if(W >= Precision::Confusion())
340 cout<<"Prolongement interieur en debut de ligne guide"<<endl;
341#endif
342 //On vire le flag au cas ou il serait deja positionne pour
343 //ne pas planter le d1
344 hasfirsttgt = Standard_False;
345 D1(W,firstori,firsttgt);
346 //et on le remet.
347 hasfirsttgt = Standard_True;
348 firsttgtpar = W;
349}
350
351
352//=======================================================================
353//function : SetLastTgt
354//purpose :
355//=======================================================================
356
357void ChFiDS_Spine::SetLastTgt(const Standard_Real W)
358{
359 if(IsPeriodic()) Standard_Failure::Raise
360 ("Pas de prologement par tangente sur les contours periodiques");
361
362#ifdef DEB
363 Standard_Real L = W - abscissa->Value(abscissa->Upper());
364 if(L <= -Precision::Confusion())
365 cout<<"Prolongement interieur en fin de ligne guide"<<endl;
366#endif
367 //On vire le flag au cas ou il serait deja positionne pour
368 //ne pas planter le d1
369 haslasttgt = Standard_False;
370 D1(W,lastori,lasttgt);
371 //et on le remet.
372 haslasttgt = Standard_True;
373 lasttgtpar = W;
374}
375
376
377//=======================================================================
378//function : HasFirstTgt
379//purpose :
380//=======================================================================
381
382Standard_Boolean ChFiDS_Spine::HasFirstTgt()const
383{
384 return hasfirsttgt;
385}
386
387//=======================================================================
388//function : HasLastTgt
389//purpose :
390//=======================================================================
391
392Standard_Boolean ChFiDS_Spine::HasLastTgt()const
393{
394 return haslasttgt;
395}
396
397//=======================================================================
398//function : SetReference
399//purpose :
400//=======================================================================
401
402void ChFiDS_Spine::SetReference(const Standard_Real W)
403{
404 hasref = Standard_True;
405 Standard_Real lll = abscissa->Value(abscissa->Upper());
406 if(IsPeriodic()) valref = ElCLib::InPeriod(W,0.,lll);
407 else valref = W;
408}
409
410
411//=======================================================================
412//function : SetReference
413//purpose :
414//=======================================================================
415
416void ChFiDS_Spine::SetReference(const Standard_Integer I)
417{
418 hasref = Standard_True;
419 if(I == 1) valref = abscissa->Value(1)*0.5;
420 else valref = (abscissa->Value(I) + abscissa->Value(I-1))*0.5;
421}
422
423
424//=======================================================================
425//function : Index
426//purpose :
427//=======================================================================
428
429Standard_Integer ChFiDS_Spine::Index(const Standard_Real W,
430 const Standard_Boolean Forward) const
431{
432 Standard_Integer ind, len = abscissa->Length();
433 Standard_Real par = W,last = abscissa->Value(abscissa->Upper());
434 Standard_Real f = 0., l = 0., t = Max(tolesp,Precision::Confusion());
435
436 if(IsPeriodic() && Abs(par) >= t && Abs(par-last) >= t)
437 par = ElCLib::InPeriod(par,0.,last);
438
439 for (ind=1; ind <= len; ind++) {
440 f = l;
441 l = abscissa->Value(ind);
442 if (par<l || ind==len) break;
443 }
444 if (Forward && ind<len && Abs(par-l) < t) ind++;
445 else if (!Forward && ind > 1 && Abs(par-f) < t) ind--;
446 else if (Forward && IsPeriodic() && ind == len && Abs(par-l) < t) ind = 1;
447 else if (!Forward && IsPeriodic() && ind == 1 && Abs(par-f) < t) ind = len;
448 return ind;
449}
450
451//=======================================================================
452//function : Index
453//purpose :
454//=======================================================================
455
456Standard_Integer ChFiDS_Spine::Index (const TopoDS_Edge& E) const
457{
458 for(Standard_Integer IE = 1; IE <= spine.Length(); IE++){
459 if(E.IsSame(spine.Value(IE))) return IE;
460 }
461 return 0;
462}
463
464//=======================================================================
465//function : UnsetReference
466//purpose :
467//=======================================================================
468
469void ChFiDS_Spine::UnsetReference()
470{
471 hasref = Standard_False;
472}
473
474//=======================================================================
475//function : Load
476//purpose :
477//=======================================================================
478
479void ChFiDS_Spine::Load()
480{
481 if(!abscissa.IsNull()){
482#ifdef DEB
483 cout<<"nouveau load du CE"<<endl;
484#endif
485 }
486 Standard_Integer len = spine.Length();
487 abscissa = new TColStd_HArray1OfReal(1,len);
488 Standard_Real a1 = 0.;
489 for (Standard_Integer i = 1; i <= len; i++){
490 myCurve.Initialize(TopoDS::Edge(spine.Value(i)));
491 a1 += GCPnts_AbscissaPoint::Length(myCurve);
492 abscissa->SetValue(i,a1);
493 }
494 indexofcurve =1;
495 myCurve.Initialize(TopoDS::Edge(spine.Value(1)));
496}
497
498
499//=======================================================================
500//function : Absc
501//purpose :
502//=======================================================================
503
504Standard_Real ChFiDS_Spine::Absc(const Standard_Real U)
505{
506 return Absc(U,indexofcurve);
507}
508
509//=======================================================================
510//function : Absc
511//purpose :
512//=======================================================================
513
514Standard_Real ChFiDS_Spine::Absc(const Standard_Real U,
515 const Standard_Integer I)
516{
517
518
519 if(indexofcurve != I){
520 void* p = (void*)this;
521 ((ChFiDS_Spine*)p)->indexofcurve = I;
522 ((ChFiDS_Spine*)p)->myCurve.Initialize(TopoDS::Edge(spine.Value(I)));
523 }
524 Standard_Real L = FirstParameter(I);
525 if (spine.Value(I).Orientation() == TopAbs_REVERSED) {
526 L += GCPnts_AbscissaPoint::Length(myCurve,U,myCurve.LastParameter());
527 }
528 else{
529 L += GCPnts_AbscissaPoint::Length(myCurve,myCurve.FirstParameter(),U);
530 }
531 return L;
532}
533
534//=======================================================================
535//function : Parameter
536//purpose :
537//=======================================================================
538
539void ChFiDS_Spine::Parameter(const Standard_Real AbsC,
540 Standard_Real& U,
541 const Standard_Boolean Oriented)
542{
543 Standard_Integer Index;
544 for (Index=1;Index<abscissa->Length();Index++) {
545 if (AbsC<abscissa->Value(Index)) break;
546 }
547 Parameter(Index,AbsC,U,Oriented);
548}
549
550
551//=======================================================================
552//function : Parameter
553//purpose :
554//=======================================================================
555
556void ChFiDS_Spine::Parameter(const Standard_Integer Index,
557 const Standard_Real AbsC,
558 Standard_Real& U,
559 const Standard_Boolean Oriented)
560{
561
562 if (Index != indexofcurve) {
563 void* p = (void*)this;
564 ((ChFiDS_Spine*)p)->indexofcurve = Index;
565 ((ChFiDS_Spine*)p)->myCurve.Initialize(TopoDS::Edge(spine.Value(Index)));
566 }
567 Standard_Real L;
568 TopAbs_Orientation Or = spine.Value(Index).Orientation();
569 if (Or == TopAbs_REVERSED) {
570 L = abscissa->Value(indexofcurve)-AbsC;
571 }
572 else if (indexofcurve==1) {
573 L = AbsC;
574 }
575 else {
576 L = AbsC - abscissa->Value(indexofcurve-1);
577 }
578 Standard_Real t = L/Length(Index);
579 Standard_Real uapp = (1. - t) * myCurve.FirstParameter() + t * myCurve.LastParameter();
580// GCPnts_AbscissaPoint GCP;
581// GCP.Perform(myCurve,L,myCurve.FirstParameter(),uapp,BRep_Tool::Tolerance(myCurve.Edge()));
582 GCPnts_AbscissaPoint GCP(myCurve,L,myCurve.FirstParameter(),uapp);
583 U = GCP.Parameter();
584 if (Or == TopAbs_REVERSED && Oriented) {
585 U = (myCurve.LastParameter()+myCurve.FirstParameter()) - U;
586 }
587}
588
589
590//=======================================================================
591//function : Prepare
592//purpose :
593//=======================================================================
594
595void ChFiDS_Spine::Prepare(Standard_Real& L,
596 Standard_Integer& Ind) const
597{
598 Standard_Real tol = Max(tolesp,Precision::Confusion());
599 Standard_Real last = abscissa->Value(abscissa->Upper());
600 Standard_Integer len = abscissa->Length();
601 if(IsPeriodic() && Abs(L) >= tol && Abs(L-last) >= tol)
602 L = ElCLib::InPeriod(L,0.,last);
603
604 if(hasfirsttgt && (L <= firsttgtpar)){
605 if(hasref && valref >= L && Abs(L-firsttgtpar) <= tol){
606 Ind = Index(L);
607 }
608 else{Ind = -1; L -= firsttgtpar;}
609 }
610 else if(L <= 0.){Ind = 1;}
611 else if(haslasttgt && (L >= lasttgtpar)){
612 if(hasref && valref <= L && Abs(L-lasttgtpar) <= tol){
613 Ind = Index(L);
614 }
615 else{Ind = len + 1; L -= lasttgtpar;}
616 }
617 else if(L >= last){Ind = len;}
618 else{
619 for (Ind=1;Ind < len;Ind++) {
620 if (L<abscissa->Value(Ind)) break;
621 }
622 if(hasref){
623 if (L >= valref && Ind != 1){
624 if(Abs(L-abscissa->Value(Ind-1)) <= Precision::Confusion()) Ind--;
625 }
626 else if (L <= valref && Ind != len){
627 if(Abs(L-abscissa->Value(Ind)) <= Precision::Confusion()) Ind++;
628 }
629 }
630 }
631 if(Ind >= 1 && Ind <= len){
632 if (spine.Value(Ind).Orientation() == TopAbs_REVERSED){
633 L = abscissa->Value(Ind) - L;
634 }
635 else if (Ind!=1){
636 L -= abscissa->Value(Ind - 1);
637 }
638 }
639}
640
641//=======================================================================
642//function : Value
643//purpose :
644//=======================================================================
645
646gp_Pnt ChFiDS_Spine::Value(const Standard_Real AbsC)
647{
648
649 Standard_Integer Index;
650 Standard_Real L = AbsC;
651
652 Prepare(L,Index);
653
654 if (Index == -1) {
655 gp_Pnt Pp = firstori;
656 gp_Vec Vp = firsttgt;
657 Vp.Multiply(L);
658 Pp.Translate(Vp);
659 return Pp;
660 }
661 else if (Index == (abscissa->Length() + 1)) {
662 gp_Pnt Pp = lastori;
663 gp_Vec Vp = lasttgt;
664 Vp.Multiply(L);
665 Pp.Translate(Vp);
666 return Pp;
667 }
668 if (Index != indexofcurve) {
669 void* p = (void*)this;
670 ((ChFiDS_Spine*)p)->indexofcurve = Index;
671 ((ChFiDS_Spine*)p)->myCurve.Initialize(TopoDS::Edge(spine.Value(Index)));
672 }
673 Standard_Real t = L/Length(Index);
674 Standard_Real uapp = (1. - t) * myCurve.FirstParameter() + t * myCurve.LastParameter();
675// GCPnts_AbscissaPoint GCP;
676// GCP.Perform(myCurve,L,myCurve.FirstParameter(),uapp,BRep_Tool::Tolerance(myCurve.Edge()));
677 GCPnts_AbscissaPoint GCP(myCurve,L,myCurve.FirstParameter(),uapp);
678 return myCurve.Value(GCP.Parameter());
679}
680
681//=======================================================================
682//function : D0
683//purpose :
684//=======================================================================
685
686void ChFiDS_Spine::D0(const Standard_Real AbsC, gp_Pnt& P)
687{
688 P = Value(AbsC);
689}
690
691//=======================================================================
692//function : D1
693//purpose :
694//=======================================================================
695
696void ChFiDS_Spine::D1(const Standard_Real AbsC,
697 gp_Pnt& P,
698 gp_Vec& V1)
699{
700 Standard_Integer Index;
701 Standard_Real L = AbsC;
702
703 Prepare(L,Index);
704
705 if (Index == -1) {
706 P = firstori;
707 V1 = firsttgt;
708 gp_Vec Vp = firsttgt;
709 Vp.Multiply(L);
710 P.Translate(Vp);
711 }
712 else if (Index == (abscissa->Length() + 1)) {
713 P = lastori;
714 V1 = lasttgt;
715 gp_Vec Vp = lasttgt;
716 Vp.Multiply(L);
717 P.Translate(Vp);
718 }
719 else {
720 if (Index != indexofcurve) {
721 void* p = (void*)this;
722 ((ChFiDS_Spine*)p)->indexofcurve = Index;
723 ((ChFiDS_Spine*)p)->myCurve.Initialize(TopoDS::Edge(spine.Value(Index)));
724 }
725 Standard_Real t = L/Length(Index);
726 Standard_Real uapp = (1. - t) * myCurve.FirstParameter() + t * myCurve.LastParameter();
727// GCPnts_AbscissaPoint GCP;
728// GCP.Perform(myCurve,L,myCurve.FirstParameter(),uapp,BRep_Tool::Tolerance(myCurve.Edge()));
729 GCPnts_AbscissaPoint GCP(myCurve,L,myCurve.FirstParameter(),uapp);
730 myCurve.D1(GCP.Parameter(),P,V1);
731 Standard_Real D1 = 1./V1.Magnitude();
732 if (spine.Value(Index).Orientation() == TopAbs_REVERSED) D1 = -D1;
733 V1.Multiply(D1);
734 }
735}
736
737
738//=======================================================================
739//function : D2
740//purpose :
741//=======================================================================
742
743void ChFiDS_Spine::D2(const Standard_Real AbsC,
744 gp_Pnt& P,
745 gp_Vec& V1,
746 gp_Vec& V2)
747{
748
749 Standard_Integer Index;
750 Standard_Real L = AbsC;
751
752 Prepare(L,Index);
753
754 if (Index == -1) {
755 P = firstori;
756 V1 = firsttgt;
757 V2.SetCoord(0.,0.,0.);
758 gp_Vec Vp = firsttgt;
759 Vp.Multiply(L);
760 P.Translate(Vp);
761 }
762 else if (Index == (abscissa->Length() + 1)) {
763 P = lastori;
764 V1 = lasttgt;
765 V2.SetCoord(0.,0.,0.);
766 gp_Vec Vp = lasttgt;
767 Vp.Multiply(L);
768 P.Translate(Vp);
769 }
770 else {
771 if (Index != indexofcurve) {
772 void* p = (void*)this;
773 ((ChFiDS_Spine*)p)->indexofcurve = Index;
774 ((ChFiDS_Spine*)p)->myCurve.Initialize(TopoDS::Edge(spine.Value(Index)));
775 }
776 Standard_Real t = L/Length(Index);
777 Standard_Real uapp = (1. - t) * myCurve.FirstParameter() + t * myCurve.LastParameter();
778// GCPnts_AbscissaPoint GCP;
779// GCP.Perform(myCurve,L,myCurve.FirstParameter(),uapp,BRep_Tool::Tolerance(myCurve.Edge()));
780 GCPnts_AbscissaPoint GCP(myCurve,L,myCurve.FirstParameter(),uapp);
781 myCurve.D2(GCP.Parameter(),P,V1,V2);
782 Standard_Real N1 = V1.SquareMagnitude();
783 Standard_Real D2 = -(V1.Dot(V2))*(1./N1)*(1./N1);
784 V2.Multiply(1./N1);
785 N1 = Sqrt(N1);
786 gp_Vec Va = V1.Multiplied(D2);
787 V2.Add(Va);
788 Standard_Real D1 = 1./N1;
789 if (spine.Value(Index).Orientation() == TopAbs_REVERSED) D1 = -D1;
790 V1.Multiply(D1);
791 }
792}
793
794//=======================================================================
795//function : SetCurrent
796//purpose :
797//=======================================================================
798
799void ChFiDS_Spine::SetCurrent(const Standard_Integer Index)
800{
801 if (Index != indexofcurve) {
802 indexofcurve = Index;
803 myCurve.Initialize(TopoDS::Edge(spine.Value(indexofcurve)));
804 }
805}
806
807//=======================================================================
808//function : CurrentElementarySpine
809//purpose :
810//=======================================================================
811
812const BRepAdaptor_Curve& ChFiDS_Spine::CurrentElementarySpine
813(const Standard_Integer Index)
814{
815 if (Index != indexofcurve) {
816 indexofcurve = Index;
817 myCurve.Initialize(TopoDS::Edge(spine.Value(indexofcurve)));
818 }
819 return myCurve;
820}
821
822//=======================================================================
823//function : GetType
824//purpose :
825//=======================================================================
826
827GeomAbs_CurveType ChFiDS_Spine::GetType() const
828{
829 return myCurve.GetType();
830}
831
832//=======================================================================
833//function : Line
834//purpose :
835//=======================================================================
836
837gp_Lin ChFiDS_Spine::Line() const
838{
839 gp_Lin LL(myCurve.Line());
840 if (spine.Value(indexofcurve).Orientation() == TopAbs_REVERSED) {
841 LL.Reverse();
842 LL.SetLocation(myCurve.Value(myCurve.LastParameter()));
843 }
844 else {
845 LL.SetLocation(myCurve.Value(myCurve.FirstParameter()));
846 }
847 return LL;
848}
849
850
851//=======================================================================
852//function : Circle
853//purpose :
854//=======================================================================
855
856gp_Circ ChFiDS_Spine::Circle() const
857{
858 gp_Ax2 Ac = myCurve.Circle().Position();
859 gp_Dir Dc(gp_Vec(Ac.Location(),myCurve.Value(myCurve.FirstParameter())));
860 gp_Dir ZZ(Ac.Direction());
861
862 if (spine.Value(indexofcurve).Orientation() == TopAbs_REVERSED) {
863 Dc = gp_Dir(gp_Vec(Ac.Location(),myCurve.Value(myCurve.LastParameter())));
864 ZZ.Reverse();
865 }
866 gp_Ax2 A(Ac.Location(),ZZ,Dc);
867 return gp_Circ(A,myCurve.Circle().Radius());
868}
869//=======================================================================
870//function : SetErrorStatus
871//purpose : met a jour le statut d'erreur
872//=======================================================================
873void ChFiDS_Spine::SetErrorStatus(const ChFiDS_ErrorStatus state)
874{
875 errorstate=state;
876}
877//=======================================================================
878//function : ErrorStatus
879//purpose : renvoie le statut d'erreur concernant la spine
880//=======================================================================
881
882ChFiDS_ErrorStatus ChFiDS_Spine::ErrorStatus()const
883{
884 return errorstate;
885}