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