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