0022627: Change OCCT memory management defaults
[occt.git] / src / BRepFill / BRepFill_Pipe.cxx
CommitLineData
7fd59977 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) {
0d969553 101 return; // Degenerated case
7fd59977 102 }
0d969553 103 myLoc->TransformInG0Law(); // Set into continuity
7fd59977 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
0d969553 114 // Construct First && Last Shape
7fd59977 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);
0d969553 137// try { // Not good, but there are no other means to test SetValues
7fd59977 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
0d969553 333//purpose : Construct a wire by sweeping of a point
7fd59977 334//=======================================================================
335
336TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
337{
0d969553 338 // Postioning
7fd59977 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
0d969553 347 // Sweeping
7fd59977 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
0d969553 489 // Labeling of elements
7fd59977 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
0d969553 585//============================================================================
7fd59977 586//function : FindEdge
0d969553
Y
587//purpose : Find the number of edge corresponding to the edge of the profile.
588//============================================================================
7fd59977 589
590Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
591 const TopoDS_Edge& E,
592 Standard_Integer& InitialLength) const
593{
594 Standard_Integer result = 0;
595
596 switch (S.ShapeType()) {
597
598 case TopAbs_EDGE :
599 {
600 InitialLength++;
601 if (S.IsSame(E)) result = InitialLength;
602 break;
603 }
604
605 case TopAbs_WIRE :
606 {
607 Standard_Integer ii = InitialLength+1;
608 Handle(BRepFill_ShapeLaw) Section =
609 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
610 InitialLength += Section->NbLaw();
611
612 for (; (ii<=InitialLength) && (!result); ii++) {
613 if (E.IsSame(Section->Edge(ii)) ) result = ii;
614 }
615 break;
616 }
617
618 case TopAbs_FACE :
619 case TopAbs_SHELL :
620 case TopAbs_COMPOUND :
621 {
622 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
623 result = FindEdge(it.Value(), E, InitialLength );
624 break;
625 }
626
627 case TopAbs_SOLID :
628 case TopAbs_COMPSOLID :
629 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
630 break;
631#ifndef DEB
632 default:
633 break;
634#endif
635 }
636
637 return result;
638}
639
640//=======================================================================
641//function : FindVertex
0d969553 642//purpose : Find the number of edge corresponding to an edge of the profile.
7fd59977 643//=======================================================================
644
645Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
646 const TopoDS_Vertex& V,
647 Standard_Integer& InitialLength) const
648{
649 Standard_Integer result = 0;
650
651 switch (S.ShapeType()) {
652 case TopAbs_VERTEX :
653 {
654 InitialLength++;
655 if (S.IsSame(V)) result = InitialLength;
656 break;
657 }
658
659 case TopAbs_EDGE :
660 {
661 TopoDS_Vertex VF, VL;
662 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
663 if (S.Orientation() == TopAbs_REVERSED) {
664 TopoDS_Vertex aux;
665 aux = VF; VF = VL; VL = aux;
666 }
667 if (VF.IsSame(V)) result = InitialLength+1;
668 else if (VL.IsSame(V)) result = InitialLength+2;
669 InitialLength += 2;
670 break;
671 }
672
673 case TopAbs_WIRE :
674 {
675 Standard_Integer ii = InitialLength+1;
676 Handle(BRepFill_ShapeLaw) Section =
677 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
678 InitialLength += Section->NbLaw()+1;
679
680 for (; (ii<=InitialLength) && (!result); ii++) {
681 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
682 }
683 break;
684 }
685
686 case TopAbs_FACE :
687 case TopAbs_SHELL :
688 case TopAbs_COMPOUND :
689 {
690 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
691 result = FindVertex(it.Value(), V, InitialLength);
692 break;
693 }
694
695 case TopAbs_SOLID :
696 case TopAbs_COMPSOLID :
697 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
698 break;
699#ifndef DEB
700 default:
701 break;
702#endif
703 }
704
705 return result;
706}
707
708//=======================================================================
709//function : DefineRealSegmax
710//purpose : Defines the real number of segments
711// required in the case of bspline spine
712//=======================================================================
713
714void BRepFill_Pipe::DefineRealSegmax()
715{
716 Standard_Integer RealSegmax = 0;
717
718 TopoDS_Iterator iter(mySpine);
719 for (; iter.More(); iter.Next())
720 {
721 TopoDS_Edge E = TopoDS::Edge(iter.Value());
722 Standard_Real first, last;
723 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
724 if (C.IsNull())
725 continue;
726 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
727 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
728 {
729 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
730 C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
731 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
732 C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve();
733 }
734 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
735 {
736 const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C);
737 Standard_Integer NbKnots = BC->NbKnots();
738 Standard_Integer RealNbKnots = NbKnots;
739 if (first > BC->FirstParameter())
740 {
741 Standard_Integer I1, I2;
742 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
743 RealNbKnots -= I1-1;
744 }
745 if (last < BC->LastParameter())
746 {
747 Standard_Integer I1, I2;
748 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
749 RealNbKnots -= NbKnots-I2;
750 }
751 RealSegmax += RealNbKnots-1;
752 }
753 }
754
755 if (mySegmax < RealSegmax)
756 mySegmax = RealSegmax;
757}