1 // File: BRepFill_Pipe.cxx
2 // Created: Tue Jun 7 16:31:15 1994
3 // Author: Bruno DUMORTIER
6 #include <BRepFill_Pipe.ixx>
8 #include <Standard_ErrorHandler.hxx>
10 #include <BRep_Tool.hxx>
11 #include <BRep_Builder.hxx>
12 #include <BRepClass3d_SolidClassifier.hxx>
13 #include <BRepLib_MakeVertex.hxx>
15 #include <GeomFill_CorrectedFrenet.hxx>
16 #include <GeomFill_CurveAndTrihedron.hxx>
18 #include <BRepFill_SectionPlacement.hxx>
19 #include <BRepFill_ShapeLaw.hxx>
20 #include <BRepFill_Edge3DLaw.hxx>
21 #include <BRepFill_Sweep.hxx>
23 #include <GeomAbs_Shape.hxx>
25 #include <TopAbs_ShapeEnum.hxx>
27 #include <TopoDS_Shell.hxx>
28 #include <TopoDS_Solid.hxx>
29 #include <TopoDS_Compound.hxx>
30 #include <TopoDS_Iterator.hxx>
32 #include <Precision.hxx>
33 #include <Standard_NotImplemented.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <Geom_OffsetCurve.hxx>
37 #include <Geom_BSplineCurve.hxx>
41 static Standard_Boolean Affich = 0;
44 //=======================================================================
45 //function : BRepFill_Pipe
47 //=======================================================================
49 BRepFill_Pipe::BRepFill_Pipe()
56 //=======================================================================
57 //function : BRepFill_Pipe
59 //=======================================================================
61 BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
62 const TopoDS_Shape& Profile,
63 const Standard_Boolean KPart)
67 Perform(Spine, Profile, KPart);
72 //=======================================================================
75 //=======================================================================
77 void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
78 const TopoDS_Shape& Profile,
79 const Standard_Boolean KPart)
91 BRepTools_WireExplorer wexp;
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
103 myLoc->TransformInG0Law(); // Mise en continuite
105 BRepFill_SectionPlacement Place(myLoc, Profile);
106 myTrsf = Place.Transformation();
108 TopLoc_Location Loc2(myTrsf), Loc1;
109 Loc1 = Profile.Location();
112 TheProf.Location(Loc2.Multiplied(Loc1));
114 // Construit les Shape First && Last
115 Handle(GeomFill_LocationLaw) law;
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(),
128 fila.Multiply(myTrsf);
129 TopLoc_Location LocFirst(fila);
131 if ( ! LocFirst.IsIdentity()) {
132 myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
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(),
142 fila.Multiply(myTrsf);
143 TopLoc_Location LocLast(fila);
144 if (! myLoc->IsClosed() || LocFirst != LocLast) {
146 if ( ! LocLast.IsIdentity()) {
147 myLast.Location(LocLast.Multiplied(myProfile.Location()) );
155 DBRep::Set("theprof", TheProf);
156 DBRep::Set("thefirst", myFirst);
157 DBRep::Set("thelast" , myLast);
161 myShape = MakeShape(TheProf, myFirst, myLast);
165 //=======================================================================
168 //=======================================================================
170 const TopoDS_Shape& BRepFill_Pipe::Spine() const
175 //=======================================================================
178 //=======================================================================
180 const TopoDS_Shape& BRepFill_Pipe::Profile() const
185 //=======================================================================
188 //=======================================================================
190 const TopoDS_Shape& BRepFill_Pipe::Shape() const
196 //=======================================================================
197 //function : FirstShape
199 //=======================================================================
201 const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
207 //=======================================================================
208 //function : LastShape
210 //=======================================================================
212 const TopoDS_Shape& BRepFill_Pipe::LastShape() const
218 //=======================================================================
221 //=======================================================================
223 TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
224 const TopoDS_Edge& EProfile)
228 if ( BRep_Tool::Degenerated(EProfile))
231 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
233 // *************************************************
234 // Search if EProfile is an edge of myProfile
235 // *************************************************
236 iprof = FindEdge(myProfile, EProfile, count);
238 if (!iprof) Standard_DomainError::Raise(
239 "BRepFill_Pipe::Face : Edge not in the Profile");
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;
249 if (!ispin) Standard_DomainError::Raise(
250 "BRepFill_Pipe::Edge : Edge not in the Spine");
252 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
257 //=======================================================================
260 //=======================================================================
261 TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
262 const TopoDS_Vertex& VProfile)
264 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;;
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");
274 // *************************************************
275 // Search if ESpine is an edge of mySpine and find
276 // the index of the corresponding Filler
277 // *************************************************
279 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
280 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
282 if (!ispin) Standard_DomainError::Raise(
283 "BRepFill_Pipe::Edge : Edge not in the Spine");
286 // *************************************************
287 // Generate the corresponding Shape
288 // *************************************************
290 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
297 //=======================================================================
300 //=======================================================================
302 TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
304 TopoDS_Iterator it, itv;
306 Standard_Integer ii, ispin = 0;
308 TopoDS_Shape curSect = myProfile;
310 // *************************************************
311 // Search if ESpine is an edge of mySpine and find
312 // the index of the corresponding Filler
313 // *************************************************
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;
319 if (!ispin) Standard_DomainError::Raise(
320 "BRepFill_Pipe::Section : Vertex not in the Spine");
323 TopoDS_Compound Comp;
324 B.MakeCompound(Comp);
325 for (ii=1; ii<=mySections->ColLength(); ii++)
326 B.Add(Comp, mySections->Value(ii, ispin));
331 //=======================================================================
332 //function : PipeLine
333 //purpose : Construit un wire par balayage d'un point
334 //=======================================================================
336 TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
343 BRepLib_MakeVertex MkV(P);
344 Handle(BRepFill_ShapeLaw) Section =
345 new (BRepFill_ShapeLaw) (MkV.Vertex());
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());
355 //=======================================================================
356 //function : MakeShape
358 //=======================================================================
360 TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
361 const TopoDS_Shape& FirstShape,
362 const TopoDS_Shape& LastShape)
366 Standard_Boolean explode = Standard_False;
367 TopoDS_Shape TheS, TheFirst, TheLast;
368 Standard_Integer InitialLength = 0;
370 TheFirst = FirstShape;
372 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
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
378 // explode is True in the second case
380 // create the result empty
382 switch (S.ShapeType()) {
386 B.MakeWire(TopoDS::Wire(result));
393 B.MakeShell(TopoDS::Shell(result));
396 W.Closed(S.Closed());
398 if (!FirstShape.IsNull()) {
400 B.Add(W, FirstShape);
401 W.Closed(FirstShape.Closed());
404 if (!LastShape.IsNull()) {
407 W.Closed(LastShape.Closed());
414 B.MakeShell(TopoDS::Shell(result));
419 B.MakeShell(TopoDS::Shell(result));
420 explode = Standard_True;
421 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
422 B.Add(result, TheFirst.Reversed());
429 B.MakeCompSolid(TopoDS::CompSolid(result));
430 explode = Standard_True;
435 case TopAbs_COMPSOLID :
436 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
439 case TopAbs_COMPOUND :
441 B.MakeCompound(TopoDS::Compound(result));
442 explode = Standard_True;
453 TopoDS_Iterator itFirst, itLast;
454 TopoDS_Shape first, last;
455 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
456 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
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);
464 B.Add(result,MakeShape(it.Value(), first, last));
466 if (!TheFirst.IsNull()) itFirst.Next();
467 if (!TheLast.IsNull()) itLast.Next();
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();
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();
489 // Reperage des elements
490 if (mySections.IsNull()) {
491 myFaces = MkSw.SubShape();
492 mySections = MkSw.Sections();
493 myEdges = MkSw.InterFaces();
496 Handle(TopTools_HArray2OfShape) Aux, Somme;
497 Standard_Integer length;
498 Standard_Integer ii, jj, kk;
500 Aux = MkSw.SubShape();
501 length = Aux->ColLength() + myFaces->ColLength();
502 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
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));
508 for (kk=1, ii=myFaces->ColLength()+1;
509 kk <=Aux->ColLength(); kk++, ii++)
510 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
515 Aux = MkSw.Sections();
516 length = Aux->ColLength() + mySections->ColLength();
517 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
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));
523 for (kk=1, ii=mySections->ColLength()+1;
524 kk <=Aux->ColLength(); kk++, ii++)
525 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
529 Aux = MkSw.InterFaces();
530 length = Aux->ColLength() + myEdges->ColLength();
531 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
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));
537 for (kk=1, ii=myEdges->ColLength()+1;
538 kk <=Aux->ColLength(); kk++, ii++)
539 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
546 if ( TheS.ShapeType() == TopAbs_FACE ) {
547 Standard_Integer ii, jj;
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);
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));
566 result.Closed(Standard_True);
567 BS.Add(solid,TopoDS::Shell(result));
569 BRepClass3d_SolidClassifier SC(solid);
570 SC.PerformInfinitePoint(Precision::Confusion());
571 if ( SC.State() == TopAbs_IN) {
573 TopoDS_Shape aLocalShape = result.Reversed();
574 BS.Add(solid,TopoDS::Shell(aLocalShape));
575 // BS.Add(solid,TopoDS::Shell(result.Reversed()));
585 //=======================================================================
586 //function : FindEdge
587 //purpose : Recherche le numero de bande correspondant a une edge du
589 //=======================================================================
591 Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
592 const TopoDS_Edge& E,
593 Standard_Integer& InitialLength) const
595 Standard_Integer result = 0;
597 switch (S.ShapeType()) {
602 if (S.IsSame(E)) result = InitialLength;
608 Standard_Integer ii = InitialLength+1;
609 Handle(BRepFill_ShapeLaw) Section =
610 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
611 InitialLength += Section->NbLaw();
613 for (; (ii<=InitialLength) && (!result); ii++) {
614 if (E.IsSame(Section->Edge(ii)) ) result = ii;
621 case TopAbs_COMPOUND :
623 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
624 result = FindEdge(it.Value(), E, InitialLength );
629 case TopAbs_COMPSOLID :
630 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
641 //=======================================================================
642 //function : FindVertex
643 //purpose : Recherche le numero de bande correspondant a une edge du
645 //=======================================================================
647 Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
648 const TopoDS_Vertex& V,
649 Standard_Integer& InitialLength) const
651 Standard_Integer result = 0;
653 switch (S.ShapeType()) {
657 if (S.IsSame(V)) result = InitialLength;
663 TopoDS_Vertex VF, VL;
664 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
665 if (S.Orientation() == TopAbs_REVERSED) {
667 aux = VF; VF = VL; VL = aux;
669 if (VF.IsSame(V)) result = InitialLength+1;
670 else if (VL.IsSame(V)) result = InitialLength+2;
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;
682 for (; (ii<=InitialLength) && (!result); ii++) {
683 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
690 case TopAbs_COMPOUND :
692 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
693 result = FindVertex(it.Value(), V, InitialLength);
698 case TopAbs_COMPSOLID :
699 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
710 //=======================================================================
711 //function : DefineRealSegmax
712 //purpose : Defines the real number of segments
713 // required in the case of bspline spine
714 //=======================================================================
716 void BRepFill_Pipe::DefineRealSegmax()
718 Standard_Integer RealSegmax = 0;
720 TopoDS_Iterator iter(mySpine);
721 for (; iter.More(); iter.Next())
723 TopoDS_Edge E = TopoDS::Edge(iter.Value());
724 Standard_Real first, last;
725 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
728 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
729 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
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();
736 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
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())
743 Standard_Integer I1, I2;
744 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
747 if (last < BC->LastParameter())
749 Standard_Integer I1, I2;
750 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
751 RealNbKnots -= NbKnots-I2;
753 RealSegmax += RealNbKnots-1;
757 if (mySegmax < RealSegmax)
758 mySegmax = RealSegmax;