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_ElSpine.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
IMPLEMENT_STANDARD_RTTIEXT(ChFiDS_Spine,Standard_Transient)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 //=======================================================================
ChFiDS_Spine(const Standard_Real Tol)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
AppendElSpine(const Handle (ChFiDS_ElSpine)& Els)100 void ChFiDS_Spine::AppendElSpine(const Handle(ChFiDS_ElSpine)& Els)
101 {
102 elspines.Append(Els);
103 }
104
105 //=======================================================================
106 //function : AppendOffsetElSpine
107 //purpose :
108 //=======================================================================
109
AppendOffsetElSpine(const Handle (ChFiDS_ElSpine)& Els)110 void ChFiDS_Spine::AppendOffsetElSpine(const Handle(ChFiDS_ElSpine)& Els)
111 {
112 offset_elspines.Append(Els);
113 }
114
115 //=======================================================================
116 //function : ElSpine
117 //purpose :
118 //=======================================================================
119
Handle(ChFiDS_ElSpine)120 Handle(ChFiDS_ElSpine) ChFiDS_Spine::ElSpine(const TopoDS_Edge& E) const
121 {
122 return ElSpine(Index(E));
123 }
124
Handle(ChFiDS_ElSpine)125 Handle(ChFiDS_ElSpine) 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
Handle(ChFiDS_ElSpine)132 Handle(ChFiDS_ElSpine) 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_ElSpine) 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_ElSpine)();
146 }
147 }
148
149 //=======================================================================
150 //function : ChangeElSpines
151 //purpose :
152 //=======================================================================
153
ChangeElSpines()154 ChFiDS_ListOfHElSpine& ChFiDS_Spine::ChangeElSpines()
155 {
156 return elspines;
157 }
158
159 //=======================================================================
160 //function : ChangeOffsetElSpines
161 //purpose :
162 //=======================================================================
163
ChangeOffsetElSpines()164 ChFiDS_ListOfHElSpine& ChFiDS_Spine::ChangeOffsetElSpines()
165 {
166 return offset_elspines;
167 }
168
169 //=======================================================================
170 //function : SplitDone
171 //purpose :
172 //=======================================================================
173
SplitDone(const Standard_Boolean B)174 void ChFiDS_Spine::SplitDone(const Standard_Boolean B)
175 {
176 splitdone = B;
177 }
178
179 //=======================================================================
180 //function : SplitDone
181 //purpose :
182 //=======================================================================
183
SplitDone() const184 Standard_Boolean ChFiDS_Spine::SplitDone() const
185 {
186 return splitdone;
187 }
188
189 //=======================================================================
190 //function : Reset
191 //purpose :
192 //=======================================================================
193
Reset(const Standard_Boolean AllData)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
FirstParameter() const211 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
LastParameter() const223 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
SetFirstParameter(const Standard_Real Par)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
SetLastParameter(const Standard_Real Par)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
FirstParameter(const Standard_Integer IndexSpine) const270 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
LastParameter(const Standard_Integer IndexSpine) const282 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
Length(const Standard_Integer IndexSpine) const293 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
IsPeriodic() const305 Standard_Boolean ChFiDS_Spine::IsPeriodic() const
306 {
307 return (firstState == ChFiDS_Closed);
308 }
309
310
311 //=======================================================================
312 //function : IsClosed
313 //purpose :
314 //=======================================================================
315
IsClosed() const316 Standard_Boolean ChFiDS_Spine::IsClosed() const
317 {
318 return (FirstVertex().IsSame(LastVertex()));
319 }
320
321
322 //=======================================================================
323 //function : FirstVertex
324 //purpose :
325 //=======================================================================
326
FirstVertex() const327 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
LastVertex() const340 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
Absc(const TopoDS_Vertex & V) const353 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
Period() const382 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
Resolution(const Standard_Real R3d) const394 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
SetFirstTgt(const Standard_Real W)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
SetLastTgt(const Standard_Real W)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
HasFirstTgt() const451 Standard_Boolean ChFiDS_Spine::HasFirstTgt()const
452 {
453 return hasfirsttgt;
454 }
455
456 //=======================================================================
457 //function : HasLastTgt
458 //purpose :
459 //=======================================================================
460
HasLastTgt() const461 Standard_Boolean ChFiDS_Spine::HasLastTgt()const
462 {
463 return haslasttgt;
464 }
465
466 //=======================================================================
467 //function : SetReference
468 //purpose :
469 //=======================================================================
470
SetReference(const Standard_Real W)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
SetReference(const Standard_Integer I)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
Index(const Standard_Real W,const Standard_Boolean Forward) const498 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
Index(const TopoDS_Edge & E) const525 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
UnsetReference()538 void ChFiDS_Spine::UnsetReference()
539 {
540 hasref = Standard_False;
541 }
542
543 //=======================================================================
544 //function : Load
545 //purpose :
546 //=======================================================================
547
Load()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
Absc(const Standard_Real U)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
Absc(const Standard_Real U,const Standard_Integer I)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
Parameter(const Standard_Real AbsC,Standard_Real & U,const Standard_Boolean Oriented)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
Parameter(const Standard_Integer Index,const Standard_Real AbsC,Standard_Real & U,const Standard_Boolean Oriented)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
Prepare(Standard_Real & L,Standard_Integer & Ind) const664 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
Value(const Standard_Real AbsC)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
D0(const Standard_Real AbsC,gp_Pnt & P)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
D1(const Standard_Real AbsC,gp_Pnt & P,gp_Vec & V1)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
D2(const Standard_Real AbsC,gp_Pnt & P,gp_Vec & V1,gp_Vec & V2)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
SetCurrent(const Standard_Integer Index)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
CurrentElementarySpine(const Standard_Integer Index)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
GetType() const896 GeomAbs_CurveType ChFiDS_Spine::GetType() const
897 {
898 return myCurve.GetType();
899 }
900
901 //=======================================================================
902 //function : Line
903 //purpose :
904 //=======================================================================
905
Line() const906 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
Circle() const925 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 //=======================================================================
SetErrorStatus(const ChFiDS_ErrorStatus state)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
ErrorStatus() const951 ChFiDS_ErrorStatus ChFiDS_Spine::ErrorStatus()const
952 {
953 return errorstate;
954 }
955