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