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