0023024: Update headers of OCCT files
[occt.git] / src / BRepFill / BRepFill_Pipe.cxx
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
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>
57 static Standard_Boolean Affich = 0;
58 #endif
59
60 //=======================================================================
61 //function : BRepFill_Pipe
62 //purpose  : 
63 //=======================================================================
64
65 BRepFill_Pipe::BRepFill_Pipe()
66 {
67   myDegmax = 10;
68   mySegmax = 100;
69 }
70
71
72 //=======================================================================
73 //function : BRepFill_Pipe
74 //purpose  : 
75 //=======================================================================
76
77 BRepFill_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
93 void 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) {
117     return; // Degenerated case
118   }
119   myLoc->TransformInG0Law(); // Set into continuity
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  
130   // Construct First && Last Shape
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);
153 //    try { // Not good, but there are no other means to test SetValues
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
186 const TopoDS_Shape& BRepFill_Pipe::Spine() const 
187 {
188   return mySpine;
189 }
190
191 //=======================================================================
192 //function : Profile
193 //purpose  : 
194 //=======================================================================
195
196 const TopoDS_Shape& BRepFill_Pipe::Profile() const 
197 {
198   return myProfile;
199 }
200
201 //=======================================================================
202 //function : Shape
203 //purpose  : 
204 //=======================================================================
205
206 const TopoDS_Shape& BRepFill_Pipe::Shape() const 
207 {
208   return myShape;
209 }
210
211
212 //=======================================================================
213 //function : FirstShape
214 //purpose  : 
215 //=======================================================================
216
217 const TopoDS_Shape& BRepFill_Pipe::FirstShape() const 
218 {
219   return myFirst;
220 }
221
222
223 //=======================================================================
224 //function : LastShape
225 //purpose  : 
226 //=======================================================================
227
228 const TopoDS_Shape& BRepFill_Pipe::LastShape() const 
229 {
230   return myLast;
231 }
232
233
234 //=======================================================================
235 //function : Face
236 //purpose  : 
237 //=======================================================================
238
239 TopoDS_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 //=======================================================================
277 TopoDS_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
318 TopoDS_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
349 //purpose  : Construct a wire by sweeping of a point
350 //=======================================================================
351
352 TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
353 {
354  // Postioning 
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
363  // Sweeping
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
376 TopoDS_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     }
461 #ifndef DEB
462   default:
463     break;
464 #endif    
465   }
466
467   if (explode) {
468     // add the subshapes
469     TopoDS_Iterator itFirst, itLast;
470     TopoDS_Shape first, last;
471     if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
472     if (!TheLast.IsNull()) itLast.Initialize(TheLast);
473
474     for (TopoDS_Iterator it(S); it.More(); it.Next()) {
475       if (!TheFirst.IsNull()) first = itFirst.Value();
476       if (!TheLast.IsNull())  last = itLast.Value();
477       if (TheS.ShapeType() == TopAbs_FACE ) 
478         MakeShape(it.Value(), first, last);
479       else
480         B.Add(result,MakeShape(it.Value(), first, last));
481
482       if (!TheFirst.IsNull()) itFirst.Next();
483       if (!TheLast.IsNull())  itLast.Next();
484     }
485   }
486   
487   else {
488     if (TheS.ShapeType() == TopAbs_VERTEX ) {
489      Handle(BRepFill_ShapeLaw) Section = 
490         new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
491       BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
492       MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
493       result = MkSw.Shape();
494     }
495
496     if (TheS.ShapeType() == TopAbs_WIRE ) {
497       Handle(BRepFill_ShapeLaw) Section = 
498         new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS));
499       BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
500       MkSw.SetBounds(TopoDS::Wire(TheFirst), 
501                      TopoDS::Wire(TheLast));
502       MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
503       result = MkSw.Shape();
504
505       // Labeling of elements
506       if (mySections.IsNull()) {
507         myFaces    = MkSw.SubShape();
508         mySections = MkSw.Sections();
509         myEdges    = MkSw.InterFaces();
510       }
511       else {
512         Handle(TopTools_HArray2OfShape) Aux, Somme;
513         Standard_Integer length;
514         Standard_Integer ii, jj, kk;
515
516         Aux = MkSw.SubShape();
517         length = Aux->ColLength() + myFaces->ColLength(); 
518         Somme = new (TopTools_HArray2OfShape) (1, length, 1, 
519                                                Aux->RowLength());
520         for (jj=1; jj<=myFaces->RowLength(); jj++) {
521           for (ii=1; ii<=myFaces->ColLength(); ii++)
522             Somme->SetValue(ii, jj, myFaces->Value(ii, jj));
523  
524           for (kk=1, ii=myFaces->ColLength()+1; 
525                kk <=Aux->ColLength(); kk++, ii++)
526             Somme->SetValue(ii, jj, Aux->Value(kk, jj));
527         }
528         myFaces = Somme;    
529        
530
531         Aux = MkSw.Sections();
532         length = Aux->ColLength() + mySections->ColLength(); 
533         Somme = new (TopTools_HArray2OfShape) (1, length, 1, 
534                                                Aux->RowLength());
535         for (jj=1; jj<=mySections->RowLength(); jj++) {
536           for (ii=1; ii<=mySections->ColLength(); ii++)
537             Somme->SetValue(ii, jj, mySections->Value(ii, jj));
538  
539           for (kk=1, ii=mySections->ColLength()+1; 
540                kk <=Aux->ColLength(); kk++, ii++)
541             Somme->SetValue(ii, jj, Aux->Value(kk, jj));   
542         }
543         mySections = Somme;
544
545         Aux = MkSw.InterFaces();
546         length = Aux->ColLength() + myEdges->ColLength(); 
547         Somme = new (TopTools_HArray2OfShape) (1, length, 1, 
548                                                Aux->RowLength());
549         for (jj=1; jj<=myEdges->RowLength(); jj++) {
550           for (ii=1; ii<=myEdges->ColLength(); ii++)
551             Somme->SetValue(ii, jj, myEdges->Value(ii, jj));
552  
553           for (kk=1, ii=myEdges->ColLength()+1; 
554                kk <=Aux->ColLength(); kk++, ii++)
555             Somme->SetValue(ii, jj, Aux->Value(kk, jj));   
556         }
557         myEdges = Somme;               
558       }
559     }
560   }
561       
562   if ( TheS.ShapeType() == TopAbs_FACE ) {
563     Standard_Integer ii, jj;
564     TopoDS_Face F;
565     for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
566       for (jj=1; jj<=myFaces->RowLength(); jj++) {
567         F = TopoDS::Face(myFaces->Value(ii, jj));
568         if (!F.IsNull()) B.Add(result, F);
569       }
570     }
571
572     if ( !mySpine.Closed()) {
573       // if Spine is not closed 
574       // add the last face of the solid
575       B.Add(result, TopoDS::Face(TheLast));
576     }
577
578     TopoDS_Solid solid;
579     BRep_Builder BS;
580     BS.MakeSolid(solid);
581
582     result.Closed(Standard_True);
583     BS.Add(solid,TopoDS::Shell(result));
584
585     BRepClass3d_SolidClassifier SC(solid);
586     SC.PerformInfinitePoint(Precision::Confusion());
587     if ( SC.State() == TopAbs_IN) {
588       BS.MakeSolid(solid);
589       TopoDS_Shape aLocalShape = result.Reversed();
590       BS.Add(solid,TopoDS::Shell(aLocalShape));
591 //      BS.Add(solid,TopoDS::Shell(result.Reversed()));
592     }
593     return solid;
594   }
595   else {
596     return result;
597   }
598   return result;
599 }
600
601 //============================================================================
602 //function : FindEdge
603 //purpose  : Find the number of edge corresponding to the edge of the profile.
604 //============================================================================
605
606 Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
607                                          const TopoDS_Edge& E,
608                                          Standard_Integer& InitialLength) const
609 {
610   Standard_Integer result = 0;
611
612   switch (S.ShapeType()) {
613           
614   case TopAbs_EDGE :
615     {
616       InitialLength++;
617       if (S.IsSame(E)) result = InitialLength;
618       break;
619     }
620           
621   case TopAbs_WIRE :
622     {
623       Standard_Integer ii = InitialLength+1;
624       Handle(BRepFill_ShapeLaw) Section = 
625         new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
626       InitialLength += Section->NbLaw();
627      
628       for (; (ii<=InitialLength) && (!result); ii++) {
629         if (E.IsSame(Section->Edge(ii)) ) result = ii;
630       }
631       break;
632     }
633
634   case TopAbs_FACE :
635   case TopAbs_SHELL :
636   case TopAbs_COMPOUND :
637     {
638      for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
639        result = FindEdge(it.Value(), E, InitialLength );
640      break;
641     }
642
643   case TopAbs_SOLID :
644   case TopAbs_COMPSOLID :
645     Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
646     break;
647 #ifndef DEB
648   default:
649     break;
650 #endif
651   }
652
653   return result; 
654 }
655
656 //=======================================================================
657 //function : FindVertex
658 //purpose  : Find the number of edge corresponding to an edge of the profile.
659 //=======================================================================
660
661 Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
662                                            const TopoDS_Vertex& V,
663                                            Standard_Integer& InitialLength) const
664 {
665   Standard_Integer result = 0;
666
667   switch (S.ShapeType()) {
668   case TopAbs_VERTEX :
669     {
670       InitialLength++;
671       if (S.IsSame(V)) result = InitialLength;
672       break;
673     }
674           
675   case TopAbs_EDGE :
676     {
677       TopoDS_Vertex VF, VL;
678       TopExp::Vertices(TopoDS::Edge(S), VF, VL);
679       if (S.Orientation() == TopAbs_REVERSED) {
680         TopoDS_Vertex aux;
681         aux = VF; VF = VL; VL = aux;
682       }
683       if (VF.IsSame(V)) result = InitialLength+1;
684       else if (VL.IsSame(V)) result = InitialLength+2;
685       InitialLength += 2;
686       break;
687     }
688           
689   case TopAbs_WIRE :
690     {
691       Standard_Integer ii = InitialLength+1;
692       Handle(BRepFill_ShapeLaw) Section = 
693         new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
694       InitialLength += Section->NbLaw()+1;
695      
696       for (; (ii<=InitialLength) && (!result); ii++) {
697         if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
698       }
699       break;
700     }
701
702   case TopAbs_FACE :
703   case TopAbs_SHELL :
704   case TopAbs_COMPOUND :
705     {
706      for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
707        result = FindVertex(it.Value(), V, InitialLength);
708      break;
709     }
710
711   case TopAbs_SOLID :
712   case TopAbs_COMPSOLID :
713     Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
714     break;
715 #ifndef DEB
716   default:
717     break;
718 #endif
719   }
720
721   return result; 
722 }
723
724 //=======================================================================
725 //function : DefineRealSegmax
726 //purpose  : Defines the real number of segments
727 //           required in the case of bspline spine
728 //=======================================================================
729
730 void BRepFill_Pipe::DefineRealSegmax()
731 {
732   Standard_Integer RealSegmax = 0;
733
734   TopoDS_Iterator iter(mySpine);
735   for (; iter.More(); iter.Next())
736     {
737       TopoDS_Edge E = TopoDS::Edge(iter.Value());
738       Standard_Real first, last;
739       Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
740       if (C.IsNull())
741         continue;
742       while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
743              C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
744         {
745           if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
746             C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
747           if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
748             C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve();
749         }
750       if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
751         {
752           const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C);
753           Standard_Integer NbKnots = BC->NbKnots();
754           Standard_Integer RealNbKnots = NbKnots;
755           if (first > BC->FirstParameter())
756             {
757               Standard_Integer I1, I2;
758               BC->LocateU( first, Precision::PConfusion(), I1, I2 );
759               RealNbKnots -= I1-1;
760             }
761           if (last < BC->LastParameter())
762             {
763               Standard_Integer I1, I2;
764               BC->LocateU( last, Precision::PConfusion(), I1, I2 );
765               RealNbKnots -= NbKnots-I2;
766             }
767           RealSegmax += RealNbKnots-1;
768         }
769     }
770
771   if (mySegmax < RealSegmax)
772     mySegmax = RealSegmax;
773 }