1 // File: BRepOffset_MakeOffset.cxx
2 // Created: Fri Oct 27 10:30:44 1995
3 // Author: Yves FRICAUD
7 // Modified by skv - Tue Mar 15 16:20:43 2005
8 // Add methods for supporting history.
10 // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455
12 #include <BRepOffset_MakeOffset.ixx>
13 #include <BRepOffset_Analyse.hxx>
14 #include <BRepOffset_DataMapOfShapeOffset.hxx>
15 #include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
16 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
17 #include <BRepOffset_Interval.hxx>
18 #include <BRepOffset_ListOfInterval.hxx>
19 #include <BRepOffset_Offset.hxx>
20 #include <BRepOffset_Tool.hxx>
21 #include <BRepOffset_Inter2d.hxx>
22 #include <BRepOffset_Inter3d.hxx>
23 #include <BRepOffset_MakeLoops.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27 #include <BRepCheck_Edge.hxx>
28 #include <BRepCheck_Vertex.hxx>
29 #include <BRepLib.hxx>
30 #include <BRepLib_MakeVertex.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_TVertex.hxx>
34 #include <BRepTools_Quilt.hxx>
35 #include <BRepClass3d_SolidClassifier.hxx>
39 #include <TopExp_Explorer.hxx>
41 #include <TopoDS_Solid.hxx>
42 #include <TopoDS_Shell.hxx>
43 #include <TopoDS_Compound.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Vertex.hxx>
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_MapIteratorOfMapOfShape.hxx>
50 #include <TopTools_ListOfShape.hxx>
51 #include <TopTools_ListIteratorOfListOfShape.hxx>
52 #include <TopTools_DataMapOfShapeShape.hxx>
53 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
55 #include <TColStd_ListIteratorOfListOfInteger.hxx>
57 #include <Standard_NotImplemented.hxx>
58 #include <Standard_ConstructionError.hxx>
59 #include <Precision.hxx>
61 #include <TopTools_SequenceOfShape.hxx>
62 #include <Geom_OffsetSurface.hxx>
63 #include <Geom_ConicalSurface.hxx>
64 #include <TopTools_IndexedMapOfShape.hxx>
65 #include <BRep_TEdge.hxx>
66 #include <BRepTools.hxx>
67 #include <gp_Cone.hxx>
70 #include <gp_Lin2d.hxx>
71 #include <GCE2d_MakeLine.hxx>
72 #include <Geom2d_Line.hxx>
73 #include <TopoDS_Iterator.hxx>
74 #include <BRepLib_MakeFace.hxx>
75 #include <Geom_Circle.hxx>
77 #include <BRep_PointRepresentation.hxx>
78 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
79 #include <GeomAPI_ProjectPointOnCurve.hxx>
81 #include <BRepAdaptor_Curve.hxx>
82 #include <BRepAdaptor_Curve2d.hxx>
83 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
84 #include <Geom_SphericalSurface.hxx>
85 #include <TopoDS_Wire.hxx>
86 #include <BRepTools_Substitution.hxx>
87 #include <Geom_TrimmedCurve.hxx>
88 #include <Geom2d_TrimmedCurve.hxx>
90 #include <BRepTools_WireExplorer.hxx>
91 #include <BRepLib_MakeEdge.hxx>
92 #include <gce_MakeDir.hxx>
93 #include <GC_MakeCylindricalSurface.hxx>
94 #include <gce_MakeCone.hxx>
95 #include <Geom_SurfaceOfLinearExtrusion.hxx>
97 #include <Geom2dAdaptor_HCurve.hxx>
98 #include <GeomAdaptor_HSurface.hxx>
99 #include <Adaptor3d_CurveOnSurface.hxx>
100 #include <GeomLib.hxx>
101 #include <GeomFill_Generator.hxx>
112 #include <OSD_Chronometer.hxx>
114 Standard_Boolean AffichInt2d = Standard_False;
115 Standard_Boolean AffichOffC = Standard_False;
116 Standard_Boolean ChronBuild = Standard_False;
117 Standard_Integer NbAE = 0;
118 Standard_Integer NbAF = 0;
119 static OSD_Chronometer Clock;
125 //=======================================================================
126 //function : DEBVerticesControl
128 //=======================================================================
130 static void DEBVerticesControl (const TopTools_MapOfShape& NewEdges,
131 Handle(BRepAlgo_AsDes) AsDes)
133 Standard_Integer NVP = 0;
134 Standard_Integer NVM = 0;
135 Standard_Integer NVN = 0;
137 TopTools_ListOfShape LVP;
138 TopTools_MapIteratorOfMapOfShape it;
139 TopTools_ListIteratorOfListOfShape it1LE ;
140 TopTools_ListIteratorOfListOfShape it2LE ;
142 for (it.Initialize(NewEdges) ; it.More(); it.Next()) {
143 const TopoDS_Edge& NE = TopoDS::Edge(it.Key());
144 if (AsDes->HasDescendant(NE)) {
145 for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
146 if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
147 LVP.Append(it1LE.Value());
148 cout <<"Vertex on at least 3 edges."<<endl;
151 sprintf (name,"VP_%d",NVP++);
152 DBRep::Set(name,it1LE.Value());
156 else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
157 cout <<"Vertex on more than 3 edges."<<endl;
160 sprintf (name,"VM_%d",NVM++);
161 DBRep::Set(name,it1LE.Value());
169 sprintf (name,"VN_%d",NVN++);
170 DBRep::Set(name,it1LE.Value());
177 //------------------------------------------------
178 // Try to mix spoiled vertices.
179 //------------------------------------------------
181 TopTools_ListIteratorOfListOfShape it1(LVP);
182 Standard_Real TolConf = 1.e-5;
183 Standard_Real Tol = Precision::Confusion();
184 Standard_Integer i = 1;
186 for ( ; it1.More(); it1.Next()) {
187 TopoDS_Shape V1 = it1.Value();
188 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(V1));
189 Standard_Real distmin = Precision::Infinite();
190 TopTools_ListIteratorOfListOfShape it2(LVP);
191 Standard_Integer j = 1;
193 for ( ; it2.More(); it2.Next()) {
195 TopoDS_Shape V2 = it2.Value();
196 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2));
197 if (!V1.IsSame(V2)) {
198 Standard_Real dist = P1.Distance(P2);
199 if (dist < distmin) distmin = dist;
200 if (dist < TolConf) {
203 const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
204 TopTools_ListIteratorOfListOfShape itAsDes;
205 for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) {
206 EWE2 = TopoDS::Edge(itAsDes.Value());
207 TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL);
208 UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
209 aLocalShape = V1.Oriented(TopAbs_INTERNAL) ;
210 B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
212 // BRep_Tool::Parameter(TopoDS::Vertex(),EWE2);
213 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
216 AsDes->Replace(V2,V1);
223 cout <<" distmin between VP : "<<distmin<<endl;
229 static void UpdateTolerance ( TopoDS_Shape& myShape,
230 const TopTools_MapOfShape& myFaces);
233 static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
234 const TopoDS_Edge& E,
237 // Search the vertex in the edge
239 Standard_Boolean rev = Standard_False;
241 TopAbs_Orientation orient = TopAbs_INTERNAL;
243 TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
245 // if the edge has no vertices
246 // and is degenerated use the vertex orientation
249 if (!itv.More() && BRep_Tool::Degenerated(E)) {
250 orient = V.Orientation();
254 const TopoDS_Shape& Vcur = itv.Value();
255 if (V.IsSame(Vcur)) {
260 rev = E.Orientation() == TopAbs_REVERSED;
261 if (Vcur.Orientation() == V.Orientation()) {
269 if (!VF.IsNull()) orient = VF.Orientation();
273 if (orient == TopAbs_FORWARD) {
274 BRep_Tool::Range(E,f,l);
275 //return (rev) ? l : f;
277 return Standard_True;
280 else if (orient == TopAbs_REVERSED) {
281 BRep_Tool::Range(E,f,l);
282 //return (rev) ? f : l;
284 return Standard_True;
289 const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
290 L = L.Predivided(V.Location());
291 if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
292 BRep_ListIteratorOfListOfPointRepresentation itpr
293 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
295 while (itpr.More()) {
296 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
297 if (pr->IsPointOnCurve(C,L)) {
298 Standard_Real p = pr->Parameter();
299 Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
301 // Closed curves RLE 16 june 94
302 if (Precision::IsNegativeInfinite(f))
304 //return pr->Parameter();//p;
306 return Standard_True;
308 if (Precision::IsPositiveInfinite(l))
310 //return pr->Parameter();//p;
312 return Standard_True;
314 gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
315 gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
316 Standard_Real tol = BRep_Tool::Tolerance(V);
317 if (Pf.Distance(Pl) < tol) {
318 if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
319 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
320 else res = l;//p = l;
326 return Standard_True;
333 // let us try with the first pcurve
334 Handle(Geom2d_Curve) PC;
335 Handle(Geom_Surface) S;
336 BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
337 L = L.Predivided(V.Location());
338 BRep_ListIteratorOfListOfPointRepresentation itpr
339 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
341 while (itpr.More()) {
342 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
343 if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
344 Standard_Real p = pr->Parameter();
345 // Closed curves RLE 16 june 94
346 if (PC->IsClosed()) {
347 if ((p == PC->FirstParameter()) ||
348 (p == PC->LastParameter())) {
349 if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
350 else p = PC->LastParameter();
355 return Standard_True;
362 //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
363 return Standard_False;
366 //=======================================================================
367 //function : GetEdgePoints
368 //purpose : gets the first, last and middle points of the edge
369 //=======================================================================
370 static void GetEdgePoints(const TopoDS_Edge& anEdge,
371 const TopoDS_Face& aFace,
372 gp_Pnt& fPnt, gp_Pnt& mPnt,
376 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
377 gp_Pnt2d fPnt2d = theCurve->Value(f);
378 gp_Pnt2d lPnt2d = theCurve->Value(l);
379 gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
380 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
381 fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
382 lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
383 mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
386 //=======================================================================
387 //function : FillContours
388 //purpose : fills free boundary contours and faces connected (MapEF)
389 //=======================================================================
390 static void FillContours(const TopoDS_Shape& aShape,
391 const BRepOffset_Analyse& Analyser,
392 TopTools_DataMapOfShapeListOfShape& Contours,
393 TopTools_DataMapOfShapeShape& MapEF)
395 TopTools_ListOfShape Edges;
397 TopExp_Explorer Explo(aShape, TopAbs_FACE);
398 BRepTools_WireExplorer Wexp;
400 for (; Explo.More(); Explo.Next())
402 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
403 TopoDS_Iterator itf(aFace);
404 for (; itf.More(); itf.Next())
406 TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
407 for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
409 TopoDS_Edge anEdge = Wexp.Current();
410 if (BRep_Tool::Degenerated(anEdge))
412 const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
413 if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
415 MapEF.Bind(anEdge, aFace);
416 Edges.Append(anEdge);
422 TopTools_ListIteratorOfListOfShape itl;
423 while (!Edges.IsEmpty())
425 TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
427 TopoDS_Vertex StartVertex, CurVertex;
428 TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
429 TopTools_ListOfShape aContour;
430 aContour.Append(StartEdge);
431 while (!CurVertex.IsSame(StartVertex))
432 for (itl.Initialize(Edges); itl.More(); itl.Next())
434 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
435 TopoDS_Vertex V1, V2;
436 TopExp::Vertices(anEdge, V1, V2);
437 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
439 aContour.Append(anEdge);
440 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
445 Contours.Bind(StartVertex, aContour);
449 //=======================================================================
450 //function : BRepOffset_MakeOffset
452 //=======================================================================
454 BRepOffset_MakeOffset::BRepOffset_MakeOffset()
456 myAsDes = new BRepAlgo_AsDes();
460 //=======================================================================
461 //function : BRepOffset_MakeOffset
463 //=======================================================================
465 BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S,
466 const Standard_Real Offset,
467 const Standard_Real Tol,
468 const BRepOffset_Mode Mode,
469 const Standard_Boolean Inter,
470 const Standard_Boolean SelfInter,
471 const GeomAbs_JoinType Join,
472 const Standard_Boolean Thickening)
479 mySelfInter (SelfInter),
481 myThickening (Thickening),
482 myDone (Standard_False)
485 myAsDes = new BRepAlgo_AsDes();
490 //=======================================================================
491 //function : Initialize
493 //=======================================================================
495 void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
496 const Standard_Real Offset,
497 const Standard_Real Tol,
498 const BRepOffset_Mode Mode,
499 const Standard_Boolean Inter,
500 const Standard_Boolean SelfInter,
501 const GeomAbs_JoinType Join,
502 const Standard_Boolean Thickening)
509 mySelfInter = SelfInter;
511 myThickening = Thickening;
512 myDone = Standard_False;
517 //=======================================================================
520 //=======================================================================
522 void BRepOffset_MakeOffset::Clear()
524 myOffsetShape.Nullify();
525 myInitOffsetFace .Clear();
526 myInitOffsetEdge .Clear();
527 myImageOffset .Clear();
529 myFaceOffset .Clear();
531 myDone = Standard_False;
534 //=======================================================================
537 //=======================================================================
539 void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
544 myInitOffsetFace.SetRoot (F) ;
545 myInitOffsetFace.Bind (F,F);
546 myImageOffset.SetRoot (F) ;
549 //=======================================================================
550 //function : SetOffsetOnFace
552 //=======================================================================
554 void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F,
555 const Standard_Real Off)
557 if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
558 myFaceOffset.Bind(F,Off);
561 //=======================================================================
562 //function : RemoveCorks
564 //=======================================================================
566 static void RemoveCorks (TopoDS_Shape& S,
567 TopTools_MapOfShape& Faces)
572 //-----------------------------------------------------
573 // Construction of a shape without caps.
574 // and Orientation of caps as in shape S.
575 //-----------------------------------------------------
576 TopExp_Explorer exp(S,TopAbs_FACE);
577 for (; exp.More(); exp.Next()) {
578 const TopoDS_Shape& Cork = exp.Current();
579 if (!Faces.Contains(Cork)) {
584 Faces.Add (Cork); // to reset it with proper orientation.
590 DBRep::Set("myInit", SS);
595 static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
597 BRepTools_Quilt Glue;
600 TopoDS_Shape SS = Glue.Shells();
601 TopExp_Explorer Explo( SS, TopAbs_SHELL );
604 return Standard_False;
606 return Standard_True;
610 //=======================================================================
611 //function : MakeList
613 //=======================================================================
615 static void MakeList (TopTools_ListOfShape& OffsetFaces,
616 const BRepAlgo_Image& myInitOffsetFace,
617 const TopTools_MapOfShape& myFaces)
619 TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
620 for ( ; itLOF.More(); itLOF.Next()) {
621 const TopoDS_Shape& Root = itLOF.Value();
622 if (!myFaces.Contains(Root))
623 OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
627 //=======================================================================
630 //=======================================================================
632 static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
635 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
636 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
637 Standard_Real TolV = BRep_Tool::Tolerance(V);
638 if (TolV > Tol) Tol = TolV;
644 //=======================================================================
645 //function : MakeOffsetShape
647 //=======================================================================
649 void BRepOffset_MakeOffset::MakeOffsetShape()
651 myDone = Standard_False;
652 //------------------------------------------
653 // Construction of myShape without caps.
654 //------------------------------------------
655 RemoveCorks (myShape,myFaces);
657 if (! IsConnectedShell(myShape))
658 Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
660 if (Abs(myOffset) < myTol) return;
662 TopAbs_State Side = TopAbs_IN;
663 if (myOffset < 0.) Side = TopAbs_OUT;
667 EvalMax(myShape,myTol);
668 if (myTol > Abs(myOffset*0.5)) {
669 Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Tol > Offset");
671 Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
672 myAnalyse.Perform(myShape,TolAngle);
673 //---------------------------------------------------
674 // Construction of Offset from preanalysis.
675 //---------------------------------------------------
676 //----------------------------
677 // MaJ of SD Face - Offset
678 //----------------------------
681 if (myJoin == GeomAbs_Arc)
683 else if (myJoin == GeomAbs_Intersection)
684 BuildOffsetByInter();
688 // if (mySelfInter) SelfInter(Modif);
692 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
693 Intersection3D (Inter);
697 TopTools_MapOfShape& Modif = Inter.TouchedFaces();
698 TopTools_MapOfShape& NewEdges = Inter.NewEdges();
700 if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
701 //-------------------------------------------------------
702 // Unwinding 2D and reconstruction of modified faces
703 //----------------------------------------------------
705 //-----------------------------------------------------
706 // Reconstruction of non modified faces sharing
707 // reconstructed edges
708 //------------------------------------------------------
709 if (!Modif.IsEmpty()) MakeFaces (Modif);
714 //-------------------------
715 // Construction of shells.
716 //-------------------------
722 //----------------------------------
723 // Coding of regularities.
724 //----------------------------------
726 //----------------------
727 // Creation of solids.
728 //----------------------
731 //-----------------------------
732 // MAJ Tolerance edge and Vertex
733 // ----------------------------
734 if (!myOffsetShape.IsNull()) {
735 UpdateTolerance (myOffsetShape,myFaces);
736 BRepLib::UpdateTolerances( myOffsetShape );
739 CorrectConicalFaces();
741 myDone = Standard_True;
746 //=======================================================================
747 //function : MakeThickSolid
749 //=======================================================================
751 void BRepOffset_MakeOffset::MakeThickSolid()
753 //--------------------------------------------------------------
754 // Construction of shell parallel to shell (initial without cap).
755 //--------------------------------------------------------------
758 //--------------------------------------------------------------------
759 // Construction of a solid with the initial shell, parallel shell
761 //--------------------------------------------------------------------
762 if (!myFaces.IsEmpty()) {
766 Standard_Integer NbF = myFaces.Extent();
770 BRepTools_Quilt Glue;
771 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
773 Glue.Add (exp.Current());
775 Standard_Boolean YaResult = 0;
776 if (!myOffsetShape.IsNull()) {
777 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
779 Glue.Add (exp.Current().Reversed());
783 myDone = Standard_False;
786 myOffsetShape = Glue.Shells();
787 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
788 B.Add(Res,exp.Current());
790 Res.Closed(Standard_True);
793 // Test of Validity of the result of thick Solid
794 // more face than the initial solid.
796 Standard_Integer NbOF = 0;
797 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
801 myDone = Standard_False;
806 if (myOffset > 0 ) myOffsetShape.Reverse();
808 myDone = Standard_True;
811 //=======================================================================
814 //=======================================================================
816 Standard_Boolean BRepOffset_MakeOffset::IsDone() const
821 //=======================================================================
824 //=======================================================================
826 BRepOffset_Error BRepOffset_MakeOffset::Error() const
831 //=======================================================================
834 //=======================================================================
836 const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const
838 return myOffsetShape;
841 //=======================================================================
842 //function : TrimEdge
843 //purpose : Trim the edge of the largest of descendants in AsDes2d.
844 // Order in AsDes two vertices that have trimmed the edge.
845 //=======================================================================
847 static void TrimEdge (TopoDS_Edge& NE,
848 const Handle(BRepAlgo_AsDes)& AsDes2d,
849 Handle(BRepAlgo_AsDes)& AsDes)
851 Standard_Real aSameParTol = Precision::Confusion();
855 Standard_Real UMin = Precision::Infinite();
856 Standard_Real UMax = -UMin;
858 const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
860 if (LE.Extent() > 1) {
861 TopTools_ListIteratorOfListOfShape it (LE);
862 for (; it.More(); it.Next()) {
863 TopoDS_Vertex V = TopoDS::Vertex(it.Value());
864 if (NE.Orientation() == TopAbs_REVERSED)
866 //V.Orientation(TopAbs_INTERNAL);
867 if (!FindParameter(V, NE, U))
870 Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
871 gp_Pnt thePoint = BRep_Tool::Pnt(V);
872 GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
873 if (Projector.NbPoints() == 0)
874 Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
875 U = Projector.LowerDistanceParameter();
884 if (V1.IsNull() || V2.IsNull()) {
885 Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
887 if (!V1.IsSame(V2)) {
888 NE.Free( Standard_True );
890 TopAbs_Orientation Or = NE.Orientation();
891 NE.Orientation(TopAbs_FORWARD);
893 TopExp::Vertices (NE,VF,VL);
896 B.Add (NE,V1.Oriented(TopAbs_FORWARD));
897 B.Add (NE,V2.Oriented(TopAbs_REVERSED));
898 B.Range(NE,UMin,UMax);
900 AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
901 AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
902 BRepLib::SameParameter(NE, aSameParTol, Standard_True);
907 //=======================================================================
908 //function : BuildOffsetByInter
910 //=======================================================================
911 void BRepOffset_MakeOffset::BuildOffsetByInter()
915 cout << " CONSTRUCTION OF OFFSETS :" << endl;
921 BRepOffset_DataMapOfShapeOffset MapSF;
922 TopTools_MapOfShape Done;
923 Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
924 //--------------------------------------------------------
925 // Construction of faces parallel to initial faces
926 //--------------------------------------------------------
928 TopTools_ListOfShape LF;
929 TopTools_ListIteratorOfListOfShape itLF;
931 BRepLib::SortFaces(myShape,LF);
933 TopTools_DataMapOfShapeShape ShapeTgt;
934 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
935 const TopoDS_Face& F = TopoDS::Face(itLF.Value());
936 Standard_Real CurOffset = myOffset;
937 if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
938 BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
939 TopTools_ListOfShape Let;
940 myAnalyse.Edges(F,BRepOffset_Tangent,Let);
941 TopTools_ListIteratorOfListOfShape itl(Let);
943 for ( ; itl.More(); itl.Next()) {
944 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
945 if ( !ShapeTgt.IsBound(Cur)) {
946 TopoDS_Shape aLocalShape = OF.Generated(Cur);
947 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
948 // const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
949 ShapeTgt.Bind(Cur,OF.Generated(Cur));
950 TopoDS_Vertex V1,V2,OV1,OV2;
951 TopExp::Vertices (Cur,V1,V2);
952 TopExp::Vertices (OTE,OV1,OV2);
953 TopTools_ListOfShape LE;
954 if (!ShapeTgt.IsBound(V1)) {
955 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
956 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
957 if (LE.Extent() == LA.Extent())
958 ShapeTgt.Bind(V1,OV1);
960 if (!ShapeTgt.IsBound(V2)) {
962 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
963 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
964 if (LE.Extent() == LA.Extent())
965 ShapeTgt.Bind(V2,OV2);
971 //--------------------------------------------------------------------
972 // MES : Map of OffsetShape -> Extended Shapes.
973 // Build : Map of Initial SS -> OffsetShape build by Inter.
974 // can be an edge or a compound of edges
975 //---------------------------------------------------------------------
976 TopTools_DataMapOfShapeShape MES;
977 TopTools_DataMapOfShapeShape Build;
978 TopTools_ListOfShape Failed;
979 TopAbs_State Side = TopAbs_IN;
980 Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
982 //-------------------------------------------------------------------
983 // Extension of faces and calculation of new edges of intersection.
984 //-------------------------------------------------------------------
985 Standard_Boolean ExtentContext = 0;
986 if (myOffset > 0) ExtentContext = 1;
988 BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
989 // Intersection between parallel faces
990 Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
991 // Intersection with caps.
992 Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
995 //---------------------------------------------------------------------------------
996 // Extension of neighbor edges of new edges and intersection between neighbors.
997 //--------------------------------------------------------------------------------
998 Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
999 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1000 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1001 // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
1002 // BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
1003 BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myOffset, myTol);
1004 // Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
1006 //-----------------------------------------------------------
1007 // Great restriction of new edges and update of AsDes.
1008 //------------------------------------------ ----------------
1009 TopTools_MapOfShape NewEdges;
1010 TopExp_Explorer Exp2,ExpC;
1015 TopAbs_Orientation Or;
1018 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1019 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1020 NF = MapSF(FI).Face();
1021 if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));}
1022 TopTools_MapOfShape View;
1023 for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
1024 const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current());
1026 if (Build.IsBound(EI)) {
1028 if (NE.ShapeType() == TopAbs_EDGE) {
1029 if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1032 //------------------------------------------------------------
1033 // The Intersections are on several edges.
1034 // The pieces without intersections with neighbors
1035 // are removed from AsDes.
1036 //------------------------------------------------------------
1037 for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1038 if (NewEdges.Add(ExpC.Current())) {
1039 TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
1040 NEC.Free(Standard_True);
1041 if (!AsDes2d->Descendant(NEC).IsEmpty()) {
1042 TrimEdge (NEC,AsDes2d,AsDes);
1052 NE = MapSF(FI).Generated(EI);
1053 //// modified by jgv, 19.12.03 for OCC4455 ////
1054 NE.Orientation( EI.Orientation() );
1055 ///////////////////////////////////////////////
1056 if (MES.IsBound(NE)) {
1058 NE.Orientation(EI.Orientation());
1059 if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1067 //---------------------------------
1068 // Intersection 2D on //
1069 //---------------------------------
1070 TopTools_ListOfShape LFE;
1071 BRepAlgo_Image IMOE;
1072 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1073 const TopoDS_Shape& FI = Exp.Current();
1074 const TopoDS_Shape& OFI = MapSF(FI).Face();
1075 if (MES.IsBound(OFI)) {
1076 const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
1082 TopTools_ListIteratorOfListOfShape itLFE(LFE);
1083 for (; itLFE.More(); itLFE.Next()) {
1084 const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
1085 BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol);
1087 //----------------------------------------------
1088 // Intersections 2d on caps.
1089 //----------------------------------------------
1090 TopTools_MapIteratorOfMapOfShape itCork(myFaces);
1091 for (; itCork.More(); itCork.Next()) {
1092 const TopoDS_Face& Cork = TopoDS::Face(itCork.Key());
1093 BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol);
1096 //-------------------------------
1097 // Unwinding of extended Faces.
1098 //-------------------------------
1099 myMakeLoops.Build(LFE ,AsDes,IMOE);
1102 TopTools_MapOfShape COES;
1104 //---------------------------
1105 // MAJ SD. for faces //
1106 //---------------------------
1107 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1108 const TopoDS_Shape& FI = Exp.Current();
1109 myInitOffsetFace.SetRoot(FI);
1110 TopoDS_Face OF = MapSF(FI).Face();
1111 if (MES.IsBound(OF)) {
1112 OF = TopoDS::Face(MES(OF));
1113 if (IMOE.HasImage(OF)) {
1114 const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
1115 myInitOffsetFace.Bind(FI,LOFE);
1116 for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
1117 const TopoDS_Shape& OFE = itLF.Value();
1118 myImageOffset.SetRoot(OFE);
1121 sprintf(name,"AF_%d",NbAF++);
1122 DBRep::Set(name,OFE);
1125 TopTools_MapOfShape View;
1126 for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1127 Exp2.More(); Exp2.Next()) {
1128 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1130 myAsDes->Add (OFE,COE);
1133 sprintf(name,"AE_%d",NbAE++);
1134 DBRep::Set(name,COE);
1139 if (!myAsDes->HasDescendant(COE)) {
1140 TopoDS_Vertex CV1,CV2;
1141 TopExp::Vertices(COE,CV1,CV2);
1142 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1143 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1150 myInitOffsetFace.Bind(FI,OF);
1151 myImageOffset.SetRoot(OF);
1154 sprintf(name,"AF_%d",NbAF++);
1155 DBRep::Set(name,OF);
1158 const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
1159 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1160 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1161 if (IMOE.HasImage(OE)) {
1162 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1163 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1164 for (; itLOE.More(); itLOE.Next()) {
1165 TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
1166 const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
1167 // const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
1168 myAsDes->Add(OF,COE);
1171 sprintf(name,"AE_%d",NbAE++);
1172 DBRep::Set(name,COE);
1177 if (!myAsDes->HasDescendant(COE)) {
1178 TopoDS_Vertex CV1,CV2;
1179 TopExp::Vertices(COE,CV1,CV2);
1180 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1181 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1186 myAsDes->Add(OF,OE);
1189 sprintf(name,"AE_%d",NbAE++);
1190 DBRep::Set(name,OE);
1195 const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
1196 myAsDes->Add(OE,LV);
1202 myInitOffsetFace.Bind(FI,OF);
1203 myImageOffset.SetRoot(OF);
1204 TopTools_MapOfShape View;
1205 for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1206 Exp2.More(); Exp2.Next()) {
1208 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1209 myAsDes->Add (OF,COE);
1212 sprintf(name,"AE_%d",NbAE++);
1213 DBRep::Set(name,COE);
1218 if (View.Add(Exp2.Current())) {
1219 if (!myAsDes->HasDescendant(COE)) {
1220 TopoDS_Vertex CV1,CV2;
1221 TopExp::Vertices(COE,CV1,CV2);
1222 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1223 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1229 // Modified by skv - Tue Mar 15 16:20:43 2005
1230 // Add methods for supporting history.
1231 TopTools_MapOfShape aMapEdges;
1233 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1234 const TopoDS_Shape& aFaceRef = Exp.Current();
1236 Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1238 for (; Exp2.More(); Exp2.Next()) {
1239 const TopoDS_Shape& anEdgeRef = Exp2.Current();
1241 if (aMapEdges.Add(anEdgeRef)) {
1242 myInitOffsetEdge.SetRoot(anEdgeRef);
1243 if (Build.IsBound(anEdgeRef)) {
1244 TopoDS_Shape aNewShape = Build(anEdgeRef);
1246 if (aNewShape.ShapeType() == TopAbs_EDGE) {
1247 if (IMOE.HasImage(aNewShape)) {
1248 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
1250 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1252 myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
1253 } else { // aNewShape != TopAbs_EDGE
1254 TopTools_ListOfShape aListNewEdge;
1256 for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1257 const TopoDS_Shape &aResEdge = ExpC.Current();
1259 if (IMOE.HasImage(aResEdge)) {
1260 const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
1261 TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
1263 for (; aNewEIter.More(); aNewEIter.Next())
1264 aListNewEdge.Append(aNewEIter.Value());
1266 aListNewEdge.Append(aResEdge);
1269 myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
1272 else { // Free boundary.
1273 TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
1275 if (MES.IsBound(aNewEdge))
1276 aNewEdge = MES(aNewEdge);
1278 if (IMOE.HasImage(aNewEdge)) {
1279 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
1281 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1283 myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
1288 // Modified by skv - Tue Mar 15 16:20:43 2005
1290 //---------------------------
1292 //---------------------------
1293 TopTools_MapOfShape View;
1294 for (itCork.Initialize(myFaces); itCork.More(); itCork.Next()) {
1295 const TopoDS_Shape& Cork = itCork.Key();
1296 const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
1297 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1298 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1299 if (IMOE.HasImage(OE)) {
1300 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1301 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1302 for (; itLOE.More(); itLOE.Next()) {
1303 const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
1304 myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
1307 sprintf(name,"AE_%d",NbAE++);
1308 DBRep::Set(name,COE);
1313 if (!myAsDes->HasDescendant(COE)) {
1314 TopoDS_Vertex CV1,CV2;
1315 TopExp::Vertices(COE,CV1,CV2);
1316 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1317 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1322 myAsDes->Add(Cork,OE);
1323 if (AsDes->HasDescendant(OE)) {
1324 myAsDes->Add(OE,AsDes->Descendant(OE));
1328 sprintf(name,"AE_%d",NbAE++);
1329 DBRep::Set(name,OE);
1338 DEBVerticesControl (COES,myAsDes);
1339 if ( ChronBuild) Clock.Show();
1344 //=======================================================================
1345 //function : BuildOffsetByArc
1347 //=======================================================================
1348 void BRepOffset_MakeOffset::BuildOffsetByArc()
1352 cout << " CONSTRUCTION OF OFFSETS :" << endl;
1358 BRepOffset_DataMapOfShapeOffset MapSF;
1359 TopTools_MapOfShape Done;
1360 Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
1361 //--------------------------------------------------------
1362 // Construction of faces parallel to initial faces
1363 //--------------------------------------------------------
1364 TopExp_Explorer Exp;
1365 TopTools_ListOfShape LF;
1366 TopTools_ListIteratorOfListOfShape itLF;
1368 BRepLib::SortFaces(myShape,LF);
1370 TopTools_DataMapOfShapeShape EdgeTgt;
1371 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
1372 const TopoDS_Face& F = TopoDS::Face(itLF.Value());
1373 Standard_Real CurOffset = myOffset;
1374 if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
1375 BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
1376 TopTools_ListOfShape Let;
1377 myAnalyse.Edges(F,BRepOffset_Tangent,Let);
1378 TopTools_ListIteratorOfListOfShape itl(Let);
1380 for ( ; itl.More(); itl.Next()) {
1381 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
1382 if ( !EdgeTgt.IsBound(Cur)) {
1383 TopoDS_Shape aLocalShape = OF.Generated(Cur);
1384 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1385 // const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
1386 EdgeTgt.Bind(Cur,OF.Generated(Cur));
1387 TopoDS_Vertex V1,V2,OV1,OV2;
1388 TopExp::Vertices (Cur,V1,V2);
1389 TopExp::Vertices (OTE,OV1,OV2);
1390 TopTools_ListOfShape LE;
1391 if (!EdgeTgt.IsBound(V1)) {
1392 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1393 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
1394 if (LE.Extent() == LA.Extent())
1395 EdgeTgt.Bind(V1,OV1);
1397 if (!EdgeTgt.IsBound(V2)) {
1399 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1400 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
1401 if (LE.Extent() == LA.Extent())
1402 EdgeTgt.Bind(V2,OV2);
1408 //--------------------------------------------------------
1409 // Construction of tubes on edge.
1410 //--------------------------------------------------------
1411 BRepOffset_Type OT = BRepOffset_Convex;
1412 if (myOffset < 0.) OT = BRepOffset_Concave;
1414 for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1415 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1417 const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
1418 if (Anc.Extent() == 2) {
1419 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1420 if (!L.IsEmpty() && L.First().Type() == OT) {
1421 Standard_Real CurOffset = myOffset;
1422 if ( myFaceOffset.IsBound(Anc.First()))
1423 CurOffset = myFaceOffset(Anc.First());
1424 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1425 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1426 aLocalShape = MapSF(Anc.Last()).Generated(E);
1427 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1428 // TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1429 // TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
1430 // find if exits tangent edges in the original shape
1431 TopoDS_Edge E1f, E1l;
1432 TopoDS_Vertex V1f, V1l;
1433 TopExp::Vertices(E,V1f,V1l);
1434 TopTools_ListOfShape TangE;
1435 myAnalyse.TangentEdges(E,V1f,TangE);
1436 // find if the pipe on the tangent edges are soon created.
1437 TopTools_ListIteratorOfListOfShape itl(TangE);
1438 Standard_Boolean Find = Standard_False;
1439 for ( ; itl.More() && !Find; itl.Next()) {
1440 if ( MapSF.IsBound(itl.Value())) {
1441 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
1442 E1f = TopoDS::Edge(aLocalShape);
1443 // E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
1444 Find = Standard_True;
1448 myAnalyse.TangentEdges(E,V1l,TangE);
1449 // find if the pipe on the tangent edges are soon created.
1450 itl.Initialize(TangE);
1451 Find = Standard_False;
1452 for ( ; itl.More() && !Find; itl.Next()) {
1453 if ( MapSF.IsBound(itl.Value())) {
1454 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
1455 E1l = TopoDS::Edge(aLocalShape);
1456 // E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
1457 Find = Standard_True;
1460 BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
1465 // ----------------------
1467 // ----------------------
1468 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1469 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1470 /// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1471 myInitOffsetEdge.SetRoot(E); // skv: supporting history.
1472 myInitOffsetEdge.Bind (E,EOn1);
1477 //--------------------------------------------------------
1478 // Construction of spheres on vertex.
1479 //--------------------------------------------------------
1481 TopTools_ListIteratorOfListOfShape it;
1483 for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
1484 const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
1486 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
1487 TopTools_ListOfShape LE;
1488 myAnalyse.Edges(V,OT,LE);
1490 if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
1491 TopTools_ListOfShape LOE;
1492 //--------------------------------------------------------
1493 // Return connected edges on tubes.
1494 //--------------------------------------------------------
1495 for (it.Initialize(LE) ; it.More(); it.Next()) {
1496 LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
1498 //----------------------
1499 // construction sphere.
1500 //-----------------------
1501 const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
1502 const TopoDS_Shape& FF = LLA.First();
1503 Standard_Real CurOffset = myOffset;
1504 if ( myFaceOffset.IsBound(FF))
1505 CurOffset = myFaceOffset(FF);
1507 BRepOffset_Offset OF(V,LOE,CurOffset);
1510 //--------------------------------------------------------------
1511 // Particular processing if V is at least a free border.
1512 //-------------------------------------------------------------
1513 TopTools_ListOfShape LBF;
1514 myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
1515 if (!LBF.IsEmpty()) {
1516 Standard_Boolean First = Standard_True;
1517 for (it.Initialize(LE) ; it.More(); it.Next()) {
1519 myInitOffsetEdge.SetRoot(V); // skv: supporting history.
1520 myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
1521 First = Standard_False;
1524 myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
1531 //------------------------------------------------------------
1532 // Extension of parallel faces to the context.
1533 // Extended faces are ordered in DS and removed from MapSF.
1534 //------------------------------------------------------------
1535 if (!myFaces.IsEmpty()) ToContext (MapSF);
1537 //------------------------------------------------------
1539 //------------------------------------------------------
1540 BRepOffset_Type RT = BRepOffset_Concave;
1541 if (myOffset < 0.) RT = BRepOffset_Convex;
1542 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
1544 Standard_Integer MapSFNb = MapSF.Extent();
1546 for ( ; It.More(); It.Next()) {
1547 const TopoDS_Shape& SI = It.Key();
1548 const BRepOffset_Offset& SF = It.Value();
1549 if (SF.Status() == BRepOffset_Reversed ||
1550 SF.Status() == BRepOffset_Degenerated ) {
1551 //------------------------------------------------
1552 // Degenerated or returned faces are not stored.
1553 //------------------------------------------------
1557 const TopoDS_Face& OF = It.Value().Face();
1558 myInitOffsetFace.Bind (SI,OF);
1559 myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
1560 myImageOffset.SetRoot (OF); // FaceOffset root of images
1562 if (SI.ShapeType() == TopAbs_FACE) {
1563 for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1564 Exp.More(); Exp.Next()) {
1565 //--------------------------------------------------------------------
1566 // To each face are associatedthe edges that restrict that
1567 // The edges that do not generate tubes or are not tangent
1568 // to two faces are removed.
1569 //--------------------------------------------------------------------
1570 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1571 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1572 if (!L.IsEmpty() && L.First().Type() != RT) {
1573 TopAbs_Orientation OO = E.Orientation();
1574 TopoDS_Shape aLocalShape = It.Value().Generated(E);
1575 TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
1576 // TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
1577 myAsDes->Add (OF,OE.Oriented(OO));
1582 for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1583 Exp.More(); Exp.Next()) {
1584 myAsDes->Add (OF,Exp.Current());
1590 if ( ChronBuild) Clock.Show();
1596 //=======================================================================
1597 //function : SelfInter
1599 //=======================================================================
1601 void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& Modif)
1605 cout << " AUTODEBOUCLAGE:" << endl;
1611 Standard_NotImplemented::Raise();
1614 if ( ChronBuild) Clock.Show();
1619 //=======================================================================
1620 //function : ToContext
1622 //=======================================================================
1624 void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
1626 TopTools_DataMapOfShapeShape Created;
1627 TopTools_DataMapOfShapeShape MEF;
1628 TopTools_MapOfShape FacesToBuild;
1629 TopTools_MapIteratorOfMapOfShape it(myFaces);
1630 TopTools_ListIteratorOfListOfShape itl;
1631 TopExp_Explorer exp;
1633 // TopAbs_State Side = TopAbs_IN;
1634 // if (myOffset < 0.) Side = TopAbs_OUT;
1636 TopAbs_State Side = TopAbs_OUT;
1638 for (; it.More(); it.Next()) {
1639 const TopoDS_Face& CF = TopoDS::Face(it.Key());
1640 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1641 exp.More(); exp.Next()) {
1642 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1643 if (!myAnalyse.HasAncestor(E)) {
1644 //----------------------------------------------------------------
1645 // The edges of context faces that are not in the initial shape
1646 // can appear in the result.
1647 //----------------------------------------------------------------
1648 //myAsDes->Add(CF,E);
1652 //-------------------------------------------------------
1653 // Determine the edges and faces reconstructed by
1655 //---------------------------------------------------------
1656 for ( it.Initialize(myFaces); it.More(); it.Next()) {
1657 const TopoDS_Face& CF = TopoDS::Face(it.Key());
1658 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1659 exp.More(); exp.Next()) {
1660 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1661 if (myAnalyse.HasAncestor(E)) {
1662 const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
1663 for (itl.Initialize(LEA); itl.More(); itl.Next()) {
1664 const BRepOffset_Offset& OF = MapSF(itl.Value());
1665 FacesToBuild.Add(itl.Value());
1666 MEF.Bind(OF.Generated(E),CF);
1669 TopExp::Vertices(E,V[0],V[1]);
1670 for (Standard_Integer i = 0; i < 2; i++) {
1671 const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]);
1672 for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
1673 const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
1674 if (MapSF.IsBound(EV)) {
1675 const BRepOffset_Offset& OF = MapSF(EV);
1676 FacesToBuild.Add(EV);
1677 MEF.Bind(OF.Generated(V[i]),CF);
1684 //---------------------------
1685 // Reconstruction of faces.
1686 //---------------------------
1688 BRepOffset_Type RT = BRepOffset_Concave;
1689 if (myOffset < 0.) RT = BRepOffset_Convex;
1691 TopAbs_Orientation Or;
1693 for (it.Initialize(FacesToBuild); it.More(); it.Next()) {
1694 const TopoDS_Shape& S = it.Key();
1695 BRepOffset_Offset BOF;
1697 F = TopoDS::Face(BOF.Face());
1698 BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
1703 myInitOffsetFace.Bind (S,NF);
1704 myInitOffsetFace.SetRoot (S); // Initial<-> Offset
1705 myImageOffset.SetRoot (NF);
1707 if (S.ShapeType() == TopAbs_FACE) {
1708 for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1709 exp.More(); exp.Next()) {
1711 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1712 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1713 OE = BOF.Generated(E);
1714 Or = E.Orientation();
1716 if (!L.IsEmpty() && L.First().Type() != RT) {
1717 if (Created.IsBound(OE)) {
1719 if (NE.Orientation() == TopAbs_REVERSED)
1720 NE.Orientation(TopAbs::Reverse(Or));
1723 myAsDes->Add(NF,NE);
1726 myAsDes->Add(NF,OE);
1732 //------------------
1734 //---------------------
1735 for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1736 exp.More(); exp.Next()) {
1737 myAsDes->Add (NF,exp.Current());
1743 //------------------
1745 //------------------
1746 TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
1747 for (itc.Initialize(Created); itc.More(); itc.Next()) {
1750 if (myInitOffsetEdge.IsImage(OE)) {
1751 TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
1752 Or = myInitOffsetEdge.Image(E).First().Orientation();
1753 if (NE.Orientation() == TopAbs_REVERSED)
1754 NE.Orientation(TopAbs::Reverse(Or));
1757 myInitOffsetEdge.Remove(OE);
1758 myInitOffsetEdge.Bind(E,NE);
1764 //=======================================================================
1765 //function : UpdateFaceOffset
1767 //=======================================================================
1769 void BRepOffset_MakeOffset::UpdateFaceOffset()
1771 TopTools_MapOfShape M;
1772 TopTools_DataMapOfShapeReal CopiedMap;
1773 CopiedMap.Assign(myFaceOffset);
1774 TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
1776 BRepOffset_Type RT = BRepOffset_Convex;
1777 if (myOffset < 0.) RT = BRepOffset_Concave;
1779 for ( ; it.More(); it.Next()) {
1780 const TopoDS_Face& F = TopoDS::Face(it.Key());
1781 Standard_Real CurOffset = CopiedMap(F);
1782 if ( !M.Add(F)) continue;
1785 Build.MakeCompound(Co);
1786 TopTools_MapOfShape Dummy;
1788 if (myJoin == GeomAbs_Arc)
1789 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
1791 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
1793 TopExp_Explorer exp(Co,TopAbs_FACE);
1794 for (; exp.More(); exp.Next()) {
1795 const TopoDS_Face& FF = TopoDS::Face(exp.Current());
1796 if ( !M.Add(FF)) continue;
1797 if ( myFaceOffset.IsBound(FF))
1798 myFaceOffset.UnBind(FF);
1799 myFaceOffset.Bind(FF,CurOffset);
1804 //=======================================================================
1805 //function : CorrectConicalFaces
1807 //=======================================================================
1809 void BRepOffset_MakeOffset::CorrectConicalFaces()
1811 TopTools_SequenceOfShape Cones;
1812 TopTools_SequenceOfShape Circs;
1813 TopTools_SequenceOfShape Seams;
1814 Standard_Real TolApex = 1.e-5;
1818 TopTools_DataMapOfShapeListOfShape FacesOfCone;
1819 //TopTools_DataMapOfShapeShape DegEdges;
1820 TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
1821 if (myJoin == GeomAbs_Arc)
1823 for (; Explo.More(); Explo.Next())
1825 TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
1826 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
1827 //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
1828 //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
1830 TopTools_IndexedMapOfShape Emap;
1831 TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
1832 for (i = 1; i <= Emap.Extent(); i++)
1834 TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
1835 //Standard_Real f, l;
1836 //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
1837 //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
1838 if (BRep_Tool::Degenerated(anEdge))
1840 //Check if anEdge is a really degenerated edge or not
1841 BRepAdaptor_Curve BACurve(anEdge, aFace);
1842 gp_Pnt Pfirst, Plast, Pmid;
1843 Pfirst = BACurve.Value(BACurve.FirstParameter());
1844 Plast = BACurve.Value(BACurve.LastParameter());
1845 Pmid = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
1846 if (Pfirst.Distance(Plast) <= TolApex &&
1847 Pfirst.Distance(Pmid) <= TolApex)
1849 //Cones.Append( aFace );
1850 //Circs.Append( anEdge );
1851 //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
1852 TopoDS_Edge OrEdge =
1853 TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
1854 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1855 if ( FacesOfCone.IsBound(VF) )
1857 //add a face to the existing list
1858 TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
1859 aFaces.Append (aFace);
1860 //DegEdges.Bind(aFace, anEdge);
1864 //the vertex is not in the map => create a new key and items
1865 TopTools_ListOfShape aFaces;
1866 aFaces.Append (aFace);
1867 FacesOfCone.Bind(VF, aFaces);
1868 //DegEdges.Bind(aFace, anEdge);
1871 } //for (i = 1; i <= Emap.Extent(); i++)
1872 } //for (; fexp.More(); fexp.Next())
1873 } //if (myJoin == GeomAbs_Arc)
1875 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
1878 for (; Cone.More(); Cone.Next() ) {
1879 gp_Sphere theSphere;
1880 Handle(Geom_SphericalSurface) aSphSurf;
1881 TopoDS_Wire SphereWire;
1882 BB.MakeWire(SphereWire);
1883 TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
1884 const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
1885 TopTools_ListIteratorOfListOfShape itFaces(Faces);
1886 Standard_Boolean isFirstFace = Standard_True;
1888 TopoDS_Vertex theFirstVertex, CurFirstVertex;
1889 for (; itFaces.More(); itFaces.Next())
1891 TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
1892 TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
1893 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
1895 DegEdge = TopoDS::Edge(Explo.Current());
1896 if (BRep_Tool::Degenerated(DegEdge))
1898 TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
1899 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1900 if (VF.IsSame(anApex))
1904 TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
1905 TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
1906 BB.Degenerated(CurEdge, Standard_False);
1907 BB.SameRange(CurEdge, Standard_False);
1908 BB.SameParameter(CurEdge, Standard_False);
1909 gp_Pnt fPnt, lPnt, mPnt;
1910 GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
1912 BRep_Tool::Range(CurEdge, f, l);
1915 gp_Vec aVec1(fPnt, mPnt);
1916 gp_Vec aVec2(fPnt, lPnt);
1917 gp_Vec aNorm = aVec1.Crossed(aVec2);
1918 gp_Pnt theApex = BRep_Tool::Pnt(anApex);
1919 gp_Vec ApexToFpnt(theApex, fPnt);
1920 gp_Vec Ydir = aNorm ^ ApexToFpnt;
1921 gp_Vec Xdir = Ydir ^ aNorm;
1922 //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
1923 gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
1924 theSphere.SetRadius(myOffset);
1925 theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
1926 aSphSurf = new Geom_SphericalSurface(theSphere);
1928 theFirstVertex = BRepLib_MakeVertex(fPnt);
1929 CurFirstVertex = theFirstVertex;
1932 TopoDS_Vertex v1, v2, FirstVert, EndVert;
1933 TopExp::Vertices(CurEdge, v1, v2);
1934 FirstVert = CurFirstVertex;
1935 if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
1936 EndVert = theFirstVertex;
1938 EndVert = BRepLib_MakeVertex(lPnt);
1939 CurEdge.Free( Standard_True );
1940 BB.Remove(CurEdge, v1);
1941 BB.Remove(CurEdge, v2);
1942 BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
1943 BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
1944 //take the curve from sphere an put it to the edge
1945 Standard_Real Uf, Vf, Ul, Vl;
1946 ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
1947 ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
1948 if (Abs(Ul) <= Precision::Confusion())
1950 Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
1954 gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
1955 if (Abs(Uf - f) > Precision::Confusion())
1957 aCircle.Rotate(aCircle.Axis(), f - Uf);
1958 aCurv = new Geom_Circle(aCircle);
1962 Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
1963 BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
1964 BB.Range(CurEdge, Uf, Ul, Standard_True);
1965 Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
1966 Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
1967 BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
1968 BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
1969 BRepLib::SameParameter(CurEdge);
1970 BB.Add(SphereWire, CurEdge);
1971 //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
1972 BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
1973 gp_Pnt2d fPnt2d, lPnt2d;
1974 fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
1975 lPnt2d = BAc2d.Value(BAc2d.LastParameter());
1976 TopTools_IndexedMapOfShape Emap;
1977 TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
1979 Standard_Integer j = 0, k;
1980 for (k = 1; k <= Emap.Extent(); k++)
1982 const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
1983 if (!BRep_Tool::Degenerated(anEdge))
1985 TopoDS_Vertex V1, V2;
1986 TopExp::Vertices(anEdge, V1, V2);
1987 if (V1.IsSame(v1) || V2.IsSame(v1))
1991 for (k = 0; k < j; k++)
1993 TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
1994 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
1995 Eforward.Free(Standard_True);
1996 TopoDS_Vertex V1, V2;
1997 TopExp::Vertices( Eforward, V1, V2 );
1998 BRepAdaptor_Curve2d EEc( Eforward, aFace );
1999 gp_Pnt2d p2d1, p2d2;
2000 p2d1 = EEc.Value(EEc.FirstParameter());
2001 p2d2 = EEc.Value(EEc.LastParameter());
2004 TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
2005 FirstVert : EndVert;
2006 BB.Remove( Eforward, V1 );
2007 BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
2011 TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
2012 FirstVert : EndVert;
2013 BB.Remove( Eforward, V2 );
2014 BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
2018 isFirstFace = Standard_False;
2019 CurFirstVertex = EndVert;
2021 //Building new spherical face
2022 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2023 gp_Pnt2d p2d1, p2d2;
2024 TopTools_ListOfShape EdgesOfWire;
2025 TopoDS_Iterator itw(SphereWire);
2026 for (; itw.More(); itw.Next())
2028 const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
2029 EdgesOfWire.Append(anEdge);
2031 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
2032 p2d1 = aC2d->Value(f);
2033 p2d2 = aC2d->Value(l);
2034 if (p2d1.X() < Ufirst)
2036 if (p2d1.X() > Ulast)
2038 if (p2d2.X() < Ufirst)
2040 if (p2d2.X() > Ulast)
2043 TopTools_ListOfShape NewEdges;
2044 TopoDS_Edge FirstEdge;
2045 TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
2046 for (; itl.More(); itl.Next())
2048 FirstEdge = TopoDS::Edge(itl.Value());
2050 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
2051 p2d1 = aC2d->Value(f);
2052 p2d2 = aC2d->Value(l);
2053 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
2055 EdgesOfWire.Remove(itl);
2059 NewEdges.Append(FirstEdge);
2060 TopoDS_Vertex Vf1, CurVertex;
2061 TopExp::Vertices(FirstEdge, Vf1, CurVertex);
2062 itl.Initialize(EdgesOfWire);
2065 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2066 TopoDS_Vertex V1, V2;
2067 TopExp::Vertices(anEdge, V1, V2);
2068 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
2070 NewEdges.Append(anEdge);
2071 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2072 EdgesOfWire.Remove(itl);
2078 Standard_Real Vfirst, Vlast;
2081 Vfirst = p2d1.Y(); Vlast = PI/2.;
2085 Vfirst = -PI/2.; Vlast = p2d1.Y();
2087 TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
2088 TopoDS_Edge OldEdge;
2089 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2091 OldEdge = TopoDS::Edge(Explo.Current());
2092 if (!BRep_Tool::Degenerated(OldEdge))
2094 BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
2095 p2d1 = BAc2d.Value(BAc2d.FirstParameter());
2096 p2d2 = BAc2d.Value(BAc2d.LastParameter());
2097 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
2098 Abs(p2d2.X() - Ulast) <= Precision::Confusion())
2102 TopoDS_Vertex V1, V2;
2103 TopExp::Vertices(OldEdge, V1, V2);
2104 TopTools_ListOfShape LV1, LV2;
2106 LV2.Append(CurVertex);
2107 BRepTools_Substitution theSubstitutor;
2108 theSubstitutor.Substitute(V1, LV1);
2110 theSubstitutor.Substitute(V2, LV2);
2111 theSubstitutor.Substitute(OldEdge, NewEdges);
2112 theSubstitutor.Build(NewSphericalFace);
2113 if (theSubstitutor.IsCopied(NewSphericalFace))
2115 const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
2116 NewSphericalFace = TopoDS::Face(listSh.First());
2119 //Adding NewSphericalFace to the shell
2120 Explo.Init( myOffsetShape, TopAbs_SHELL );
2121 TopoDS_Shape theShell = Explo.Current();
2122 theShell.Free( Standard_True );
2123 BB.Add( theShell, NewSphericalFace );
2126 Explo.Init( myOffsetShape, TopAbs_SHELL );
2129 TopoDS_Shape theShell = Explo.Current();
2130 theShell.Closed( Standard_True );
2136 for (i = 1; i <= Cones.Length(); i++)
2138 TopoDS_Face Cone = TopoDS::Face( Cones(i) );
2139 TopoDS_Edge Circ = TopoDS::Edge( Circs(i) );
2140 TopoDS_Edge Seam = TopoDS::Edge( Seams(i) );
2141 if (Circ.IsNull()) //case 1 with big offset
2143 //ExtraFace is absent
2145 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2147 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2148 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2149 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2150 gp_Pnt apex = theCone.Apex();
2151 Standard_Real Uapex, Vapex;
2152 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2153 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2154 apex = OffSurf->Value( Uapex, Vapex );
2156 //Making new degenerated edge
2157 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*PI, Vapex ) );
2158 TopoDS_Edge NewEdge;
2159 BB.MakeEdge( NewEdge );
2160 NewEdge.Orientation(TopAbs_FORWARD);
2161 BB.UpdateEdge( NewEdge, theLine, Cone, Precision::Confusion() );
2162 BB.Range( NewEdge, 0., 2.*PI );
2163 BB.SameParameter( NewEdge, Standard_True );
2164 BB.SameRange( NewEdge, Standard_True );
2165 BB.Degenerated( NewEdge, Standard_True );
2166 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2167 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2168 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2170 //Reconstructing Seam
2171 Standard_Real f, l, par, cpar;
2172 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2173 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2174 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2175 TopoDS_Shape aLocalShape = Seam.Oriented(TopAbs_FORWARD);
2176 TopoDS_Vertex cver = TopExp::LastVertex( TopoDS::Edge(aLocalShape) );
2177 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2178 if (Abs(f-cpar) < Abs(l-cpar))
2179 BB.Range( Seam, par, l );
2181 BB.Range( Seam, f, par );
2182 Seam.Free( Standard_True );
2184 TopoDS_Iterator iter( Seam );
2185 for (; iter.More(); iter.Next())
2187 cver1 = iter.Value();
2188 if (cver1.IsSame(cver))
2191 BB.Remove( Seam, cver1 );
2192 if (Abs(f-cpar) < Abs(l-cpar))
2193 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2195 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2197 //Adding NewEdge into Cone
2198 TopoDS_Shape theWire;
2199 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2201 theWire = fexp.Current();
2202 Standard_Boolean found = Standard_False;
2203 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2205 if (Seam.IsSame( iter.Value() ))
2207 found = Standard_True;
2214 theWire.Free( Standard_True );
2215 NewEdge.Orientation( TopAbs::Compose(theWire.Orientation(),TopAbs_REVERSED) );
2216 BB.Add( theWire, NewEdge );
2217 } //end of case 1 with big offset
2220 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Circ.TShape());
2221 if (! TE->Degenerated()) //case 1
2224 TopoDS_Face ExtraFace;
2225 for (fexp.Init( myOffsetShape, TopAbs_FACE ); fexp.More(); fexp.Next())
2227 ExtraFace = TopoDS::Face( fexp.Current() );
2228 if (ExtraFace.IsSame( Cone ))
2230 Standard_Boolean found = Standard_False;
2231 TopExp_Explorer eexp( ExtraFace, TopAbs_EDGE );
2232 for (; eexp.More(); eexp.Next())
2233 if (Circ.IsSame( eexp.Current() ))
2235 found = Standard_True;
2242 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2243 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2244 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2245 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2246 gp_Pnt apex = theCone.Apex();
2247 Standard_Real Uapex, Vapex;
2248 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2249 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2250 apex = OffSurf->Value( Uapex, Vapex );
2252 //Making new degenerated edge
2253 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*PI, Vapex ) );
2254 TopoDS_Edge NewEdge;
2255 BB.MakeEdge( NewEdge );
2256 NewEdge.Orientation(TopAbs_FORWARD);
2257 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
2258 BB.Range( NewEdge, 0., 2.*PI );
2259 BB.SameParameter( NewEdge, Standard_True );
2260 BB.SameRange( NewEdge, Standard_True );
2261 BB.Degenerated( NewEdge, Standard_True );
2262 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2263 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2264 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2266 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2268 //Reconstructing Seam
2269 Standard_Real f, l, par, cpar;
2270 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2271 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2272 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2273 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2274 if (Abs(f-cpar) < Abs(l-cpar))
2275 BB.Range( Seam, par, l );
2277 BB.Range( Seam, f, par );
2278 Seam.Free( Standard_True );
2280 TopoDS_Iterator iter( Seam );
2281 for (; iter.More(); iter.Next())
2283 cver1 = iter.Value();
2284 if (cver1.IsSame(cver))
2287 BB.Remove( Seam, cver1 );
2288 if (Abs(f-cpar) < Abs(l-cpar))
2289 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2291 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2293 //Removing ExtraFace from the shell
2294 fexp.Init( myOffsetShape, TopAbs_SHELL );
2295 TopoDS_Shape theShell = fexp.Current();
2296 theShell.Free( Standard_True );
2297 TopoDS_Shape ExtraFace1;
2298 for (iter.Initialize( theShell ); iter.More(); iter.Next())
2300 ExtraFace1 = iter.Value();
2301 if (ExtraFace1.IsSame(ExtraFace))
2304 BB.Remove( theShell, ExtraFace1 );
2306 //Substitute Circ by NewEdge in Cone
2307 TopoDS_Shape theWire;
2309 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2311 theWire = fexp.Current();
2312 Standard_Boolean found = Standard_False;
2313 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2315 Circ1 = iter.Value();
2316 if (Circ1.IsSame(Circ))
2318 found = Standard_True;
2325 TopAbs_Orientation Or = Circ1.Orientation();
2326 theWire.Free( Standard_True );
2327 BB.Remove( theWire, Circ1 );
2328 BB.Add( theWire, NewEdge.Oriented(Or) );
2330 else // Circ is degenerated
2332 if (myOffset > 0. && myJoin == GeomAbs_Arc) //case 2
2334 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2336 TopoDS_Face OrCone = TopoDS::Face( myInitOffsetFace.Root( Cone ) );
2337 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( OrCone ), OffSurf = aSurf;
2338 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2339 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2340 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2341 gp_Pnt apex = theCone.Apex();
2342 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2344 Standard_Real Uapex, Vapex;
2345 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2346 apex = OffSurf->Value( Uapex, Vapex );
2350 Handle(Geom_Curve) ccur = BRep_Tool::Curve( Circ, f, l );
2351 gp_Ax2 Axe2 = (Handle(Geom_Circle)::DownCast(ccur))->Circ().Position();
2352 gp_Ax3 Axe3( Axe2 );
2353 Axe3.SetLocation( apex );
2354 gp_Sphere theSphere( Axe3, myOffset );
2356 gp_Pnt OrPnt = BRep_Tool::Pnt(cver);
2357 Standard_Real Uor, Vor;
2358 ElSLib::Parameters( theSphere, OrPnt, Uor, Vor );
2359 TopoDS_Face NewFace;
2361 NewFace = BRepLib_MakeFace( theSphere, 0., 2.*PI, Vor, PI/2. );
2363 NewFace = BRepLib_MakeFace( theSphere, 0., 2.*PI, -PI/2., Vor );
2365 //Updating the bound of NewFace
2367 TopExp_Explorer eexp( NewFace, TopAbs_EDGE );
2368 for (; eexp.More(); eexp.Next())
2370 Bound = TopoDS::Edge( eexp.Current() );
2371 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Bound.TShape());
2372 if (!TE->Degenerated() && !BRepTools::IsReallyClosed( Bound, NewFace ))
2375 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( Circ, Cone, f, l );
2376 BB.UpdateEdge( Bound, pcurve, Cone, BRep_Tool::Tolerance(Circ) );
2377 TopoDS_Vertex bver = TopExp::FirstVertex( Bound );
2378 BB.UpdateVertex( bver, BRep_Tool::Tolerance(cver) );
2380 //Updating cver in Seam
2381 TopoDS_Vertex cver1;
2382 TopoDS_Iterator iter( Seam );
2383 for (; iter.More(); iter.Next())
2385 cver1 = TopoDS::Vertex( iter.Value() );
2386 if (cver1.IsSame(cver))
2389 TopAbs_Orientation Or = cver1.Orientation();
2390 Seam.Free( Standard_True );
2391 BB.Remove( Seam, cver1 );
2392 BB.Add( Seam, bver.Oriented(Or) );
2394 //Substitute Circ by Bound in Cone
2395 TopoDS_Shape theWire;
2397 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2399 theWire = fexp.Current();
2400 Standard_Boolean found = Standard_False;
2401 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2403 Circ1 = iter.Value();
2404 if (Circ1.IsSame(Circ))
2406 found = Standard_True;
2413 Or = Circ1.Orientation();
2414 theWire.Free( Standard_True );
2415 BB.Remove( theWire, Circ1 );
2416 BB.Add( theWire, Bound.Oriented(Or) );
2418 //Adding NewFace to the shell
2419 fexp.Init( myOffsetShape, TopAbs_SHELL );
2420 TopoDS_Shape theShell = fexp.Current();
2421 theShell.Free( Standard_True );
2422 BB.Add( theShell, NewFace );
2424 theShell.Closed( Standard_True );
2426 else // if ((myOffset > 0. && myJoin == GeomAbs_Intersection) || myOffset < 0.) //case 3, 4
2428 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2429 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2430 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2431 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2432 gp_Pnt apex = theCone.Apex();
2433 Standard_Real Uapex, Vapex;
2434 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2435 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2436 apex = OffSurf->Value( Uapex, Vapex );
2438 //Making new degenerated edge
2439 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*PI, Vapex ) );
2440 TopoDS_Edge NewEdge;
2441 BB.MakeEdge( NewEdge );
2442 NewEdge.Orientation(TopAbs_FORWARD);
2443 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
2444 BB.Range( NewEdge, 0., 2.*PI );
2445 BB.SameParameter( NewEdge, Standard_True );
2446 BB.SameRange( NewEdge, Standard_True );
2447 BB.Degenerated( NewEdge, Standard_True );
2448 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2449 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2450 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2452 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2454 //Reconstructing Seam
2455 Standard_Real f, l, par, cpar;
2456 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2457 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2458 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2459 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2460 if (Abs(f-cpar) < Abs(l-cpar))
2461 BB.Range( Seam, par, l );
2463 BB.Range( Seam, f, par );
2464 Seam.Free( Standard_True );
2466 TopoDS_Iterator iter( Seam );
2467 for (; iter.More(); iter.Next())
2469 cver1 = iter.Value();
2470 if (cver1.IsSame(cver))
2473 BB.Remove( Seam, cver1 );
2474 if (Abs(f-cpar) < Abs(l-cpar))
2475 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2477 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2479 //Substitute Circ by NewEdge in Cone
2480 TopoDS_Shape theWire;
2482 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2484 theWire = fexp.Current();
2485 Standard_Boolean found = Standard_False;
2486 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2488 Circ1 = iter.Value();
2489 if (Circ1.IsSame(Circ))
2491 found = Standard_True;
2498 TopAbs_Orientation Or = Circ1.Orientation();
2499 theWire.Free( Standard_True );
2500 BB.Remove( theWire, Circ1 );
2501 BB.Add( theWire, NewEdge.Oriented(Or) );
2503 fexp.Init( myOffsetShape, TopAbs_SHELL );
2504 TopoDS_Shape theShell = fexp.Current();
2505 theShell.Closed( Standard_True );
2506 } //end of case 3, 4
2508 } //else (! Circ.IsNull())
2512 Standard_Integer NbShell = 0;
2515 BB.MakeCompound (NC);
2517 for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
2518 const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
2524 Sol.Closed(Standard_True);
2526 if (NbShell == 1) S1 = Sol;
2530 if (NbShell == 1) S1 = Sh;
2533 if (NbShell == 1) myOffsetShape = S1;
2534 else myOffsetShape = NC;
2538 //=======================================================================
2539 //function : Intersection3D
2541 //=======================================================================
2543 void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
2547 cout << " INTERSECTION 3D:" << endl;
2552 TopTools_ListOfShape OffsetFaces; // list of faces // created.
2553 MakeList (OffsetFaces,myInitOffsetFace,myFaces);
2555 if (!myFaces.IsEmpty()) {
2556 Standard_Boolean InSide = (myOffset < 0.); // Temporary
2557 // it is necessary to calculate Inside taking account of the concavity or convexity of edges
2558 // between the cap and the part.
2560 if (myJoin == GeomAbs_Arc)
2561 Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
2567 Inter.CompletInt (OffsetFaces,myInitOffsetFace);
2568 TopTools_MapOfShape& NewEdges = Inter.NewEdges();
2569 if (myJoin == GeomAbs_Intersection) {
2570 BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
2574 //--------------------------------
2575 // Only between neighbor faces.
2576 //--------------------------------
2577 Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
2580 if ( ChronBuild) Clock.Show();
2584 //=======================================================================
2585 //function : Intersection2D
2587 //=======================================================================
2589 void BRepOffset_MakeOffset::Intersection2D(const TopTools_MapOfShape& Modif,
2590 const TopTools_MapOfShape& NewEdges)
2594 cout << " INTERSECTION 2D:" << endl;
2599 //--------------------------------------------------------
2600 // calculate intersections2d on faces concerned by
2602 //--------------------------------------------------------
2603 TopTools_MapIteratorOfMapOfShape it(Modif);
2604 //-----------------------------------------------
2605 // Intersection of edges 2 by 2.
2606 //-----------------------------------------------
2607 for ( it.Initialize(Modif); it.More(); it.Next()) {
2608 const TopoDS_Face& F = TopoDS::Face(it.Key());
2609 BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
2614 DEBVerticesControl (NewEdges,myAsDes);
2616 if ( ChronBuild) Clock.Show();
2621 //=======================================================================
2622 //function : MakeLoops
2624 //=======================================================================
2626 void BRepOffset_MakeOffset::MakeLoops(TopTools_MapOfShape& Modif)
2630 cout << " DEBOUCLAGE 2D:" << endl;
2635 TopTools_MapIteratorOfMapOfShape it(Modif);
2636 TopTools_ListOfShape LF,LC;
2637 //-----------------------------------------
2638 // unwinding of faces // modified.
2639 //-----------------------------------------
2640 for (; it.More(); it.Next()) {
2641 if (!myFaces.Contains(it.Key())) LF.Append(it.Key());
2643 myMakeLoops.Build(LF,myAsDes,myImageOffset);
2645 //-----------------------------------------
2646 // unwinding of caps.
2647 //-----------------------------------------
2648 for (it.Initialize(myFaces); it.More(); it.Next()) {
2649 LC.Append(it.Key());
2651 Standard_Boolean InSide = 1;
2652 if (myOffset > 0 ) InSide = 0;
2653 myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
2656 if ( ChronBuild) Clock.Show();
2660 //=======================================================================
2661 //function : MakeFaces
2662 //purpose : Reconstruction of topologically unchanged faces that
2663 // share edges that were reconstructed.
2664 //=======================================================================
2666 void BRepOffset_MakeOffset::MakeFaces(TopTools_MapOfShape& Modif)
2670 cout << " RECONSTRUCTION OF FACES:" << endl;
2675 TopTools_ListIteratorOfListOfShape itr;
2676 const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
2677 TopTools_ListOfShape LOF;
2678 //----------------------------------
2679 // Loop on all faces //.
2680 //----------------------------------
2681 for (itr.Initialize(Roots); itr.More(); itr.Next()) {
2682 TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
2685 myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
2688 if ( ChronBuild) Clock.Show();
2692 //=======================================================================
2693 //function : UpdateInitOffset
2694 //purpose : Update and cleaning of myInitOffset
2695 //=======================================================================
2697 static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
2698 BRepAlgo_Image& myImageOffset,
2699 const TopoDS_Shape& myOffsetShape,
2700 const TopAbs_ShapeEnum &theShapeType) // skv
2702 BRepAlgo_Image NIOF;
2703 const TopTools_ListOfShape& Roots = myInitOffset.Roots();
2704 TopTools_ListIteratorOfListOfShape it(Roots);
2705 for (; it.More(); it.Next()) {
2706 NIOF.SetRoot (it.Value());
2708 for (it.Initialize(Roots); it.More(); it.Next()) {
2709 const TopoDS_Shape& SI = it.Value();
2710 TopTools_ListOfShape LI;
2711 TopTools_ListOfShape L1;
2712 myInitOffset.LastImage(SI,L1);
2713 TopTools_ListIteratorOfListOfShape itL1(L1);
2714 for (; itL1.More(); itL1.Next()) {
2715 const TopoDS_Shape& O1 = itL1.Value();
2716 TopTools_ListOfShape L2;
2717 myImageOffset.LastImage(O1,L2);
2722 // Modified by skv - Mon Apr 4 18:17:27 2005 Begin
2723 // Supporting history.
2724 // NIOF.Filter(myOffsetShape,TopAbs_FACE);
2725 NIOF.Filter(myOffsetShape, theShapeType);
2726 // Modified by skv - Mon Apr 4 18:17:27 2005 End
2727 myInitOffset = NIOF;
2730 //=======================================================================
2731 //function : MakeMissingWalls
2733 //=======================================================================
2735 void BRepOffset_MakeOffset::MakeMissingWalls ()
2737 TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
2738 TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
2739 Standard_Real OffsetVal = Abs(myOffset);
2741 FillContours(myShape, myAnalyse, Contours, MapEF);
2743 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
2744 for (; iter.More(); iter.Next())
2746 TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
2747 TopoDS_Edge StartEdge;
2748 const TopTools_ListOfShape& aContour = iter.Value();
2749 TopTools_ListIteratorOfListOfShape itl(aContour);
2750 Standard_Boolean FirstStep = Standard_True;
2751 TopoDS_Edge PrevEdge;
2752 TopoDS_Vertex PrevVertex = StartVertex;
2753 for (; itl.More(); itl.Next())
2755 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
2756 if (!myInitOffsetEdge.HasImage(anEdge))
2758 //if (BRep_Tool::Degenerated(anEdge))
2760 TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
2761 //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
2762 TopTools_ListOfShape LOE, LOE2;
2763 myInitOffsetEdge.LastImage( anEdge, LOE );
2764 myImageOffset.LastImage( LOE.Last(), LOE2 );
2765 TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
2766 ////////////////////////////////////////////////////////////////////////
2767 TopoDS_Vertex V1, V2, V3, V4;
2768 TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
2769 TopExp::Vertices(OE, V4, V3/*, Standard_True*/);
2770 Standard_Boolean ToReverse = Standard_False;
2771 if (!V1.IsSame(PrevVertex))
2773 TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
2774 aVtx = V3; V3 = V4; V4 = aVtx;
2775 ToReverse = Standard_True;
2779 OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
2783 E4 = BRepLib_MakeEdge( V1, V4 );
2788 Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
2789 if (V2.IsSame(StartVertex) && !ArcOnV2)
2792 E3 = BRepLib_MakeEdge( V2, V3 );
2794 TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
2795 const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
2796 Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
2797 Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
2799 TopoDS_Wire theWire;
2800 BB.MakeWire(theWire);
2803 BB.Add(theWire, anEdge.Reversed());
2804 BB.Add(theWire, E3.Reversed());
2805 BB.Add(theWire, OE.Reversed());
2806 BB.Add(theWire, E4.Reversed());
2810 BB.Add(theWire, anEdge);
2811 BB.Add(theWire, E3);
2812 BB.Add(theWire, OE);
2813 BB.Add(theWire, E4);
2815 BRepLib::BuildCurves3d( theWire, myTol );
2816 theWire.Closed(Standard_True);
2817 TopoDS_Face NewFace;
2818 Handle(Geom_Surface) theSurf;
2819 BRepAdaptor_Curve BAcurve(anEdge);
2820 BRepAdaptor_Curve BAcurveOE(OE);
2821 Standard_Real fpar = BAcurve.FirstParameter();
2822 Standard_Real lpar = BAcurve.LastParameter();
2823 gp_Pnt PonE = BAcurve.Value(fpar);
2824 gp_Pnt PonOE = BAcurveOE.Value(fpar);
2825 gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
2826 Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
2827 Standard_Boolean IsPlanar = Standard_False;
2828 if (BAcurve.GetType() == GeomAbs_Circle &&
2829 BAcurveOE.GetType() == GeomAbs_Circle)
2831 gp_Circ aCirc = BAcurve.Circle();
2832 gp_Dir CircAxisDir = aCirc.Axis().Direction();
2833 if (OffsetDir.IsParallel( CircAxisDir, Precision::Confusion() )) //case of cylinder
2834 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
2835 else if (Abs(OffsetDir * CircAxisDir) > Precision::PConfusion()) //case of cone
2837 gp_Circ aCircOE = BAcurveOE.Circle();
2838 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
2839 aCirc.Radius(), aCircOE.Radius());
2840 gp_Ax3 theAx3(aCirc.Position());
2841 if (CircAxisDir * theCone.Axis().Direction() < 0.)
2844 CircAxisDir.Reverse();
2846 theCone.SetPosition(theAx3);
2847 theSurf = new Geom_ConicalSurface(theCone);
2849 if (!theSurf.IsNull())
2851 TopLoc_Location Loc;
2852 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
2853 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2854 Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
2855 OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
2856 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2857 aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
2858 aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
2862 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2865 BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
2867 BB.MakeWire(theWire);
2868 BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
2869 BB.Add(theWire, E4);
2870 BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
2871 BB.Add(theWire, E3);
2872 theWire.Closed(Standard_True);
2877 BB.SameParameter(E3, Standard_False);
2878 BB.SameRange(E3, Standard_False);
2879 BB.SameParameter(E4, Standard_False);
2880 BB.SameRange(E4, Standard_False);
2881 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2882 BB.Range(E3, theSurf, Loc, 0., OffsetVal);
2883 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2884 BB.Range(E4, theSurf, Loc, 0., OffsetVal);
2886 NewFace = BRepLib_MakeFace(theSurf, theWire);
2889 if (NewFace.IsNull())
2891 BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
2892 if (MF.Error() == BRepLib_FaceDone)
2894 NewFace = MF.Face();
2895 IsPlanar = Standard_True;
2897 else //Extrusion (by thrusections)
2899 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
2900 Handle(Geom_TrimmedCurve) TrEdgeCurve =
2901 new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
2902 Standard_Real fparOE, lparOE;
2903 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
2904 Handle(Geom_TrimmedCurve) TrOffsetCurve =
2905 new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
2906 GeomFill_Generator ThrusecGenerator;
2907 ThrusecGenerator.AddCurve( TrEdgeCurve );
2908 ThrusecGenerator.AddCurve( TrOffsetCurve );
2909 ThrusecGenerator.Perform( Precision::PConfusion() );
2910 theSurf = ThrusecGenerator.Surface();
2911 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
2912 Standard_Real Uf, Ul, Vf, Vl;
2913 theSurf->Bounds(Uf, Ul, Vf, Vl);
2914 TopLoc_Location Loc;
2915 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
2916 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2917 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
2918 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2919 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
2920 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
2921 aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
2922 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
2925 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2926 Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
2927 BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
2928 BB.Range(E3, Vf, Vl);
2932 BB.SameParameter(E3, Standard_False);
2933 BB.SameRange(E3, Standard_False);
2934 BB.SameParameter(E4, Standard_False);
2935 BB.SameRange(E4, Standard_False);
2936 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2937 BB.Range(E3, theSurf, Loc, Vf, Vl);
2938 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2939 BB.Range(E4, theSurf, Loc, Vf, Vl);
2940 Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
2941 BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
2942 BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
2943 Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
2944 BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
2945 BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
2947 NewFace = BRepLib_MakeFace(theSurf, theWire);
2952 Standard_Real fparOE = BAcurveOE.FirstParameter();
2953 Standard_Real lparOE = BAcurveOE.LastParameter();
2954 TopLoc_Location Loc;
2955 if (Abs(fpar - fparOE) > Precision::Confusion())
2957 const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
2958 gp_Pnt2d fp2d = EdgeLine2d->Value(fpar);
2959 gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
2960 aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
2961 Handle(Geom_Curve) aCurve;
2962 Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
2963 Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
2964 GeomAdaptor_Surface GAsurf( theSurf );
2965 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2966 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2967 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2968 Standard_Real max_deviation = 0., average_deviation;
2969 GeomLib::BuildCurve3d(Precision::Confusion(),
2970 ConS, FirstPar, LastPar,
2971 aCurve, max_deviation, average_deviation);
2972 BB.UpdateEdge( anE4, aCurve, max_deviation );
2973 BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
2974 BB.Range( anE4, FirstPar, LastPar );
2976 if (Abs(lpar - lparOE) > Precision::Confusion())
2978 const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
2979 gp_Pnt2d lp2d = EdgeLine2d->Value(lpar);
2980 gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
2981 aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
2982 Handle(Geom_Curve) aCurve;
2983 Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
2984 Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
2985 GeomAdaptor_Surface GAsurf( theSurf );
2986 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2987 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2988 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2989 Standard_Real max_deviation = 0., average_deviation;
2990 GeomLib::BuildCurve3d(Precision::Confusion(),
2991 ConS, FirstPar, LastPar,
2992 aCurve, max_deviation, average_deviation);
2993 BB.UpdateEdge( anE3, aCurve, max_deviation );
2994 BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
2995 BB.Range( anE3, FirstPar, LastPar );
2998 BRepLib::SameParameter(NewFace);
2999 BRepTools::Update(NewFace);
3000 myWalls.Append(NewFace);
3003 TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
3004 TopoDS_Vertex arcV1, arcV2;
3005 TopExp::Vertices(anArc, arcV1, arcV2);
3006 Standard_Boolean ArcReverse = Standard_False;
3007 if (!arcV1.IsSame(V3))
3009 TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
3010 ArcReverse = Standard_True;
3012 TopoDS_Edge EA1, EA2;
3013 //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
3018 //////////////////////////////////////////////////////
3019 if (V2.IsSame(StartVertex))
3022 EA2 = BRepLib_MakeEdge( V2, arcV2 );
3023 anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
3024 if (EA1.Orientation() == TopAbs_REVERSED)
3026 EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
3027 TopoDS_Wire arcWire;
3028 BB.MakeWire(arcWire);
3029 BB.Add(arcWire, EA1);
3030 BB.Add(arcWire, anArc);
3031 BB.Add(arcWire, EA2);
3032 BRepLib::BuildCurves3d( arcWire, myTol );
3033 arcWire.Closed(Standard_True);
3034 TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
3035 BRepTools::Update(arcFace);
3036 myWalls.Append(arcFace);
3037 TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
3038 const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
3047 FirstStep = Standard_False;
3052 //=======================================================================
3053 //function : MakeShells
3055 //=======================================================================
3057 void BRepOffset_MakeOffset::MakeShells ()
3061 cout << " RECONSTRUCTION OF SHELLS:" << endl;
3066 BRepTools_Quilt Glue;
3067 const TopTools_ListOfShape& R = myImageOffset.Roots();
3068 TopTools_ListIteratorOfListOfShape it(R);
3070 for ( ; it.More(); it.Next()) {
3071 TopTools_ListOfShape Image;
3072 myImageOffset.LastImage(it.Value(),Image);
3073 TopTools_ListIteratorOfListOfShape it2(Image);
3074 for ( ; it2.More(); it2.Next()) {
3075 Glue.Add(it2.Value());
3081 TopExp_Explorer Explo(myShape, TopAbs_FACE);
3082 for (; Explo.More(); Explo.Next())
3083 Glue.Add(Explo.Current());
3085 for (it.Initialize(myWalls); it.More(); it.Next())
3086 Glue.Add(it.Value());
3089 myOffsetShape = Glue.Shells();
3092 //=======================================================================
3093 //function : MakeSolid
3095 //=======================================================================
3097 void BRepOffset_MakeOffset::MakeSolid ()
3099 if (myOffsetShape.IsNull()) return;
3101 // Modified by skv - Mon Apr 4 18:17:27 2005 Begin
3102 // Supporting history.
3103 UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
3104 UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
3105 // Modified by skv - Mon Apr 4 18:17:27 2005 End
3106 TopExp_Explorer exp;
3108 Standard_Integer NbShell = 0;
3111 B.MakeCompound (NC);
3113 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
3114 TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
3115 if (myThickening && myOffset > 0.)
3122 Sol.Closed(Standard_True);
3124 if (NbShell == 1) S1 = Sol;
3128 if (NbShell == 1) S1 = Sh;
3131 if (NbShell == 1) myOffsetShape = S1;
3132 else myOffsetShape = NC;
3135 //=======================================================================
3136 //function : SelectShells
3138 //=======================================================================
3140 void BRepOffset_MakeOffset::SelectShells ()
3142 TopTools_MapOfShape FreeEdges;
3143 TopExp_Explorer exp(myShape,TopAbs_EDGE);
3144 //-------------------------------------------------------------
3145 // FreeEdges all edges that can have free border in the
3147 // 1 - free borders of myShape .
3148 //-------------------------------------------------------------
3149 for ( ; exp.More(); exp.Next()) {
3150 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3151 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
3152 if (LA.Extent() < 2) {
3153 if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
3158 // myShape has free borders and there are no caps
3160 if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
3162 myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
3165 //=======================================================================
3166 //function : OffsetFacesFromShapes
3168 //=======================================================================
3170 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
3172 return myInitOffsetFace;
3175 // Modified by skv - Tue Mar 15 16:20:43 2005 Begin
3177 //=======================================================================
3178 //function : GetJoinType
3179 //purpose : Query offset join type.
3180 //=======================================================================
3182 GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
3187 //=======================================================================
3188 //function : OffsetEdgesFromShapes
3190 //=======================================================================
3192 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
3194 return myInitOffsetEdge;
3197 // Modified by skv - Tue Mar 15 16:20:43 2005 End
3199 //=======================================================================
3200 //function : ClosingFaces
3202 //=======================================================================
3204 const TopTools_MapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
3211 //=======================================================================
3212 //function : EncodeRegularity
3214 //=======================================================================
3216 void BRepOffset_MakeOffset::EncodeRegularity ()
3220 cout << " CODING OF REGULARITIES:" << endl;
3226 if (myOffsetShape.IsNull()) return;
3227 // find edges G1 in the result
3228 TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
3231 TopTools_MapOfShape MS;
3233 for ( ; exp.More(); exp.Next()) {
3234 TopoDS_Edge OE = TopoDS::Edge(exp.Current());
3235 BRepLib::BuildCurve3d(OE,myTol);
3236 TopoDS_Edge ROE = OE;
3238 if ( !MS.Add(OE)) continue;
3240 if ( myImageOffset.IsImage(OE))
3241 ROE = TopoDS::Edge(myImageOffset.Root(OE));
3243 const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
3245 if (LofOF.Extent() != 2) {
3247 if ( Standard_False)
3248 cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
3253 const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
3254 const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
3256 if ( F1.IsNull() || F2.IsNull())
3259 const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
3260 const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
3262 TopAbs_ShapeEnum Type1 = Root1.ShapeType();
3263 TopAbs_ShapeEnum Type2 = Root2.ShapeType();
3265 if (F1.IsSame(F2)) {
3266 if (BRep_Tool::IsClosed(OE,F1)) {
3267 // Temporary Debug for the Bench.
3269 // In mode intersection, the edges are not coded in myInitOffsetEdge
3270 // so, manage case by case
3271 // Note DUB; for Hidden parts, it is NECESSARY to code CN
3272 // Analytic Surfaces.
3273 if (myJoin == GeomAbs_Intersection) {
3274 BRepAdaptor_Surface BS(F1,Standard_False);
3275 GeomAbs_SurfaceType SType = BS.GetType();
3276 if (SType == GeomAbs_Cylinder ||
3277 SType == GeomAbs_Cone ||
3278 SType == GeomAbs_Sphere ||
3279 SType == GeomAbs_Torus ) {
3280 B.Continuity(OE,F1,F1,GeomAbs_CN);
3283 // See YFR : MaJ of myInitOffsetFace
3286 else if (myInitOffsetEdge.IsImage(ROE)) {
3287 if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3288 const TopoDS_Face& FRoot = TopoDS::Face(Root1);
3289 const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
3290 GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
3291 if (Conti == GeomAbs_CN) {
3292 B.Continuity(OE,F1,F1,GeomAbs_CN);
3294 else if ( Conti > GeomAbs_C0) {
3295 B.Continuity(OE,F1,F1,GeomAbs_G1);
3304 // code regularities G1 between :
3305 // - sphere and tube : one root is a vertex, the other is an edge
3306 // and the vertex is included in the edge
3307 // - face and tube : one root is a face, the other an edge
3308 // and the edge is included in the face
3309 // - face and face : if two root faces are tangent in
3310 // the initial shape, they will be tangent in the offset shape
3311 // - tube and tube : if 2 edges generating tubes are
3312 // tangents, the 2 will be tangent either.
3313 if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
3314 TopoDS_Vertex V1,V2;
3315 TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
3316 if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
3317 B.Continuity(OE,F1,F2,GeomAbs_G1);
3320 else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
3321 TopoDS_Vertex V1,V2;
3322 TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
3323 if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
3324 B.Continuity(OE,F1,F2,GeomAbs_G1);
3327 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
3328 TopExp_Explorer exp2(Root1,TopAbs_EDGE);
3329 for ( ; exp2.More(); exp2.Next()) {
3330 if ( exp2.Current().IsSame(Root2)) {
3331 B.Continuity(OE,F1,F2,GeomAbs_G1);
3336 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
3337 TopExp_Explorer exp2(Root2,TopAbs_EDGE);
3338 for ( ; exp2.More(); exp2.Next()) {
3339 if ( exp2.Current().IsSame(Root1)) {
3340 B.Continuity(OE,F1,F2,GeomAbs_G1);
3345 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3346 // if two root faces are tangent in
3347 // the initial shape, they will be tangent in the offset shape
3348 TopTools_ListOfShape LE,LV;
3349 BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
3350 TopoDS::Face(Root2),
3352 if ( LE.Extent() == 1) {
3353 const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
3354 if ( myAnalyse.HasAncestor(Ed)) {
3355 const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
3356 if (LI.Extent() == 1 &&
3357 LI.First().Type() == BRepOffset_Tangent) {
3358 B.Continuity(OE,F1,F2,GeomAbs_G1);
3363 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
3364 TopTools_ListOfShape LV;
3365 TopExp_Explorer exp1,exp2;
3366 for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
3367 TopExp_Explorer exp2(F2,TopAbs_EDGE);
3368 for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
3369 if (exp1.Current().IsSame(exp2.Current())) {
3370 LV.Append(exp1.Current());
3374 if ( LV.Extent() == 1) {
3375 TopTools_ListOfShape LEdTg;
3376 myAnalyse.TangentEdges(TopoDS::Edge(Root1),
3377 TopoDS::Vertex(LV.First()),
3379 TopTools_ListIteratorOfListOfShape it(LEdTg);
3380 for (; it.More(); it.Next()) {
3381 if ( it.Value().IsSame(Root2)) {
3382 B.Continuity(OE,F1,F2,GeomAbs_G1);
3391 if ( ChronBuild) Clock.Show();
3397 //=======================================================================
3398 //function : UpDateTolerance
3400 //=======================================================================
3402 static void UpdateTolerance (TopoDS_Shape& S,
3403 const TopTools_MapOfShape& Faces)
3406 TopTools_MapOfShape View;
3409 // The edges of caps are not modified.
3410 TopTools_MapIteratorOfMapOfShape it;
3411 for (it.Initialize(Faces); it.More(); it.Next()) {
3412 const TopoDS_Shape& F = it.Key();
3413 TopExp_Explorer Exp;
3414 for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3415 View.Add(Exp.Current());
3419 TopExp_Explorer Exp;
3420 for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3421 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
3423 Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E);
3424 Standard_Real Tol = EdgeCorrector->Tolerance();
3425 B.UpdateEdge (E,Tol);
3427 // Update the vertices.
3428 TopExp::Vertices(E,V[0],V[1]);
3430 for (Standard_Integer i = 0 ; i <=1 ; i++) {
3431 if (View.Add(V[i])) {
3432 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
3434 Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]);
3435 B.UpdateVertex (V[i],VertexCorrector->Tolerance());
3436 // use the occasion to clean the vertices.
3437 (TV->ChangePoints()).Clear();
3439 B.UpdateVertex(V[i],Tol);