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