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