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