1 // Created on: 1994-06-07
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_CurveOnSurface.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepBuilderAPI_Copy.hxx>
22 #include <BRepBuilderAPI_Transform.hxx>
23 #include <BRepClass3d_SolidClassifier.hxx>
24 #include <BRepFill_Edge3DLaw.hxx>
25 #include <BRepFill_LocationLaw.hxx>
26 #include <BRepFill_Pipe.hxx>
27 #include <BRepFill_SectionPlacement.hxx>
28 #include <BRepFill_ShapeLaw.hxx>
29 #include <BRepFill_Sweep.hxx>
30 #include <BRepLib.hxx>
31 #include <BRepLib_MakeVertex.hxx>
32 #include <BRepTools_Substitution.hxx>
33 #include <Geom2dAdaptor_HCurve.hxx>
34 #include <Geom_BSplineCurve.hxx>
35 #include <Geom_OffsetCurve.hxx>
36 #include <Geom_TrimmedCurve.hxx>
37 #include <GeomAbs_Shape.hxx>
38 #include <GeomAdaptor_HSurface.hxx>
39 #include <GeomFill_CorrectedFrenet.hxx>
40 #include <GeomFill_CurveAndTrihedron.hxx>
41 #include <GeomFill_DiscreteTrihedron.hxx>
42 #include <GeomFill_Frenet.hxx>
44 #include <Precision.hxx>
45 #include <ShapeUpgrade_RemoveLocations.hxx>
46 #include <Standard_DomainError.hxx>
47 #include <Standard_ErrorHandler.hxx>
48 #include <Standard_NotImplemented.hxx>
49 #include <StdFail_NotDone.hxx>
50 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
51 #include <TColStd_DataMapOfIntegerInteger.hxx>
52 #include <TopAbs_ShapeEnum.hxx>
55 #include <TopoDS_Compound.hxx>
56 #include <TopoDS_Edge.hxx>
57 #include <TopoDS_Face.hxx>
58 #include <TopoDS_Iterator.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Shell.hxx>
61 #include <TopoDS_Solid.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <TopoDS_Wire.hxx>
64 #include <TopTools_DataMapOfShapeInteger.hxx>
65 #include <TopTools_DataMapOfIntegerShape.hxx>
66 #include <TopTools_ListIteratorOfListOfShape.hxx>
67 #include <TopTools_SequenceOfShape.hxx>
71 static Standard_Boolean Affich = 0;
74 // ---------------------------------------------------------------------------------
75 // static function: UpdateMap
77 // ---------------------------------------------------------------------------------
78 static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
79 const TopoDS_Shape& theValue,
80 TopTools_DataMapOfShapeListOfShape& theMap)
82 if(!theMap.IsBound(theKey))
84 TopTools_ListOfShape thelist;
85 theMap.Bind(theKey, thelist);
87 TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
88 TopTools_ListIteratorOfListOfShape anIt(aList);
89 Standard_Boolean found = Standard_False;
91 for(; anIt.More(); anIt.Next())
93 if(theValue.IsSame(anIt.Value()))
95 found = Standard_True;
101 aList.Append(theValue);
106 static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace,
109 Standard_Real fpar, lpar;
110 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar);
111 if (aPCurve.IsNull())
114 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
118 Handle(Geom2dAdaptor_HCurve) GAHC2d = new Geom2dAdaptor_HCurve(aPCurve, fpar, lpar);
119 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
120 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aSurf);
121 Adaptor3d_CurveOnSurface ConS(GAHC2d, GAHS);
123 Standard_Real Tol = BRep_Tool::Tolerance(anEdge);
124 Standard_Real InitTol = Tol;
125 Standard_Real TolTol = Tol*Tol;
126 const Standard_Integer NCONTROL = 22;
127 Standard_Real delta = (lpar - fpar)/NCONTROL;
128 for (Standard_Integer i = 0; i <= NCONTROL; i++)
130 Standard_Real par = fpar + i*delta;
131 gp_Pnt pnt = aCurve->Value(par);
132 gp_Pnt prj = ConS.Value(par);
133 Standard_Real sqdist = pnt.SquareDistance(prj);
137 Tol = 1.00005 * Sqrt(TolTol);
141 BB.UpdateEdge(anEdge, Tol);
142 TopoDS_Iterator itv(anEdge);
143 for (; itv.More(); itv.Next())
145 TopoDS_Vertex aVertex = TopoDS::Vertex(itv.Value());
146 BB.UpdateVertex(aVertex, Tol);
151 //=======================================================================
152 //function : BRepFill_Pipe
154 //=======================================================================
156 BRepFill_Pipe::BRepFill_Pipe()
160 myContinuity = GeomAbs_C2;
161 myMode = GeomFill_IsCorrectedFrenet;
162 myForceApproxC1 = Standard_False;
164 myCurIndexOfSectionEdge = 1;
168 //=======================================================================
169 //function : BRepFill_Pipe
171 //=======================================================================
173 BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
174 const TopoDS_Shape& Profile,
175 const GeomFill_Trihedron aMode,
176 const Standard_Boolean ForceApproxC1,
177 const Standard_Boolean KPart)
183 myMode = GeomFill_IsCorrectedFrenet;
184 if (aMode == GeomFill_IsFrenet ||
185 aMode == GeomFill_IsCorrectedFrenet ||
186 aMode == GeomFill_IsDiscreteTrihedron)
189 myContinuity = GeomAbs_C2;
190 if (myMode == GeomFill_IsDiscreteTrihedron)
191 myContinuity = GeomAbs_C0;
193 myForceApproxC1 = ForceApproxC1;
195 myCurIndexOfSectionEdge = 1;
197 Perform(Spine, Profile, KPart);
201 //=======================================================================
204 //=======================================================================
206 void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
207 const TopoDS_Shape& Profile,
208 const Standard_Boolean /*KPart*/)
211 mySections.Nullify();
220 BRepTools_WireExplorer wexp;
221 TopoDS_Shape TheProf;
223 Handle(GeomFill_TrihedronLaw) TLaw;
226 case GeomFill_IsFrenet:
227 TLaw = new GeomFill_Frenet();
229 case GeomFill_IsCorrectedFrenet:
230 TLaw = new GeomFill_CorrectedFrenet();
232 case GeomFill_IsDiscreteTrihedron:
233 TLaw = new GeomFill_DiscreteTrihedron();
238 Handle(GeomFill_CurveAndTrihedron) Loc =
239 new (GeomFill_CurveAndTrihedron) (TLaw);
240 myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
241 if (myLoc->NbLaw() == 0) {
242 return; // Degenerated case
244 myLoc->TransformInG0Law(); // Set into continuity
246 BRepFill_SectionPlacement Place(myLoc, Profile);
247 myTrsf = Place.Transformation();
249 TopLoc_Location Loc2(myTrsf), Loc1;
250 Loc1 = Profile.Location();
253 TheProf.Location(Loc2.Multiplied(Loc1));
255 // Construct First && Last Shape
256 Handle(GeomFill_LocationLaw) law;
261 Standard_Real first, last;
262 myLoc->Law(1)->GetDomain(first, last);
263 myLoc->Law(1)->D0(first, M, V);
264 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
265 M(2,1), M(2,2), M(2,3), V.Y(),
266 M(3,1), M(3,2), M(3,3), V.Z());
268 fila.Multiply(myTrsf);
269 TopLoc_Location LocFirst(fila);
271 if ( ! LocFirst.IsIdentity()) {
272 //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
273 myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
276 ShapeUpgrade_RemoveLocations RemLoc;
277 RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
278 RemLoc.Remove(myFirst);
279 myFirst = RemLoc.GetResult();
281 myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
282 myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
283 // try { // Not good, but there are no other means to test SetValues
284 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
285 M(2,1), M(2,2), M(2,3), V.Y(),
286 M(3,1), M(3,2), M(3,3), V.Z());
287 fila.Multiply(myTrsf);
288 TopLoc_Location LocLast(fila);
289 if (! myLoc->IsClosed() || LocFirst != LocLast) {
291 if ( ! LocLast.IsIdentity()) {
292 //myLast.Location(LocLast.Multiplied(myProfile.Location()) );
293 myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
300 RemLoc.Remove(myLast);
301 myLast = RemLoc.GetResult();
305 DBRep::Set("theprof", TheProf);
306 DBRep::Set("thefirst", myFirst);
307 DBRep::Set("thelast" , myLast);
311 myShape = MakeShape(TheProf, myProfile, myFirst, myLast);
315 //=======================================================================
318 //=======================================================================
320 const TopoDS_Shape& BRepFill_Pipe::Spine() const
325 //=======================================================================
328 //=======================================================================
330 const TopoDS_Shape& BRepFill_Pipe::Profile() const
335 //=======================================================================
338 //=======================================================================
340 const TopoDS_Shape& BRepFill_Pipe::Shape() const
345 //=======================================================================
346 //function : ErrorOnSurface
348 //=======================================================================
350 Standard_Real BRepFill_Pipe::ErrorOnSurface() const
352 return myErrorOnSurf;
356 //=======================================================================
357 //function : FirstShape
359 //=======================================================================
361 const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
367 //=======================================================================
368 //function : LastShape
370 //=======================================================================
372 const TopoDS_Shape& BRepFill_Pipe::LastShape() const
377 //=======================================================================
378 //function : Generated
380 //=======================================================================
381 void BRepFill_Pipe::Generated(const TopoDS_Shape& theShape,
382 TopTools_ListOfShape& theList)
386 if(myGenMap.IsBound(theShape)) {
387 theList = myGenMap.Find(theShape);
391 //=======================================================================
394 //=======================================================================
396 TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
397 const TopoDS_Edge& EProfile)
401 if ( BRep_Tool::Degenerated(EProfile))
404 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
406 // *************************************************
407 // Search if EProfile is an edge of myProfile
408 // *************************************************
409 iprof = FindEdge(myProfile, EProfile, count);
411 if (!iprof) throw Standard_DomainError(
412 "BRepFill_Pipe::Face : Edge not in the Profile");
415 // *************************************************
416 // Search if ESpine is an edge of mySpine and find
417 // the index of the corresponding Filler
418 // *************************************************
419 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
420 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
422 if (!ispin) throw Standard_DomainError(
423 "BRepFill_Pipe::Edge : Edge not in the Spine");
425 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
430 //=======================================================================
433 //=======================================================================
434 TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
435 const TopoDS_Vertex& VProfile)
437 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
439 // *************************************************
440 // Search if VProfile is a Vertex of myProfile
441 // *************************************************
442 iprof = FindVertex(myProfile, VProfile, count);
443 if (!iprof) throw Standard_DomainError(
444 "BRepFill_Pipe::Edge : Vertex not in the Profile");
447 // *************************************************
448 // Search if ESpine is an edge of mySpine and find
449 // the index of the corresponding Filler
450 // *************************************************
452 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
453 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
455 if (!ispin) throw Standard_DomainError(
456 "BRepFill_Pipe::Edge : Edge not in the Spine");
459 // *************************************************
460 // Generate the corresponding Shape
461 // *************************************************
463 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
470 //=======================================================================
473 //=======================================================================
475 TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
477 TopoDS_Iterator it, itv;
479 Standard_Integer ii, ispin = 0;
481 TopoDS_Shape curSect = myProfile;
483 // *************************************************
484 // Search if ESpine is an edge of mySpine and find
485 // the index of the corresponding Filler
486 // *************************************************
488 // iterate on all the edges of mySpine
489 for (ii=1; ii<=myLoc->NbLaw()+1 && (!ispin); ii++)
490 if (VSpine.IsSame(myLoc->Vertex(ii))) ispin = ii;
492 if (!ispin) throw Standard_DomainError(
493 "BRepFill_Pipe::Section : Vertex not in the Spine");
496 TopoDS_Compound Comp;
497 B.MakeCompound(Comp);
498 for (ii=1; ii<=mySections->ColLength(); ii++)
499 B.Add(Comp, mySections->Value(ii, ispin));
504 //=======================================================================
505 //function : PipeLine
506 //purpose : Construct a wire by sweeping of a point
507 //=======================================================================
509 TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
516 TopoDS_Vertex VertexSection = BRepLib_MakeVertex(P);
517 Handle(BRepFill_ShapeLaw) Section =
518 new (BRepFill_ShapeLaw) (VertexSection);
521 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
522 MkSw.SetForceApproxC1(myForceApproxC1);
523 MkSw.Build( myReversedEdges, myTapes, myRails,
524 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
525 TopoDS_Shape aLocalShape = MkSw.Shape();
526 myErrorOnSurf = MkSw.ErrorOnSurface();
527 BuildHistory(MkSw, VertexSection);
528 return TopoDS::Wire(aLocalShape);
529 // return TopoDS::Wire(MkSw.Shape());
532 //=======================================================================
533 //function : MakeShape
535 //=======================================================================
537 TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
538 const TopoDS_Shape& theOriginalS,
539 const TopoDS_Shape& FirstShape,
540 const TopoDS_Shape& LastShape)
544 Standard_Boolean explode = Standard_False;
545 TopoDS_Shape TheS, TheFirst, TheLast;
546 Standard_Integer InitialLength = 0;
548 TheFirst = FirstShape;
550 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
552 TopLoc_Location BackLoc(myTrsf.Inverted());
554 // there are two kinds of generation
555 // 1. generate with S from each Filler (Vertex, Edge)
556 // 2. call MakeShape recursively on the subshapes of S
558 // explode is True in the second case
560 // create the result empty
562 switch (S.ShapeType()) {
566 B.MakeWire(TopoDS::Wire(result));
573 B.MakeShell(TopoDS::Shell(result));
576 W.Closed(BRep_Tool::IsClosed(S));
578 if (!FirstShape.IsNull()) {
580 B.Add(W, FirstShape);
581 W.Closed(BRep_Tool::IsClosed(FirstShape));
584 if (!LastShape.IsNull()) {
587 W.Closed(BRep_Tool::IsClosed(LastShape));
590 result.Closed (BRep_Tool::IsClosed (result));
595 B.MakeShell(TopoDS::Shell(result));
600 B.MakeShell(TopoDS::Shell(result));
601 explode = Standard_True;
602 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
603 B.Add(result, TheFirst.Reversed());
605 result.Closed (BRep_Tool::IsClosed (result));
611 B.MakeCompSolid(TopoDS::CompSolid(result));
612 explode = Standard_True;
617 case TopAbs_COMPSOLID :
618 throw Standard_DomainError("BRepFill_Pipe::profile contains solids");
621 case TopAbs_COMPOUND :
623 B.MakeCompound(TopoDS::Compound(result));
624 explode = Standard_True;
633 TopoDS_Iterator itFirst, itLast;
634 TopoDS_Shape first, last;
635 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
636 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
638 TopoDS_Iterator it(S);
639 TopoDS_Iterator itorig(theOriginalS);
640 for (; it.More(); it.Next(),itorig.Next()) {
641 if (!TheFirst.IsNull()) first = itFirst.Value();
642 if (!TheLast.IsNull()) last = itLast.Value();
643 if (TheS.ShapeType() == TopAbs_FACE )
644 MakeShape(it.Value(), itorig.Value(), first, last);
646 B.Add(result,MakeShape(it.Value(), itorig.Value(), first, last));
648 if (!TheFirst.IsNull()) itFirst.Next();
649 if (!TheLast.IsNull()) itLast.Next();
654 if (TheS.ShapeType() == TopAbs_VERTEX ) {
655 Handle(BRepFill_ShapeLaw) Section =
656 new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
657 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
658 MkSw.SetForceApproxC1(myForceApproxC1);
659 MkSw.Build( myReversedEdges, myTapes, myRails,
660 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
661 result = MkSw.Shape();
662 UpdateMap(theOriginalS, result, myGenMap);
663 myErrorOnSurf = MkSw.ErrorOnSurface();
665 Handle(TopTools_HArray2OfShape) aSections = MkSw.Sections();
667 if (aSections.IsNull() == Standard_False) {
668 const Standard_Integer aVLast = aSections->UpperCol();
670 myFirst = aSections->Value(1, 1);
671 myLast = aSections->Value(1, aVLast);
674 BuildHistory(MkSw, theOriginalS);
677 if (TheS.ShapeType() == TopAbs_WIRE ) {
678 Handle(BRepFill_ShapeLaw) Section =
679 new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS));
680 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
681 MkSw.SetBounds(TopoDS::Wire(TheFirst),
682 TopoDS::Wire(TheLast));
683 MkSw.SetForceApproxC1(myForceApproxC1);
684 MkSw.Build( myReversedEdges, myTapes, myRails,
685 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
686 result = MkSw.Shape();
687 myErrorOnSurf = MkSw.ErrorOnSurface();
689 // Labeling of elements
690 if (mySections.IsNull()) {
691 myFaces = MkSw.SubShape();
692 mySections = MkSw.Sections();
693 myEdges = MkSw.InterFaces();
696 Handle(TopTools_HArray2OfShape) Aux, Somme;
697 Standard_Integer length;
698 Standard_Integer ii, jj, kk;
700 Aux = MkSw.SubShape();
701 length = Aux->ColLength() + myFaces->ColLength();
702 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
704 for (jj=1; jj<=myFaces->RowLength(); jj++) {
705 for (ii=1; ii<=myFaces->ColLength(); ii++)
706 Somme->SetValue(ii, jj, myFaces->Value(ii, jj));
708 for (kk=1, ii=myFaces->ColLength()+1;
709 kk <=Aux->ColLength(); kk++, ii++)
710 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
714 Aux = MkSw.Sections();
715 length = Aux->ColLength() + mySections->ColLength();
716 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
718 for (jj=1; jj<=mySections->RowLength(); jj++) {
719 for (ii=1; ii<=mySections->ColLength(); ii++)
720 Somme->SetValue(ii, jj, mySections->Value(ii, jj));
722 myCurIndexOfSectionEdge = mySections->ColLength()+1;
724 for (kk=1, ii=mySections->ColLength()+1;
725 kk <=Aux->ColLength(); kk++, ii++)
726 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
730 Aux = MkSw.InterFaces();
731 length = Aux->ColLength() + myEdges->ColLength();
732 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
734 for (jj=1; jj<=myEdges->RowLength(); jj++) {
735 for (ii=1; ii<=myEdges->ColLength(); ii++)
736 Somme->SetValue(ii, jj, myEdges->Value(ii, jj));
738 for (kk=1, ii=myEdges->ColLength()+1;
739 kk <=Aux->ColLength(); kk++, ii++)
740 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
746 BuildHistory(MkSw, theOriginalS);
750 if ( TheS.ShapeType() == TopAbs_FACE ) {
751 Standard_Integer ii, jj;
753 TopExp_Explorer Explo(result, TopAbs_FACE);
754 for (; Explo.More(); Explo.Next())
756 TopoDS_Shape aFace = Explo.Current();
757 RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed
761 for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
762 for (jj=1; jj<=myFaces->RowLength(); jj++) {
763 if (myFaces->Value(ii, jj).ShapeType() == TopAbs_FACE)
765 F = TopoDS::Face(myFaces->Value(ii, jj));
766 if (!F.IsNull()) B.Add(result, F);
771 if ( !mySpine.Closed()) {
772 // if Spine is not closed
773 // add the last face of the solid
776 RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face
778 B.Add(result, TopoDS::Face(TheLast));
785 result.Closed(Standard_True);
786 BS.Add(solid,TopoDS::Shell(result));
788 BRepClass3d_SolidClassifier SC(solid);
789 SC.PerformInfinitePoint(Precision::Confusion());
790 if ( SC.State() == TopAbs_IN) {
792 TopoDS_Shape aLocalShape = result.Reversed();
793 BS.Add(solid,TopoDS::Shell(aLocalShape));
794 // BS.Add(solid,TopoDS::Shell(result.Reversed()));
796 UpdateMap(theOriginalS, solid, myGenMap);
804 //============================================================================
805 //function : FindEdge
806 //purpose : Find the number of edge corresponding to the edge of the profile.
807 //============================================================================
809 Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
810 const TopoDS_Edge& E,
811 Standard_Integer& InitialLength) const
813 Standard_Integer result = 0;
815 switch (S.ShapeType()) {
820 if (S.IsSame(E)) result = InitialLength;
826 Handle(BRepFill_ShapeLaw) Section =
827 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
828 Standard_Integer NbLaw = Section->NbLaw();
830 for (Standard_Integer ii = 1; (ii<=NbLaw) && (!result); ii++) {
831 if (E.IsSame(Section->Edge(ii)) ) result = InitialLength + ii;
833 InitialLength += NbLaw;
839 case TopAbs_COMPOUND :
841 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
842 result = FindEdge(it.Value(), E, InitialLength );
847 case TopAbs_COMPSOLID :
848 throw Standard_DomainError("BRepFill_Pipe::SOLID or COMPSOLID");
857 //=======================================================================
858 //function : FindVertex
859 //purpose : Find the number of edge corresponding to an edge of the profile.
860 //=======================================================================
862 Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
863 const TopoDS_Vertex& V,
864 Standard_Integer& InitialLength) const
866 Standard_Integer result = 0;
868 switch (S.ShapeType()) {
872 if (S.IsSame(V)) result = InitialLength;
878 TopoDS_Vertex VF, VL;
879 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
880 if (S.Orientation() == TopAbs_REVERSED) {
882 aux = VF; VF = VL; VL = aux;
884 if (VF.IsSame(V)) result = InitialLength+1;
885 else if (VL.IsSame(V)) result = InitialLength+2;
892 Standard_Integer ii = InitialLength+1;
893 Handle(BRepFill_ShapeLaw) Section =
894 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
895 InitialLength += Section->NbLaw()+1;
897 for (; (ii<=InitialLength) && (!result); ii++) {
898 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
905 case TopAbs_COMPOUND :
907 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
908 result = FindVertex(it.Value(), V, InitialLength);
913 case TopAbs_COMPSOLID :
914 throw Standard_DomainError("BRepFill_Pipe::SOLID or COMPSOLID");
923 //=======================================================================
924 //function : DefineRealSegmax
925 //purpose : Defines the real number of segments
926 // required in the case of bspline spine
927 //=======================================================================
929 void BRepFill_Pipe::DefineRealSegmax()
931 Standard_Integer RealSegmax = 0;
933 TopoDS_Iterator iter(mySpine);
934 for (; iter.More(); iter.Next())
936 TopoDS_Edge E = TopoDS::Edge(iter.Value());
937 Standard_Real first, last;
938 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
941 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
942 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
944 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
945 C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
946 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
947 C = Handle(Geom_OffsetCurve)::DownCast (C)->BasisCurve();
949 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
951 Handle(Geom_BSplineCurve) BC (Handle(Geom_BSplineCurve)::DownCast (C));
952 Standard_Integer NbKnots = BC->NbKnots();
953 Standard_Integer RealNbKnots = NbKnots;
954 if (first > BC->FirstParameter())
956 Standard_Integer I1, I2;
957 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
960 if (last < BC->LastParameter())
962 Standard_Integer I1, I2;
963 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
964 RealNbKnots -= NbKnots-I2;
966 RealSegmax += RealNbKnots-1;
970 if (mySegmax < RealSegmax)
971 mySegmax = RealSegmax;
974 //=======================================================================
975 //function : RebuildTopOrBottomFace
976 //purpose : Correct orientation of v-iso edges
977 // according to new 3d and 2d curves taken from swept surfaces
978 //=======================================================================
980 void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace,
981 const Standard_Boolean IsTop) const
983 Standard_Integer IndexOfSection =
984 (IsTop)? 1 : mySections->RowLength();
988 TopoDS_Iterator itf(aFace);
989 for (; itf.More(); itf.Next())
991 TopoDS_Shape aWire = itf.Value();
992 TopTools_SequenceOfShape InitEdges;
993 TopTools_SequenceOfShape ResEdges;
994 TopoDS_Iterator itw(aWire);
995 for (; itw.More(); itw.Next())
997 TopoDS_Shape anEdge = itw.Value();
998 for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++)
1000 TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection);
1001 if (anEdge.IsSame(aVisoEdge))
1003 InitEdges.Append(anEdge);
1004 ResEdges.Append(aVisoEdge);
1009 aWire.Free(Standard_True);
1010 for (ii = 1; ii <= InitEdges.Length(); ii++)
1012 BB.Remove(aWire, InitEdges(ii));
1013 UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii)));
1014 BB.Add(aWire, ResEdges(ii));
1019 //=======================================================================
1020 //function : BuildHistory
1021 //purpose : Builds history for edges and vertices
1022 // of section and path
1023 //=======================================================================
1024 void BRepFill_Pipe::BuildHistory(const BRepFill_Sweep& theSweep,
1025 const TopoDS_Shape& theSection)
1027 //Filling of <myGenMap>
1028 const Handle(TopTools_HArray2OfShape)& anUEdges = theSweep.InterFaces();
1030 Standard_Integer inde;
1031 TopoDS_Iterator itw;
1033 if (theSection.ShapeType() == TopAbs_WIRE)
1035 TopoDS_Wire aSection = TopoDS::Wire(theSection);
1036 BRepTools_WireExplorer wexp_sec(aSection);
1037 for (inde = 0; wexp_sec.More(); wexp_sec.Next())
1040 const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current());
1041 if (BRep_Tool::Degenerated(anEdge))
1043 if (myGenMap.IsBound(anEdge))
1046 TopoDS_Vertex aVertex [2];
1047 TopExp::Vertices(anEdge, aVertex[0], aVertex[1]);
1049 //For an edge generated shape is a "tape" -
1050 //a shell usually containing this edge and
1051 //passing from beginning of path to its end
1052 TopoDS_Shell aTape = TopoDS::Shell(theSweep.Tape(inde));
1054 //Processing of vertices of <anEdge>
1055 //We should choose right index in <anUEdges>
1056 //for each vertex of edge
1057 Standard_Integer UIndex [2];
1061 if (anEdge.Orientation() == TopAbs_REVERSED)
1062 { Standard_Integer Tmp = UIndex[0]; UIndex[0] = UIndex[1]; UIndex[1] = Tmp; }
1064 for (Standard_Integer kk = 0; kk < 2; kk++)
1066 if (myGenMap.IsBound(aVertex[kk]))
1069 //Assemble the list of edges ("rail" along the path)
1070 TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape());
1071 Standard_Integer jj;
1072 for (jj = 1; jj <= anUEdges->UpperCol(); jj++)
1074 const TopoDS_Shape& anUedge = anUEdges->Value(UIndex[kk], jj);
1075 if (!anUedge.IsNull())
1076 Elist->Append(anUedge);
1078 } //for (Standard_Integer kk = 0; kk < 2; kk++)
1080 TopTools_ListOfShape* Flist = myGenMap.Bound(anEdge, TopTools_ListOfShape());
1081 TopoDS_Iterator itsh(aTape);
1082 for (; itsh.More(); itsh.Next())
1083 Flist->Append(itsh.Value());
1084 } //for (inde = 0; wexp_sec.More(); wexp_sec.Next())
1085 } //if (theSection.ShapeType() == TopAbs_WIRE)
1087 //For subshapes of spine
1088 const Handle(TopTools_HArray2OfShape)& aFaces = theSweep.SubShape();
1089 const Handle(TopTools_HArray2OfShape)& aVEdges = theSweep.Sections();
1091 BRepTools_WireExplorer wexp(mySpine);
1093 Standard_Boolean ToExit = Standard_False;
1097 ToExit = Standard_True;
1103 const TopoDS_Edge& anEdgeOfSpine = wexp.Current();
1104 for (Standard_Integer i = 1; i <= aFaces->UpperRow(); i++)
1106 const TopoDS_Shape& aFace = aFaces->Value(i, inde);
1107 UpdateMap(anEdgeOfSpine, aFace, myGenMap);
1111 const TopoDS_Vertex& aVertexOfSpine = wexp.CurrentVertex();
1112 for (Standard_Integer i = 1; i <= aVEdges->UpperRow(); i++)
1114 const TopoDS_Shape& aVedge = aVEdges->Value(i, inde);
1115 UpdateMap(aVertexOfSpine, aVedge, myGenMap);