0023643: Intersection algorithm produces B-Spline curve in case of coaxial cones
[occt.git] / src / BRepFill / BRepFill_Pipe.cxx
CommitLineData
b311480e 1// Created on: 1994-06-07
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-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
22#include <BRepFill_Pipe.ixx>
23
24#include <Standard_ErrorHandler.hxx>
25
26#include <BRep_Tool.hxx>
27#include <BRep_Builder.hxx>
28#include <BRepClass3d_SolidClassifier.hxx>
29#include <BRepLib_MakeVertex.hxx>
30
31#include <GeomFill_CorrectedFrenet.hxx>
32#include <GeomFill_CurveAndTrihedron.hxx>
33
34#include <BRepFill_SectionPlacement.hxx>
35#include <BRepFill_ShapeLaw.hxx>
36#include <BRepFill_Edge3DLaw.hxx>
37#include <BRepFill_Sweep.hxx>
38
39#include <GeomAbs_Shape.hxx>
40#include <TopExp.hxx>
41#include <TopAbs_ShapeEnum.hxx>
42#include <TopoDS.hxx>
43#include <TopoDS_Shell.hxx>
44#include <TopoDS_Solid.hxx>
45#include <TopoDS_Compound.hxx>
46#include <TopoDS_Iterator.hxx>
47
48#include <Precision.hxx>
49#include <Standard_NotImplemented.hxx>
50
51#include <Geom_TrimmedCurve.hxx>
52#include <Geom_OffsetCurve.hxx>
53#include <Geom_BSplineCurve.hxx>
54
55#ifdef DRAW
56#include <DBRep.hxx>
57static Standard_Boolean Affich = 0;
58#endif
59
60//=======================================================================
61//function : BRepFill_Pipe
62//purpose :
63//=======================================================================
64
65BRepFill_Pipe::BRepFill_Pipe()
66{
67 myDegmax = 10;
68 mySegmax = 100;
69}
70
71
72//=======================================================================
73//function : BRepFill_Pipe
74//purpose :
75//=======================================================================
76
77BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
78 const TopoDS_Shape& Profile,
79 const Standard_Boolean KPart)
80{
81 myDegmax = 10;
82 mySegmax = 100;
83 Perform(Spine, Profile, KPart);
84}
85
86
87
88//=======================================================================
89//function : Perform
90//purpose :
91//=======================================================================
92
93void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
94 const TopoDS_Shape& Profile,
95 const Standard_Boolean KPart)
96
97{
98 mySections.Nullify();
99 myFaces.Nullify();
100 myEdges.Nullify();
101
102 mySpine = Spine;
103 myProfile = Profile;
104
105 DefineRealSegmax();
106
107 BRepTools_WireExplorer wexp;
108 TopoDS_Shape TheProf;
109
110
111 Handle(GeomFill_CorrectedFrenet) TLaw =
112 new (GeomFill_CorrectedFrenet) ();
113 Handle(GeomFill_CurveAndTrihedron) Loc =
114 new (GeomFill_CurveAndTrihedron) (TLaw);
115 myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
116 if (myLoc->NbLaw() == 0) {
0d969553 117 return; // Degenerated case
7fd59977 118 }
0d969553 119 myLoc->TransformInG0Law(); // Set into continuity
7fd59977 120
121 BRepFill_SectionPlacement Place(myLoc, Profile);
122 myTrsf = Place.Transformation();
123
124 TopLoc_Location Loc2(myTrsf), Loc1;
125 Loc1 = Profile.Location();
126 TopoDS_Shape aux;
127 TheProf = myProfile;
128 TheProf.Location(Loc2.Multiplied(Loc1));
129
0d969553 130 // Construct First && Last Shape
7fd59977 131 Handle(GeomFill_LocationLaw) law;
132
133 gp_Mat M;
134 gp_Vec V;
135 gp_Trsf fila;
136 Standard_Real first, last;
137 myLoc->Law(1)->GetDomain(first, last);
138 myLoc->Law(1)->D0(first, M, V);
139 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
140 M(2,1), M(2,2), M(2,3), V.Y(),
141 M(3,1), M(3,2), M(3,3), V.Z(),
142 1.e-12, 1.e-14);
143
144 fila.Multiply(myTrsf);
145 TopLoc_Location LocFirst(fila);
146 myFirst = myProfile;
147 if ( ! LocFirst.IsIdentity()) {
148 myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
149 }
150
151 myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
152 myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
0d969553 153// try { // Not good, but there are no other means to test SetValues
7fd59977 154 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
155 M(2,1), M(2,2), M(2,3), V.Y(),
156 M(3,1), M(3,2), M(3,3), V.Z(),
157 1.e-12, 1.e-14);
158 fila.Multiply(myTrsf);
159 TopLoc_Location LocLast(fila);
160 if (! myLoc->IsClosed() || LocFirst != LocLast) {
161 myLast = myProfile;
162 if ( ! LocLast.IsIdentity()) {
163 myLast.Location(LocLast.Multiplied(myProfile.Location()) );
164 }
165 }
166 else {
167 myLast = myFirst;
168 }
169#if DRAW
170 if (Affich) {
171 DBRep::Set("theprof", TheProf);
172 DBRep::Set("thefirst", myFirst);
173 DBRep::Set("thelast" , myLast);
174 }
175#endif
176
177 myShape = MakeShape(TheProf, myFirst, myLast);
178}
179
180
181//=======================================================================
182//function : Spine
183//purpose :
184//=======================================================================
185
186const TopoDS_Shape& BRepFill_Pipe::Spine() const
187{
188 return mySpine;
189}
190
191//=======================================================================
192//function : Profile
193//purpose :
194//=======================================================================
195
196const TopoDS_Shape& BRepFill_Pipe::Profile() const
197{
198 return myProfile;
199}
200
201//=======================================================================
202//function : Shape
203//purpose :
204//=======================================================================
205
206const TopoDS_Shape& BRepFill_Pipe::Shape() const
207{
208 return myShape;
209}
210
211
212//=======================================================================
213//function : FirstShape
214//purpose :
215//=======================================================================
216
217const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
218{
219 return myFirst;
220}
221
222
223//=======================================================================
224//function : LastShape
225//purpose :
226//=======================================================================
227
228const TopoDS_Shape& BRepFill_Pipe::LastShape() const
229{
230 return myLast;
231}
232
233
234//=======================================================================
235//function : Face
236//purpose :
237//=======================================================================
238
239TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
240 const TopoDS_Edge& EProfile)
241{
242 TopoDS_Face theFace;
243
244 if ( BRep_Tool::Degenerated(EProfile))
245 return theFace;
246
247 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
248
249 // *************************************************
250 // Search if EProfile is an edge of myProfile
251 // *************************************************
252 iprof = FindEdge(myProfile, EProfile, count);
253
254 if (!iprof) Standard_DomainError::Raise(
255 "BRepFill_Pipe::Face : Edge not in the Profile");
256
257
258 // *************************************************
259 // Search if ESpine is an edge of mySpine and find
260 // the index of the corresponding Filler
261 // *************************************************
262 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
263 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
264
265 if (!ispin) Standard_DomainError::Raise(
266 "BRepFill_Pipe::Edge : Edge not in the Spine");
267
268 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
269 return theFace;
270
271}
272
273//=======================================================================
274//function : Edge
275//purpose :
276//=======================================================================
277TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
278 const TopoDS_Vertex& VProfile)
279{
280 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;;
281
282 // *************************************************
283 // Search if VProfile is a Vertex of myProfile
284 // *************************************************
285 iprof = FindVertex(myProfile, VProfile, count);
286 if (!iprof) Standard_DomainError::Raise(
287 "BRepFill_Pipe::Edge : Vertex not in the Profile");
288
289
290 // *************************************************
291 // Search if ESpine is an edge of mySpine and find
292 // the index of the corresponding Filler
293 // *************************************************
294
295 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
296 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
297
298 if (!ispin) Standard_DomainError::Raise(
299 "BRepFill_Pipe::Edge : Edge not in the Spine");
300
301
302 // *************************************************
303 // Generate the corresponding Shape
304 // *************************************************
305 TopoDS_Edge theEdge;
306 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
307
308 return theEdge;
309
310}
311
312
313//=======================================================================
314//function : Section
315//purpose :
316//=======================================================================
317
318TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
319{
320 TopoDS_Iterator it, itv;
321
322 Standard_Integer ii, ispin = 0;
323
324 TopoDS_Shape curSect = myProfile;
325
326 // *************************************************
327 // Search if ESpine is an edge of mySpine and find
328 // the index of the corresponding Filler
329 // *************************************************
330
331 // iterate on all the edges of mySpine
332 for (ii=1; ii<=myLoc->NbLaw()+1 && (!ispin); ii++)
333 if (VSpine.IsSame(myLoc->Vertex(ii))) ispin = ii;
334
335 if (!ispin) Standard_DomainError::Raise(
336 "BRepFill_Pipe::Section : Vertex not in the Spine");
337
338 BRep_Builder B;
339 TopoDS_Compound Comp;
340 B.MakeCompound(Comp);
341 for (ii=1; ii<=mySections->ColLength(); ii++)
342 B.Add(Comp, mySections->Value(ii, ispin));
343
344 return Comp;
345}
346
347//=======================================================================
348//function : PipeLine
0d969553 349//purpose : Construct a wire by sweeping of a point
7fd59977 350//=======================================================================
351
352TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
353{
0d969553 354 // Postioning
7fd59977 355 gp_Pnt P;
356 P = Point;
357 P.Transform(myTrsf);
358
359 BRepLib_MakeVertex MkV(P);
360 Handle(BRepFill_ShapeLaw) Section =
361 new (BRepFill_ShapeLaw) (MkV.Vertex());
362
0d969553 363 // Sweeping
7fd59977 364 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
365 MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
366 TopoDS_Shape aLocalShape = MkSw.Shape();
367 return TopoDS::Wire(aLocalShape);
368// return TopoDS::Wire(MkSw.Shape());
369}
370
371//=======================================================================
372//function : MakeShape
373//purpose :
374//=======================================================================
375
376TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
377 const TopoDS_Shape& FirstShape,
378 const TopoDS_Shape& LastShape)
379{
380 TopoDS_Shape result;
381 BRep_Builder B;
382 Standard_Boolean explode = Standard_False;
383 TopoDS_Shape TheS, TheFirst, TheLast;
384 Standard_Integer InitialLength = 0;
385 TheS = S;
386 TheFirst = FirstShape;
387 TheLast = LastShape;
388 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
389
390 // there are two kinds of generation
391 // 1. generate with S from each Filler (Vertex, Edge)
392 // 2. call MakeShape recursively on the subshapes of S
393 //
394 // explode is True in the second case
395
396 // create the result empty
397
398 switch (S.ShapeType()) {
399
400 case TopAbs_VERTEX :
401 {
402 B.MakeWire(TopoDS::Wire(result));
403 break;
404 }
405
406 case TopAbs_EDGE :
407 {
408 TopoDS_Wire W;
409 B.MakeShell(TopoDS::Shell(result));
410 B.MakeWire(W);
411 B.Add(W, S);
412 W.Closed(S.Closed());
413 TheS = W;
414 if (!FirstShape.IsNull()) {
415 B.MakeWire(W);
416 B.Add(W, FirstShape);
417 W.Closed(FirstShape.Closed());
418 TheFirst = W;
419 }
420 if (!LastShape.IsNull()) {
421 B.MakeWire(W);
422 B.Add(W, LastShape);
423 W.Closed(LastShape.Closed());
424 TheLast = W;
425 }
426 break;
427 }
428
429 case TopAbs_WIRE :
430 B.MakeShell(TopoDS::Shell(result));
431 break;
432
433 case TopAbs_FACE :
434 {
435 B.MakeShell(TopoDS::Shell(result));
436 explode = Standard_True;
437 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
438 B.Add(result, TheFirst.Reversed());
439 }
440 break;
441 }
442
443 case TopAbs_SHELL :
444 {
445 B.MakeCompSolid(TopoDS::CompSolid(result));
446 explode = Standard_True;
447 break;
448 }
449
450 case TopAbs_SOLID :
451 case TopAbs_COMPSOLID :
452 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
453 break;
454
455 case TopAbs_COMPOUND :
456 {
457 B.MakeCompound(TopoDS::Compound(result));
458 explode = Standard_True;
459 break;
460 }
7fd59977 461 default:
462 break;
7fd59977 463 }
464
465 if (explode) {
466 // add the subshapes
467 TopoDS_Iterator itFirst, itLast;
468 TopoDS_Shape first, last;
469 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
470 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
471
472 for (TopoDS_Iterator it(S); it.More(); it.Next()) {
473 if (!TheFirst.IsNull()) first = itFirst.Value();
474 if (!TheLast.IsNull()) last = itLast.Value();
475 if (TheS.ShapeType() == TopAbs_FACE )
476 MakeShape(it.Value(), first, last);
477 else
478 B.Add(result,MakeShape(it.Value(), first, last));
479
480 if (!TheFirst.IsNull()) itFirst.Next();
481 if (!TheLast.IsNull()) itLast.Next();
482 }
483 }
484
485 else {
486 if (TheS.ShapeType() == TopAbs_VERTEX ) {
487 Handle(BRepFill_ShapeLaw) Section =
488 new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
489 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
490 MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
491 result = MkSw.Shape();
492 }
493
494 if (TheS.ShapeType() == TopAbs_WIRE ) {
495 Handle(BRepFill_ShapeLaw) Section =
496 new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS));
497 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
498 MkSw.SetBounds(TopoDS::Wire(TheFirst),
499 TopoDS::Wire(TheLast));
500 MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
501 result = MkSw.Shape();
502
0d969553 503 // Labeling of elements
7fd59977 504 if (mySections.IsNull()) {
505 myFaces = MkSw.SubShape();
506 mySections = MkSw.Sections();
507 myEdges = MkSw.InterFaces();
508 }
509 else {
510 Handle(TopTools_HArray2OfShape) Aux, Somme;
511 Standard_Integer length;
512 Standard_Integer ii, jj, kk;
513
514 Aux = MkSw.SubShape();
515 length = Aux->ColLength() + myFaces->ColLength();
516 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
517 Aux->RowLength());
518 for (jj=1; jj<=myFaces->RowLength(); jj++) {
519 for (ii=1; ii<=myFaces->ColLength(); ii++)
520 Somme->SetValue(ii, jj, myFaces->Value(ii, jj));
521
522 for (kk=1, ii=myFaces->ColLength()+1;
523 kk <=Aux->ColLength(); kk++, ii++)
524 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
525 }
526 myFaces = Somme;
527
528
529 Aux = MkSw.Sections();
530 length = Aux->ColLength() + mySections->ColLength();
531 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
532 Aux->RowLength());
533 for (jj=1; jj<=mySections->RowLength(); jj++) {
534 for (ii=1; ii<=mySections->ColLength(); ii++)
535 Somme->SetValue(ii, jj, mySections->Value(ii, jj));
536
537 for (kk=1, ii=mySections->ColLength()+1;
538 kk <=Aux->ColLength(); kk++, ii++)
539 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
540 }
541 mySections = Somme;
542
543 Aux = MkSw.InterFaces();
544 length = Aux->ColLength() + myEdges->ColLength();
545 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
546 Aux->RowLength());
547 for (jj=1; jj<=myEdges->RowLength(); jj++) {
548 for (ii=1; ii<=myEdges->ColLength(); ii++)
549 Somme->SetValue(ii, jj, myEdges->Value(ii, jj));
550
551 for (kk=1, ii=myEdges->ColLength()+1;
552 kk <=Aux->ColLength(); kk++, ii++)
553 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
554 }
555 myEdges = Somme;
556 }
557 }
558 }
559
560 if ( TheS.ShapeType() == TopAbs_FACE ) {
561 Standard_Integer ii, jj;
562 TopoDS_Face F;
563 for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
564 for (jj=1; jj<=myFaces->RowLength(); jj++) {
565 F = TopoDS::Face(myFaces->Value(ii, jj));
566 if (!F.IsNull()) B.Add(result, F);
567 }
568 }
569
570 if ( !mySpine.Closed()) {
571 // if Spine is not closed
572 // add the last face of the solid
573 B.Add(result, TopoDS::Face(TheLast));
574 }
575
576 TopoDS_Solid solid;
577 BRep_Builder BS;
578 BS.MakeSolid(solid);
579
580 result.Closed(Standard_True);
581 BS.Add(solid,TopoDS::Shell(result));
582
583 BRepClass3d_SolidClassifier SC(solid);
584 SC.PerformInfinitePoint(Precision::Confusion());
585 if ( SC.State() == TopAbs_IN) {
586 BS.MakeSolid(solid);
587 TopoDS_Shape aLocalShape = result.Reversed();
588 BS.Add(solid,TopoDS::Shell(aLocalShape));
589// BS.Add(solid,TopoDS::Shell(result.Reversed()));
590 }
591 return solid;
592 }
593 else {
594 return result;
595 }
596 return result;
597}
598
0d969553 599//============================================================================
7fd59977 600//function : FindEdge
0d969553
Y
601//purpose : Find the number of edge corresponding to the edge of the profile.
602//============================================================================
7fd59977 603
604Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
605 const TopoDS_Edge& E,
606 Standard_Integer& InitialLength) const
607{
608 Standard_Integer result = 0;
609
610 switch (S.ShapeType()) {
611
612 case TopAbs_EDGE :
613 {
614 InitialLength++;
615 if (S.IsSame(E)) result = InitialLength;
616 break;
617 }
618
619 case TopAbs_WIRE :
620 {
621 Standard_Integer ii = InitialLength+1;
622 Handle(BRepFill_ShapeLaw) Section =
623 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
624 InitialLength += Section->NbLaw();
625
626 for (; (ii<=InitialLength) && (!result); ii++) {
627 if (E.IsSame(Section->Edge(ii)) ) result = ii;
628 }
629 break;
630 }
631
632 case TopAbs_FACE :
633 case TopAbs_SHELL :
634 case TopAbs_COMPOUND :
635 {
636 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
637 result = FindEdge(it.Value(), E, InitialLength );
638 break;
639 }
640
641 case TopAbs_SOLID :
642 case TopAbs_COMPSOLID :
643 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
644 break;
7fd59977 645 default:
646 break;
7fd59977 647 }
648
649 return result;
650}
651
652//=======================================================================
653//function : FindVertex
0d969553 654//purpose : Find the number of edge corresponding to an edge of the profile.
7fd59977 655//=======================================================================
656
657Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
658 const TopoDS_Vertex& V,
659 Standard_Integer& InitialLength) const
660{
661 Standard_Integer result = 0;
662
663 switch (S.ShapeType()) {
664 case TopAbs_VERTEX :
665 {
666 InitialLength++;
667 if (S.IsSame(V)) result = InitialLength;
668 break;
669 }
670
671 case TopAbs_EDGE :
672 {
673 TopoDS_Vertex VF, VL;
674 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
675 if (S.Orientation() == TopAbs_REVERSED) {
676 TopoDS_Vertex aux;
677 aux = VF; VF = VL; VL = aux;
678 }
679 if (VF.IsSame(V)) result = InitialLength+1;
680 else if (VL.IsSame(V)) result = InitialLength+2;
681 InitialLength += 2;
682 break;
683 }
684
685 case TopAbs_WIRE :
686 {
687 Standard_Integer ii = InitialLength+1;
688 Handle(BRepFill_ShapeLaw) Section =
689 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
690 InitialLength += Section->NbLaw()+1;
691
692 for (; (ii<=InitialLength) && (!result); ii++) {
693 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
694 }
695 break;
696 }
697
698 case TopAbs_FACE :
699 case TopAbs_SHELL :
700 case TopAbs_COMPOUND :
701 {
702 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
703 result = FindVertex(it.Value(), V, InitialLength);
704 break;
705 }
706
707 case TopAbs_SOLID :
708 case TopAbs_COMPSOLID :
709 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
710 break;
7fd59977 711 default:
712 break;
7fd59977 713 }
714
715 return result;
716}
717
718//=======================================================================
719//function : DefineRealSegmax
720//purpose : Defines the real number of segments
721// required in the case of bspline spine
722//=======================================================================
723
724void BRepFill_Pipe::DefineRealSegmax()
725{
726 Standard_Integer RealSegmax = 0;
727
728 TopoDS_Iterator iter(mySpine);
729 for (; iter.More(); iter.Next())
730 {
731 TopoDS_Edge E = TopoDS::Edge(iter.Value());
732 Standard_Real first, last;
733 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
734 if (C.IsNull())
735 continue;
736 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
737 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
738 {
739 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
740 C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
741 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
742 C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve();
743 }
744 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
745 {
746 const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C);
747 Standard_Integer NbKnots = BC->NbKnots();
748 Standard_Integer RealNbKnots = NbKnots;
749 if (first > BC->FirstParameter())
750 {
751 Standard_Integer I1, I2;
752 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
753 RealNbKnots -= I1-1;
754 }
755 if (last < BC->LastParameter())
756 {
757 Standard_Integer I1, I2;
758 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
759 RealNbKnots -= NbKnots-I2;
760 }
761 RealSegmax += RealNbKnots-1;
762 }
763 }
764
765 if (mySegmax < RealSegmax)
766 mySegmax = RealSegmax;
767}