1 // Created on: 1995-10-27
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by skv - Tue Mar 15 16:20:43 2005
18 // Add methods for supporting history.
20 // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455
22 #include <BRepOffset_MakeOffset.ixx>
23 #include <BRepOffset_Analyse.hxx>
24 #include <BRepOffset_DataMapOfShapeOffset.hxx>
25 #include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
26 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
27 #include <BRepOffset_Interval.hxx>
28 #include <BRepOffset_ListOfInterval.hxx>
29 #include <BRepOffset_Offset.hxx>
30 #include <BRepOffset_Tool.hxx>
31 #include <BRepOffset_Inter2d.hxx>
32 #include <BRepOffset_Inter3d.hxx>
33 #include <BRepOffset_MakeLoops.hxx>
36 #include <BRepAdaptor_Surface.hxx>
37 #include <BRepCheck_Edge.hxx>
38 #include <BRepCheck_Vertex.hxx>
39 #include <BRepLib.hxx>
40 #include <BRepLib_MakeVertex.hxx>
41 #include <BRep_Builder.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRep_TVertex.hxx>
44 #include <BRepTools_Quilt.hxx>
45 #include <BRepClass3d_SolidClassifier.hxx>
49 #include <TopExp_Explorer.hxx>
51 #include <TopoDS_Solid.hxx>
52 #include <TopoDS_Shell.hxx>
53 #include <TopoDS_Compound.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Vertex.hxx>
58 #include <TopTools_MapOfShape.hxx>
59 #include <TopTools_MapIteratorOfMapOfShape.hxx>
60 #include <TopTools_ListOfShape.hxx>
61 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include <TopTools_DataMapOfShapeShape.hxx>
63 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
64 #include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
65 #include <TColStd_ListIteratorOfListOfInteger.hxx>
67 #include <Standard_NotImplemented.hxx>
68 #include <Standard_ConstructionError.hxx>
69 #include <Precision.hxx>
71 #include <TopTools_SequenceOfShape.hxx>
72 #include <Geom_OffsetSurface.hxx>
73 #include <Geom_ConicalSurface.hxx>
74 #include <TopTools_IndexedMapOfShape.hxx>
75 #include <BRep_TEdge.hxx>
76 #include <BRepTools.hxx>
77 #include <gp_Cone.hxx>
80 #include <gp_Lin2d.hxx>
81 #include <GCE2d_MakeLine.hxx>
82 #include <Geom2d_Line.hxx>
83 #include <TopoDS_Iterator.hxx>
84 #include <BRepLib_MakeFace.hxx>
85 #include <Geom_Circle.hxx>
87 #include <BRep_PointRepresentation.hxx>
88 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
89 #include <GeomAPI_ProjectPointOnCurve.hxx>
91 #include <BRepAdaptor_Curve.hxx>
92 #include <BRepAdaptor_Curve2d.hxx>
93 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
94 #include <Geom_SphericalSurface.hxx>
95 #include <TopoDS_Wire.hxx>
96 #include <BRepTools_Substitution.hxx>
97 #include <Geom_TrimmedCurve.hxx>
98 #include <Geom2d_TrimmedCurve.hxx>
100 #include <BRepTools_WireExplorer.hxx>
101 #include <BRepLib_MakeEdge.hxx>
102 #include <gce_MakeDir.hxx>
103 #include <GC_MakeCylindricalSurface.hxx>
104 #include <gce_MakeCone.hxx>
105 #include <Geom_SurfaceOfLinearExtrusion.hxx>
107 #include <Geom2dAdaptor_HCurve.hxx>
108 #include <GeomAdaptor_HSurface.hxx>
109 #include <Adaptor3d_CurveOnSurface.hxx>
110 #include <GeomLib.hxx>
111 #include <GeomFill_Generator.hxx>
112 #include <Geom_Plane.hxx>
113 #include <IntTools_FClass2d.hxx>
114 #include <BRepLib_FindSurface.hxx>
125 #include <OSD_Chronometer.hxx>
127 Standard_Boolean AffichInt2d = Standard_False;
128 Standard_Boolean AffichOffC = Standard_False;
129 Standard_Boolean ChronBuild = Standard_False;
130 Standard_Integer NbAE = 0;
131 Standard_Integer NbAF = 0;
132 static OSD_Chronometer Clock;
138 //=======================================================================
139 //function : DEBVerticesControl
141 //=======================================================================
143 static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
144 Handle(BRepAlgo_AsDes) AsDes)
146 TopTools_ListOfShape LVP;
147 TopTools_ListIteratorOfListOfShape it1LE ;
148 TopTools_ListIteratorOfListOfShape it2LE ;
151 for (i = 1; i <= NewEdges.Extent(); i++) {
152 const TopoDS_Edge& NE = TopoDS::Edge(NewEdges(i));
153 if (AsDes->HasDescendant(NE)) {
154 for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
155 if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
156 LVP.Append(it1LE.Value());
157 cout <<"Vertex on at least 3 edges."<<endl;
160 sprintf (name,"VP_%d",NVP++);
161 DBRep::Set(name,it1LE.Value());
165 else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
166 cout <<"Vertex on more than 3 edges."<<endl;
169 sprintf (name,"VM_%d",NVM++);
170 DBRep::Set(name,it1LE.Value());
178 sprintf (name,"VN_%d",NVN++);
179 DBRep::Set(name,it1LE.Value());
186 //------------------------------------------------
187 // Try to mix spoiled vertices.
188 //------------------------------------------------
190 TopTools_ListIteratorOfListOfShape it1(LVP);
191 Standard_Real TolConf = 1.e-5;
192 Standard_Real Tol = Precision::Confusion();
193 //Standard_Integer i = 1;
196 for ( ; it1.More(); it1.Next()) {
197 TopoDS_Shape V1 = it1.Value();
198 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(V1));
199 Standard_Real distmin = Precision::Infinite();
200 TopTools_ListIteratorOfListOfShape it2(LVP);
201 Standard_Integer j = 1;
203 for ( ; it2.More(); it2.Next()) {
205 TopoDS_Shape V2 = it2.Value();
206 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2));
207 if (!V1.IsSame(V2)) {
208 Standard_Real dist = P1.Distance(P2);
209 if (dist < distmin) distmin = dist;
210 if (dist < TolConf) {
213 const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
214 TopTools_ListIteratorOfListOfShape itAsDes;
215 for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) {
216 EWE2 = TopoDS::Edge(itAsDes.Value());
217 TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL);
218 UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
219 aLocalShape = V1.Oriented(TopAbs_INTERNAL) ;
220 B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
222 // BRep_Tool::Parameter(TopoDS::Vertex(),EWE2);
223 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
226 AsDes->Replace(V2,V1);
233 cout <<" distmin between VP : "<<distmin<<endl;
239 static void UpdateTolerance ( TopoDS_Shape& myShape,
240 const TopTools_IndexedMapOfShape& myFaces);
243 static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
244 const TopoDS_Edge& E,
247 // Search the vertex in the edge
249 Standard_Boolean rev = Standard_False;
251 TopAbs_Orientation orient = TopAbs_INTERNAL;
253 TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
255 // if the edge has no vertices
256 // and is degenerated use the vertex orientation
259 if (!itv.More() && BRep_Tool::Degenerated(E)) {
260 orient = V.Orientation();
264 const TopoDS_Shape& Vcur = itv.Value();
265 if (V.IsSame(Vcur)) {
270 rev = E.Orientation() == TopAbs_REVERSED;
271 if (Vcur.Orientation() == V.Orientation()) {
279 if (!VF.IsNull()) orient = VF.Orientation();
283 if (orient == TopAbs_FORWARD) {
284 BRep_Tool::Range(E,f,l);
285 //return (rev) ? l : f;
287 return Standard_True;
290 else if (orient == TopAbs_REVERSED) {
291 BRep_Tool::Range(E,f,l);
292 //return (rev) ? f : l;
294 return Standard_True;
299 const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
300 L = L.Predivided(V.Location());
301 if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
302 BRep_ListIteratorOfListOfPointRepresentation itpr
303 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
305 while (itpr.More()) {
306 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
307 if (pr->IsPointOnCurve(C,L)) {
308 Standard_Real p = pr->Parameter();
309 Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
311 // Closed curves RLE 16 june 94
312 if (Precision::IsNegativeInfinite(f))
314 //return pr->Parameter();//p;
316 return Standard_True;
318 if (Precision::IsPositiveInfinite(l))
320 //return pr->Parameter();//p;
322 return Standard_True;
324 gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
325 gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
326 Standard_Real tol = BRep_Tool::Tolerance(V);
327 if (Pf.Distance(Pl) < tol) {
328 if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
329 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
330 else res = l;//p = l;
336 return Standard_True;
343 // let us try with the first pcurve
344 Handle(Geom2d_Curve) PC;
345 Handle(Geom_Surface) S;
346 BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
347 L = L.Predivided(V.Location());
348 BRep_ListIteratorOfListOfPointRepresentation itpr
349 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
351 while (itpr.More()) {
352 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
353 if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
354 Standard_Real p = pr->Parameter();
355 // Closed curves RLE 16 june 94
356 if (PC->IsClosed()) {
357 if ((p == PC->FirstParameter()) ||
358 (p == PC->LastParameter())) {
359 if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
360 else p = PC->LastParameter();
365 return Standard_True;
372 //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
373 return Standard_False;
376 //=======================================================================
377 //function : GetEdgePoints
378 //purpose : gets the first, last and middle points of the edge
379 //=======================================================================
380 static void GetEdgePoints(const TopoDS_Edge& anEdge,
381 const TopoDS_Face& aFace,
382 gp_Pnt& fPnt, gp_Pnt& mPnt,
386 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
387 gp_Pnt2d fPnt2d = theCurve->Value(f);
388 gp_Pnt2d lPnt2d = theCurve->Value(l);
389 gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
390 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
391 fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
392 lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
393 mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
396 //=======================================================================
397 //function : FillContours
398 //purpose : fills free boundary contours and faces connected (MapEF)
399 //=======================================================================
400 static void FillContours(const TopoDS_Shape& aShape,
401 const BRepOffset_Analyse& Analyser,
402 TopTools_DataMapOfShapeListOfShape& Contours,
403 TopTools_DataMapOfShapeShape& MapEF)
405 TopTools_ListOfShape Edges;
407 TopExp_Explorer Explo(aShape, TopAbs_FACE);
408 BRepTools_WireExplorer Wexp;
410 for (; Explo.More(); Explo.Next())
412 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
413 TopoDS_Iterator itf(aFace);
414 for (; itf.More(); itf.Next())
416 TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
417 for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
419 TopoDS_Edge anEdge = Wexp.Current();
420 if (BRep_Tool::Degenerated(anEdge))
422 const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
423 if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
425 MapEF.Bind(anEdge, aFace);
426 Edges.Append(anEdge);
432 TopTools_ListIteratorOfListOfShape itl;
433 while (!Edges.IsEmpty())
435 TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
437 TopoDS_Vertex StartVertex, CurVertex;
438 TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
439 TopTools_ListOfShape aContour;
440 aContour.Append(StartEdge);
441 while (!CurVertex.IsSame(StartVertex))
442 for (itl.Initialize(Edges); itl.More(); itl.Next())
444 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
445 TopoDS_Vertex V1, V2;
446 TopExp::Vertices(anEdge, V1, V2);
447 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
449 aContour.Append(anEdge);
450 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
455 Contours.Bind(StartVertex, aContour);
459 //=======================================================================
460 //function : BRepOffset_MakeOffset
462 //=======================================================================
464 BRepOffset_MakeOffset::BRepOffset_MakeOffset()
466 myAsDes = new BRepAlgo_AsDes();
470 //=======================================================================
471 //function : BRepOffset_MakeOffset
473 //=======================================================================
475 BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S,
476 const Standard_Real Offset,
477 const Standard_Real Tol,
478 const BRepOffset_Mode Mode,
479 const Standard_Boolean Inter,
480 const Standard_Boolean SelfInter,
481 const GeomAbs_JoinType Join,
482 const Standard_Boolean Thickening)
489 mySelfInter (SelfInter),
491 myThickening (Thickening),
492 myDone (Standard_False)
495 myAsDes = new BRepAlgo_AsDes();
500 //=======================================================================
501 //function : Initialize
503 //=======================================================================
505 void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
506 const Standard_Real Offset,
507 const Standard_Real Tol,
508 const BRepOffset_Mode Mode,
509 const Standard_Boolean Inter,
510 const Standard_Boolean SelfInter,
511 const GeomAbs_JoinType Join,
512 const Standard_Boolean Thickening)
519 mySelfInter = SelfInter;
521 myThickening = Thickening;
522 myDone = Standard_False;
527 //=======================================================================
530 //=======================================================================
532 void BRepOffset_MakeOffset::Clear()
534 myOffsetShape.Nullify();
535 myInitOffsetFace .Clear();
536 myInitOffsetEdge .Clear();
537 myImageOffset .Clear();
539 myFaceOffset .Clear();
541 myDone = Standard_False;
544 //=======================================================================
547 //=======================================================================
549 void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
554 myInitOffsetFace.SetRoot (F) ;
555 myInitOffsetFace.Bind (F,F);
556 myImageOffset.SetRoot (F) ;
559 //=======================================================================
560 //function : SetOffsetOnFace
562 //=======================================================================
564 void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F,
565 const Standard_Real Off)
567 if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
568 myFaceOffset.Bind(F,Off);
571 //=======================================================================
572 //function : RemoveCorks
574 //=======================================================================
576 static void RemoveCorks (TopoDS_Shape& S,
577 TopTools_IndexedMapOfShape& Faces)
582 //-----------------------------------------------------
583 // Construction of a shape without caps.
584 // and Orientation of caps as in shape S.
585 //-----------------------------------------------------
586 TopExp_Explorer exp(S,TopAbs_FACE);
587 for (; exp.More(); exp.Next()) {
588 const TopoDS_Shape& Cork = exp.Current();
589 if (!Faces.Contains(Cork)) {
593 //Faces.Remove (Cork);
594 //begin instead of Remove//
595 TopoDS_Shape LastShape = Faces(Faces.Extent());
597 if (Faces.FindIndex(Cork) != 0)
598 Faces.Substitute(Faces.FindIndex(Cork), LastShape);
599 //end instead of Remove //
600 Faces.Add(Cork); // to reset it with proper orientation.
606 DBRep::Set("myInit", SS);
611 static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
613 BRepTools_Quilt Glue;
616 TopoDS_Shape SS = Glue.Shells();
617 TopExp_Explorer Explo( SS, TopAbs_SHELL );
620 return Standard_False;
622 return Standard_True;
626 //=======================================================================
627 //function : MakeList
629 //=======================================================================
631 static void MakeList (TopTools_ListOfShape& OffsetFaces,
632 const BRepAlgo_Image& myInitOffsetFace,
633 const TopTools_IndexedMapOfShape& myFaces)
635 TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
636 for ( ; itLOF.More(); itLOF.Next()) {
637 const TopoDS_Shape& Root = itLOF.Value();
638 if (!myFaces.Contains(Root))
639 OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
643 //=======================================================================
646 //=======================================================================
648 static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
651 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
652 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
653 Standard_Real TolV = BRep_Tool::Tolerance(V);
654 if (TolV > Tol) Tol = TolV;
660 //=======================================================================
661 //function : MakeOffsetShape
663 //=======================================================================
665 void BRepOffset_MakeOffset::MakeOffsetShape()
667 myDone = Standard_False;
668 //------------------------------------------
669 // Construction of myShape without caps.
670 //------------------------------------------
671 RemoveCorks (myShape,myFaces);
673 if (! IsConnectedShell(myShape))
674 Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
676 if (Abs(myOffset) < myTol) return;
678 TopAbs_State Side = TopAbs_IN;
679 if (myOffset < 0.) Side = TopAbs_OUT;
683 EvalMax(myShape,myTol);
684 if (myTol > Abs(myOffset*0.5)) {
685 Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Tol > Offset");
687 Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
688 myAnalyse.Perform(myShape,TolAngle);
689 //---------------------------------------------------
690 // Construction of Offset from preanalysis.
691 //---------------------------------------------------
692 //----------------------------
693 // MaJ of SD Face - Offset
694 //----------------------------
697 if (myJoin == GeomAbs_Arc)
699 else if (myJoin == GeomAbs_Intersection)
700 BuildOffsetByInter();
704 // if (mySelfInter) SelfInter(Modif);
708 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
709 Intersection3D (Inter);
713 TopTools_IndexedMapOfShape& Modif = Inter.TouchedFaces();
714 TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
716 if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
717 //-------------------------------------------------------
718 // Unwinding 2D and reconstruction of modified faces
719 //----------------------------------------------------
721 //-----------------------------------------------------
722 // Reconstruction of non modified faces sharing
723 // reconstructed edges
724 //------------------------------------------------------
725 if (!Modif.IsEmpty()) MakeFaces (Modif);
730 //-------------------------
731 // Construction of shells.
732 //-------------------------
738 //----------------------------------
739 // Coding of regularities.
740 //----------------------------------
742 //----------------------
743 // Creation of solids.
744 //----------------------
747 //-----------------------------
748 // MAJ Tolerance edge and Vertex
749 // ----------------------------
750 if (!myOffsetShape.IsNull()) {
751 UpdateTolerance (myOffsetShape,myFaces);
752 BRepLib::UpdateTolerances( myOffsetShape );
755 CorrectConicalFaces();
757 myDone = Standard_True;
762 //=======================================================================
763 //function : MakeThickSolid
765 //=======================================================================
767 void BRepOffset_MakeOffset::MakeThickSolid()
769 //--------------------------------------------------------------
770 // Construction of shell parallel to shell (initial without cap).
771 //--------------------------------------------------------------
774 //--------------------------------------------------------------------
775 // Construction of a solid with the initial shell, parallel shell
777 //--------------------------------------------------------------------
778 if (!myFaces.IsEmpty()) {
782 Standard_Integer NbF = myFaces.Extent();
786 BRepTools_Quilt Glue;
787 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
789 Glue.Add (exp.Current());
791 Standard_Boolean YaResult = 0;
792 if (!myOffsetShape.IsNull())
794 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next())
797 Glue.Add (exp.Current().Reversed());
802 cout << "OffsetShape does not contain a FACES." << endl;
809 cout << "OffsetShape is null!" << endl;
815 myDone = Standard_False;
819 myOffsetShape = Glue.Shells();
820 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
821 B.Add(Res,exp.Current());
823 Res.Closed(Standard_True);
826 // Test of Validity of the result of thick Solid
827 // more face than the initial solid.
829 Standard_Integer NbOF = 0;
830 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
834 myDone = Standard_False;
839 if (myOffset > 0 ) myOffsetShape.Reverse();
841 myDone = Standard_True;
844 //=======================================================================
847 //=======================================================================
849 Standard_Boolean BRepOffset_MakeOffset::IsDone() const
854 //=======================================================================
857 //=======================================================================
859 BRepOffset_Error BRepOffset_MakeOffset::Error() const
864 //=======================================================================
867 //=======================================================================
869 const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const
871 return myOffsetShape;
874 //=======================================================================
875 //function : TrimEdge
876 //purpose : Trim the edge of the largest of descendants in AsDes2d.
877 // Order in AsDes two vertices that have trimmed the edge.
878 //=======================================================================
880 static void TrimEdge (TopoDS_Edge& NE,
881 const Handle(BRepAlgo_AsDes)& AsDes2d,
882 Handle(BRepAlgo_AsDes)& AsDes)
884 Standard_Real aSameParTol = Precision::Confusion();
888 Standard_Real UMin = Precision::Infinite();
889 Standard_Real UMax = -UMin;
891 const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
893 if (LE.Extent() > 1) {
894 TopTools_ListIteratorOfListOfShape it (LE);
895 for (; it.More(); it.Next()) {
896 TopoDS_Vertex V = TopoDS::Vertex(it.Value());
897 if (NE.Orientation() == TopAbs_REVERSED)
899 //V.Orientation(TopAbs_INTERNAL);
900 if (!FindParameter(V, NE, U))
903 Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
904 gp_Pnt thePoint = BRep_Tool::Pnt(V);
905 GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
906 if (Projector.NbPoints() == 0)
907 Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
908 U = Projector.LowerDistanceParameter();
917 if (V1.IsNull() || V2.IsNull()) {
918 Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
920 if (!V1.IsSame(V2)) {
921 NE.Free( Standard_True );
923 TopAbs_Orientation Or = NE.Orientation();
924 NE.Orientation(TopAbs_FORWARD);
926 TopExp::Vertices (NE,VF,VL);
929 B.Add (NE,V1.Oriented(TopAbs_FORWARD));
930 B.Add (NE,V2.Oriented(TopAbs_REVERSED));
931 B.Range(NE,UMin,UMax);
933 AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
934 AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
935 BRepLib::SameParameter(NE, aSameParTol, Standard_True);
940 //=======================================================================
941 //function : BuildOffsetByInter
943 //=======================================================================
944 void BRepOffset_MakeOffset::BuildOffsetByInter()
948 cout << " CONSTRUCTION OF OFFSETS :" << endl;
954 BRepOffset_DataMapOfShapeOffset MapSF;
955 TopTools_MapOfShape Done;
956 Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
957 //--------------------------------------------------------
958 // Construction of faces parallel to initial faces
959 //--------------------------------------------------------
961 TopTools_ListOfShape LF;
962 TopTools_ListIteratorOfListOfShape itLF;
964 BRepLib::SortFaces(myShape,LF);
966 TopTools_DataMapOfShapeShape ShapeTgt;
967 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
968 const TopoDS_Face& F = TopoDS::Face(itLF.Value());
969 Standard_Real CurOffset = myOffset;
970 if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
971 BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
972 TopTools_ListOfShape Let;
973 myAnalyse.Edges(F,BRepOffset_Tangent,Let);
974 TopTools_ListIteratorOfListOfShape itl(Let);
976 for ( ; itl.More(); itl.Next()) {
977 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
978 if ( !ShapeTgt.IsBound(Cur)) {
979 TopoDS_Shape aLocalShape = OF.Generated(Cur);
980 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
981 // const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
982 ShapeTgt.Bind(Cur,OF.Generated(Cur));
983 TopoDS_Vertex V1,V2,OV1,OV2;
984 TopExp::Vertices (Cur,V1,V2);
985 TopExp::Vertices (OTE,OV1,OV2);
986 TopTools_ListOfShape LE;
987 if (!ShapeTgt.IsBound(V1)) {
988 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
989 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
990 if (LE.Extent() == LA.Extent())
991 ShapeTgt.Bind(V1,OV1);
993 if (!ShapeTgt.IsBound(V2)) {
995 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
996 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
997 if (LE.Extent() == LA.Extent())
998 ShapeTgt.Bind(V2,OV2);
1004 //--------------------------------------------------------------------
1005 // MES : Map of OffsetShape -> Extended Shapes.
1006 // Build : Map of Initial SS -> OffsetShape build by Inter.
1007 // can be an edge or a compound of edges
1008 //---------------------------------------------------------------------
1009 TopTools_DataMapOfShapeShape MES;
1010 TopTools_DataMapOfShapeShape Build;
1011 TopTools_ListOfShape Failed;
1012 TopAbs_State Side = TopAbs_IN;
1013 Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
1015 //-------------------------------------------------------------------
1016 // Extension of faces and calculation of new edges of intersection.
1017 //-------------------------------------------------------------------
1018 Standard_Boolean ExtentContext = 0;
1019 if (myOffset > 0) ExtentContext = 1;
1021 BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
1022 // Intersection between parallel faces
1023 Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
1024 // Intersection with caps.
1025 Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
1028 //---------------------------------------------------------------------------------
1029 // Extension of neighbor edges of new edges and intersection between neighbors.
1030 //--------------------------------------------------------------------------------
1031 Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
1032 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1033 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1034 // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
1035 // BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
1036 BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myOffset, myTol);
1037 // Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
1039 //-----------------------------------------------------------
1040 // Great restriction of new edges and update of AsDes.
1041 //------------------------------------------ ----------------
1042 TopTools_IndexedMapOfShape NewEdges;
1043 TopExp_Explorer Exp2,ExpC;
1048 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1049 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1050 NF = MapSF(FI).Face();
1051 if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));}
1052 TopTools_MapOfShape View;
1053 for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
1054 const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current());
1056 if (Build.IsBound(EI)) {
1058 if (NE.ShapeType() == TopAbs_EDGE) {
1059 if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1062 //------------------------------------------------------------
1063 // The Intersections are on several edges.
1064 // The pieces without intersections with neighbors
1065 // are removed from AsDes.
1066 //------------------------------------------------------------
1067 for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1068 if (NewEdges.Add(ExpC.Current())) {
1069 TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
1070 NEC.Free(Standard_True);
1071 if (!AsDes2d->Descendant(NEC).IsEmpty()) {
1072 TrimEdge (NEC,AsDes2d,AsDes);
1082 NE = MapSF(FI).Generated(EI);
1083 //// modified by jgv, 19.12.03 for OCC4455 ////
1084 NE.Orientation( EI.Orientation() );
1085 ///////////////////////////////////////////////
1086 if (MES.IsBound(NE)) {
1088 NE.Orientation(EI.Orientation());
1089 if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1097 //---------------------------------
1098 // Intersection 2D on //
1099 //---------------------------------
1100 TopTools_ListOfShape LFE;
1101 BRepAlgo_Image IMOE;
1102 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1103 const TopoDS_Shape& FI = Exp.Current();
1104 const TopoDS_Shape& OFI = MapSF(FI).Face();
1105 if (MES.IsBound(OFI)) {
1106 const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
1112 TopTools_ListIteratorOfListOfShape itLFE(LFE);
1113 for (; itLFE.More(); itLFE.Next()) {
1114 const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
1115 BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol);
1117 //----------------------------------------------
1118 // Intersections 2d on caps.
1119 //----------------------------------------------
1121 for (i = 1; i <= myFaces.Extent(); i++) {
1122 const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
1123 BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol);
1126 //-------------------------------
1127 // Unwinding of extended Faces.
1128 //-------------------------------
1129 myMakeLoops.Build(LFE ,AsDes,IMOE);
1132 TopTools_IndexedMapOfShape COES;
1134 //---------------------------
1135 // MAJ SD. for faces //
1136 //---------------------------
1137 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1138 const TopoDS_Shape& FI = Exp.Current();
1139 myInitOffsetFace.SetRoot(FI);
1140 TopoDS_Face OF = MapSF(FI).Face();
1141 if (MES.IsBound(OF)) {
1142 OF = TopoDS::Face(MES(OF));
1143 if (IMOE.HasImage(OF)) {
1144 const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
1145 myInitOffsetFace.Bind(FI,LOFE);
1146 for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
1147 const TopoDS_Shape& OFE = itLF.Value();
1148 myImageOffset.SetRoot(OFE);
1151 sprintf(name,"AF_%d",NbAF++);
1152 DBRep::Set(name,OFE);
1155 TopTools_MapOfShape View;
1156 for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1157 Exp2.More(); Exp2.Next()) {
1158 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1160 myAsDes->Add (OFE,COE);
1163 sprintf(name,"AE_%d",NbAE++);
1164 DBRep::Set(name,COE);
1169 if (!myAsDes->HasDescendant(COE)) {
1170 TopoDS_Vertex CV1,CV2;
1171 TopExp::Vertices(COE,CV1,CV2);
1172 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1173 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1180 myInitOffsetFace.Bind(FI,OF);
1181 myImageOffset.SetRoot(OF);
1184 sprintf(name,"AF_%d",NbAF++);
1185 DBRep::Set(name,OF);
1188 const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
1189 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1190 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1191 if (IMOE.HasImage(OE)) {
1192 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1193 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1194 for (; itLOE.More(); itLOE.Next()) {
1195 TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
1196 const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
1197 // const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
1198 myAsDes->Add(OF,COE);
1201 sprintf(name,"AE_%d",NbAE++);
1202 DBRep::Set(name,COE);
1207 if (!myAsDes->HasDescendant(COE)) {
1208 TopoDS_Vertex CV1,CV2;
1209 TopExp::Vertices(COE,CV1,CV2);
1210 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1211 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1216 myAsDes->Add(OF,OE);
1219 sprintf(name,"AE_%d",NbAE++);
1220 DBRep::Set(name,OE);
1225 const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
1226 myAsDes->Add(OE,LV);
1232 myInitOffsetFace.Bind(FI,OF);
1233 myImageOffset.SetRoot(OF);
1234 TopTools_MapOfShape View;
1235 for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1236 Exp2.More(); Exp2.Next()) {
1238 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1239 myAsDes->Add (OF,COE);
1242 sprintf(name,"AE_%d",NbAE++);
1243 DBRep::Set(name,COE);
1248 if (View.Add(Exp2.Current())) {
1249 if (!myAsDes->HasDescendant(COE)) {
1250 TopoDS_Vertex CV1,CV2;
1251 TopExp::Vertices(COE,CV1,CV2);
1252 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1253 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1259 // Modified by skv - Tue Mar 15 16:20:43 2005
1260 // Add methods for supporting history.
1261 TopTools_MapOfShape aMapEdges;
1263 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1264 const TopoDS_Shape& aFaceRef = Exp.Current();
1266 Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1268 for (; Exp2.More(); Exp2.Next()) {
1269 const TopoDS_Shape& anEdgeRef = Exp2.Current();
1271 if (aMapEdges.Add(anEdgeRef)) {
1272 myInitOffsetEdge.SetRoot(anEdgeRef);
1273 if (Build.IsBound(anEdgeRef)) {
1274 TopoDS_Shape aNewShape = Build(anEdgeRef);
1276 if (aNewShape.ShapeType() == TopAbs_EDGE) {
1277 if (IMOE.HasImage(aNewShape)) {
1278 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
1280 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1282 myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
1283 } else { // aNewShape != TopAbs_EDGE
1284 TopTools_ListOfShape aListNewEdge;
1286 for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1287 const TopoDS_Shape &aResEdge = ExpC.Current();
1289 if (IMOE.HasImage(aResEdge)) {
1290 const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
1291 TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
1293 for (; aNewEIter.More(); aNewEIter.Next())
1294 aListNewEdge.Append(aNewEIter.Value());
1296 aListNewEdge.Append(aResEdge);
1299 myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
1302 else { // Free boundary.
1303 TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
1305 if (MES.IsBound(aNewEdge))
1306 aNewEdge = MES(aNewEdge);
1308 if (IMOE.HasImage(aNewEdge)) {
1309 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
1311 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1313 myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
1318 // Modified by skv - Tue Mar 15 16:20:43 2005
1320 //---------------------------
1322 //---------------------------
1323 //TopTools_MapOfShape View;
1324 for (i = 1; i <= myFaces.Extent(); i++) {
1325 const TopoDS_Shape& Cork = myFaces(i);
1326 const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
1327 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1328 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1329 if (IMOE.HasImage(OE)) {
1330 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1331 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1332 for (; itLOE.More(); itLOE.Next()) {
1333 const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
1334 myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
1337 sprintf(name,"AE_%d",NbAE++);
1338 DBRep::Set(name,COE);
1343 if (!myAsDes->HasDescendant(COE)) {
1344 TopoDS_Vertex CV1,CV2;
1345 TopExp::Vertices(COE,CV1,CV2);
1346 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1347 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1352 myAsDes->Add(Cork,OE);
1353 if (AsDes->HasDescendant(OE)) {
1354 myAsDes->Add(OE,AsDes->Descendant(OE));
1358 sprintf(name,"AE_%d",NbAE++);
1359 DBRep::Set(name,OE);
1368 DEBVerticesControl (COES,myAsDes);
1369 if ( ChronBuild) Clock.Show();
1374 //=======================================================================
1375 //function : BuildOffsetByArc
1377 //=======================================================================
1378 void BRepOffset_MakeOffset::BuildOffsetByArc()
1382 cout << " CONSTRUCTION OF OFFSETS :" << endl;
1388 BRepOffset_DataMapOfShapeOffset MapSF;
1389 TopTools_MapOfShape Done;
1390 Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
1391 //--------------------------------------------------------
1392 // Construction of faces parallel to initial faces
1393 //--------------------------------------------------------
1394 TopExp_Explorer Exp;
1395 TopTools_ListOfShape LF;
1396 TopTools_ListIteratorOfListOfShape itLF;
1398 BRepLib::SortFaces(myShape,LF);
1400 TopTools_DataMapOfShapeShape EdgeTgt;
1401 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
1402 const TopoDS_Face& F = TopoDS::Face(itLF.Value());
1403 Standard_Real CurOffset = myOffset;
1404 if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
1405 BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
1406 TopTools_ListOfShape Let;
1407 myAnalyse.Edges(F,BRepOffset_Tangent,Let);
1408 TopTools_ListIteratorOfListOfShape itl(Let);
1410 for ( ; itl.More(); itl.Next()) {
1411 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
1412 if ( !EdgeTgt.IsBound(Cur)) {
1413 TopoDS_Shape aLocalShape = OF.Generated(Cur);
1414 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1415 // const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
1416 EdgeTgt.Bind(Cur,OF.Generated(Cur));
1417 TopoDS_Vertex V1,V2,OV1,OV2;
1418 TopExp::Vertices (Cur,V1,V2);
1419 TopExp::Vertices (OTE,OV1,OV2);
1420 TopTools_ListOfShape LE;
1421 if (!EdgeTgt.IsBound(V1)) {
1422 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1423 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
1424 if (LE.Extent() == LA.Extent())
1425 EdgeTgt.Bind(V1,OV1);
1427 if (!EdgeTgt.IsBound(V2)) {
1429 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1430 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
1431 if (LE.Extent() == LA.Extent())
1432 EdgeTgt.Bind(V2,OV2);
1438 //--------------------------------------------------------
1439 // Construction of tubes on edge.
1440 //--------------------------------------------------------
1441 BRepOffset_Type OT = BRepOffset_Convex;
1442 if (myOffset < 0.) OT = BRepOffset_Concave;
1444 for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1445 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1447 const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
1448 if (Anc.Extent() == 2) {
1449 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1450 if (!L.IsEmpty() && L.First().Type() == OT) {
1451 Standard_Real CurOffset = myOffset;
1452 if ( myFaceOffset.IsBound(Anc.First()))
1453 CurOffset = myFaceOffset(Anc.First());
1454 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1455 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1456 aLocalShape = MapSF(Anc.Last()).Generated(E);
1457 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1458 // TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1459 // TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
1460 // find if exits tangent edges in the original shape
1461 TopoDS_Edge E1f, E1l;
1462 TopoDS_Vertex V1f, V1l;
1463 TopExp::Vertices(E,V1f,V1l);
1464 TopTools_ListOfShape TangE;
1465 myAnalyse.TangentEdges(E,V1f,TangE);
1466 // find if the pipe on the tangent edges are soon created.
1467 TopTools_ListIteratorOfListOfShape itl(TangE);
1468 Standard_Boolean Find = Standard_False;
1469 for ( ; itl.More() && !Find; itl.Next()) {
1470 if ( MapSF.IsBound(itl.Value())) {
1471 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
1472 E1f = TopoDS::Edge(aLocalShape);
1473 // E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
1474 Find = Standard_True;
1478 myAnalyse.TangentEdges(E,V1l,TangE);
1479 // find if the pipe on the tangent edges are soon created.
1480 itl.Initialize(TangE);
1481 Find = Standard_False;
1482 for ( ; itl.More() && !Find; itl.Next()) {
1483 if ( MapSF.IsBound(itl.Value())) {
1484 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
1485 E1l = TopoDS::Edge(aLocalShape);
1486 // E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
1487 Find = Standard_True;
1490 BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
1495 // ----------------------
1497 // ----------------------
1498 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1499 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1500 /// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1501 myInitOffsetEdge.SetRoot(E); // skv: supporting history.
1502 myInitOffsetEdge.Bind (E,EOn1);
1507 //--------------------------------------------------------
1508 // Construction of spheres on vertex.
1509 //--------------------------------------------------------
1511 TopTools_ListIteratorOfListOfShape it;
1513 for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
1514 const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
1516 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
1517 TopTools_ListOfShape LE;
1518 myAnalyse.Edges(V,OT,LE);
1520 if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
1521 TopTools_ListOfShape LOE;
1522 //--------------------------------------------------------
1523 // Return connected edges on tubes.
1524 //--------------------------------------------------------
1525 for (it.Initialize(LE) ; it.More(); it.Next()) {
1526 LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
1528 //----------------------
1529 // construction sphere.
1530 //-----------------------
1531 const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
1532 const TopoDS_Shape& FF = LLA.First();
1533 Standard_Real CurOffset = myOffset;
1534 if ( myFaceOffset.IsBound(FF))
1535 CurOffset = myFaceOffset(FF);
1537 BRepOffset_Offset OF(V,LOE,CurOffset);
1540 //--------------------------------------------------------------
1541 // Particular processing if V is at least a free border.
1542 //-------------------------------------------------------------
1543 TopTools_ListOfShape LBF;
1544 myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
1545 if (!LBF.IsEmpty()) {
1546 Standard_Boolean First = Standard_True;
1547 for (it.Initialize(LE) ; it.More(); it.Next()) {
1549 myInitOffsetEdge.SetRoot(V); // skv: supporting history.
1550 myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
1551 First = Standard_False;
1554 myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
1561 //------------------------------------------------------------
1562 // Extension of parallel faces to the context.
1563 // Extended faces are ordered in DS and removed from MapSF.
1564 //------------------------------------------------------------
1565 if (!myFaces.IsEmpty()) ToContext (MapSF);
1567 //------------------------------------------------------
1569 //------------------------------------------------------
1570 BRepOffset_Type RT = BRepOffset_Concave;
1571 if (myOffset < 0.) RT = BRepOffset_Convex;
1572 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
1573 for ( ; It.More(); It.Next()) {
1574 const TopoDS_Shape& SI = It.Key();
1575 const BRepOffset_Offset& SF = It.Value();
1576 if (SF.Status() == BRepOffset_Reversed ||
1577 SF.Status() == BRepOffset_Degenerated ) {
1578 //------------------------------------------------
1579 // Degenerated or returned faces are not stored.
1580 //------------------------------------------------
1584 const TopoDS_Face& OF = It.Value().Face();
1585 myInitOffsetFace.Bind (SI,OF);
1586 myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
1587 myImageOffset.SetRoot (OF); // FaceOffset root of images
1589 if (SI.ShapeType() == TopAbs_FACE) {
1590 for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1591 Exp.More(); Exp.Next()) {
1592 //--------------------------------------------------------------------
1593 // To each face are associatedthe edges that restrict that
1594 // The edges that do not generate tubes or are not tangent
1595 // to two faces are removed.
1596 //--------------------------------------------------------------------
1597 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1598 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1599 if (!L.IsEmpty() && L.First().Type() != RT) {
1600 TopAbs_Orientation OO = E.Orientation();
1601 TopoDS_Shape aLocalShape = It.Value().Generated(E);
1602 TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
1603 // TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
1604 myAsDes->Add (OF,OE.Oriented(OO));
1609 for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1610 Exp.More(); Exp.Next()) {
1611 myAsDes->Add (OF,Exp.Current());
1617 if ( ChronBuild) Clock.Show();
1623 //=======================================================================
1624 //function : SelfInter
1626 //=======================================================================
1628 void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
1632 cout << " AUTODEBOUCLAGE:" << endl;
1638 Standard_NotImplemented::Raise();
1641 if ( ChronBuild) Clock.Show();
1646 //=======================================================================
1647 //function : ToContext
1649 //=======================================================================
1651 void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
1653 TopTools_DataMapOfShapeShape Created;
1654 TopTools_DataMapOfShapeShape MEF;
1655 TopTools_IndexedMapOfShape FacesToBuild;
1656 TopTools_ListIteratorOfListOfShape itl;
1657 TopExp_Explorer exp;
1659 // TopAbs_State Side = TopAbs_IN;
1660 // if (myOffset < 0.) Side = TopAbs_OUT;
1662 TopAbs_State Side = TopAbs_OUT;
1666 for (i = 1; i <= myFaces.Extent(); i++) {
1667 const TopoDS_Face& CF = TopoDS::Face(myFaces(i));
1668 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1669 exp.More(); exp.Next()) {
1670 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1671 if (!myAnalyse.HasAncestor(E)) {
1672 //----------------------------------------------------------------
1673 // The edges of context faces that are not in the initial shape
1674 // can appear in the result.
1675 //----------------------------------------------------------------
1676 //myAsDes->Add(CF,E);
1682 //--------------------------------------------------------
1683 // Determine the edges and faces reconstructed by
1685 //---------------------------------------------------------
1687 for (j = 1; j <= myFaces.Extent(); j++) {
1688 const TopoDS_Face& CF = TopoDS::Face(myFaces(j));
1689 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1690 exp.More(); exp.Next()) {
1691 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1692 if (myAnalyse.HasAncestor(E)) {
1693 const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
1694 for (itl.Initialize(LEA); itl.More(); itl.Next()) {
1695 const BRepOffset_Offset& OF = MapSF(itl.Value());
1696 FacesToBuild.Add(itl.Value());
1697 MEF.Bind(OF.Generated(E),CF);
1700 TopExp::Vertices(E,V[0],V[1]);
1701 for (Standard_Integer i = 0; i < 2; i++) {
1702 const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]);
1703 for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
1704 const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
1705 if (MapSF.IsBound(EV)) {
1706 const BRepOffset_Offset& OF = MapSF(EV);
1707 FacesToBuild.Add(EV);
1708 MEF.Bind(OF.Generated(V[i]),CF);
1715 //---------------------------
1716 // Reconstruction of faces.
1717 //---------------------------
1719 BRepOffset_Type RT = BRepOffset_Concave;
1720 if (myOffset < 0.) RT = BRepOffset_Convex;
1722 TopAbs_Orientation Or;
1724 for (j = 1; j <= FacesToBuild.Extent(); j++) {
1725 const TopoDS_Shape& S = FacesToBuild(j);
1726 BRepOffset_Offset BOF;
1728 F = TopoDS::Face(BOF.Face());
1729 BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
1734 myInitOffsetFace.Bind (S,NF);
1735 myInitOffsetFace.SetRoot (S); // Initial<-> Offset
1736 myImageOffset.SetRoot (NF);
1738 if (S.ShapeType() == TopAbs_FACE) {
1739 for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1740 exp.More(); exp.Next()) {
1742 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1743 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1744 OE = BOF.Generated(E);
1745 Or = E.Orientation();
1747 if (!L.IsEmpty() && L.First().Type() != RT) {
1748 if (Created.IsBound(OE)) {
1750 if (NE.Orientation() == TopAbs_REVERSED)
1751 NE.Orientation(TopAbs::Reverse(Or));
1754 myAsDes->Add(NF,NE);
1757 myAsDes->Add(NF,OE);
1763 //------------------
1765 //---------------------
1766 for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1767 exp.More(); exp.Next()) {
1768 myAsDes->Add (NF,exp.Current());
1774 //------------------
1776 //------------------
1777 TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
1778 for (itc.Initialize(Created); itc.More(); itc.Next()) {
1781 if (myInitOffsetEdge.IsImage(OE)) {
1782 TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
1783 Or = myInitOffsetEdge.Image(E).First().Orientation();
1784 if (NE.Orientation() == TopAbs_REVERSED)
1785 NE.Orientation(TopAbs::Reverse(Or));
1788 myInitOffsetEdge.Remove(OE);
1789 myInitOffsetEdge.Bind(E,NE);
1795 //=======================================================================
1796 //function : UpdateFaceOffset
1798 //=======================================================================
1800 void BRepOffset_MakeOffset::UpdateFaceOffset()
1802 TopTools_MapOfShape M;
1803 TopTools_DataMapOfShapeReal CopiedMap;
1804 CopiedMap.Assign(myFaceOffset);
1805 TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
1807 BRepOffset_Type RT = BRepOffset_Convex;
1808 if (myOffset < 0.) RT = BRepOffset_Concave;
1810 for ( ; it.More(); it.Next()) {
1811 const TopoDS_Face& F = TopoDS::Face(it.Key());
1812 Standard_Real CurOffset = CopiedMap(F);
1813 if ( !M.Add(F)) continue;
1816 Build.MakeCompound(Co);
1817 TopTools_MapOfShape Dummy;
1819 if (myJoin == GeomAbs_Arc)
1820 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
1822 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
1824 TopExp_Explorer exp(Co,TopAbs_FACE);
1825 for (; exp.More(); exp.Next()) {
1826 const TopoDS_Face& FF = TopoDS::Face(exp.Current());
1827 if ( !M.Add(FF)) continue;
1828 if ( myFaceOffset.IsBound(FF))
1829 myFaceOffset.UnBind(FF);
1830 myFaceOffset.Bind(FF,CurOffset);
1835 //=======================================================================
1836 //function : CorrectConicalFaces
1838 //=======================================================================
1840 void BRepOffset_MakeOffset::CorrectConicalFaces()
1842 TopTools_SequenceOfShape Cones;
1843 TopTools_SequenceOfShape Circs;
1844 TopTools_SequenceOfShape Seams;
1845 Standard_Real TolApex = 1.e-5;
1849 TopTools_DataMapOfShapeListOfShape FacesOfCone;
1850 //TopTools_DataMapOfShapeShape DegEdges;
1851 TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
1852 if (myJoin == GeomAbs_Arc)
1854 for (; Explo.More(); Explo.Next())
1856 TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
1857 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
1858 //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
1859 //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
1861 TopTools_IndexedMapOfShape Emap;
1862 TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
1863 for (i = 1; i <= Emap.Extent(); i++)
1865 TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
1866 //Standard_Real f, l;
1867 //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
1868 //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
1869 if (BRep_Tool::Degenerated(anEdge))
1871 //Check if anEdge is a really degenerated edge or not
1872 BRepAdaptor_Curve BACurve(anEdge, aFace);
1873 gp_Pnt Pfirst, Plast, Pmid;
1874 Pfirst = BACurve.Value(BACurve.FirstParameter());
1875 Plast = BACurve.Value(BACurve.LastParameter());
1876 Pmid = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
1877 if (Pfirst.Distance(Plast) <= TolApex &&
1878 Pfirst.Distance(Pmid) <= TolApex)
1880 //Cones.Append( aFace );
1881 //Circs.Append( anEdge );
1882 //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
1883 TopoDS_Edge OrEdge =
1884 TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
1885 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1886 if ( FacesOfCone.IsBound(VF) )
1888 //add a face to the existing list
1889 TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
1890 aFaces.Append (aFace);
1891 //DegEdges.Bind(aFace, anEdge);
1895 //the vertex is not in the map => create a new key and items
1896 TopTools_ListOfShape aFaces;
1897 aFaces.Append (aFace);
1898 FacesOfCone.Bind(VF, aFaces);
1899 //DegEdges.Bind(aFace, anEdge);
1902 } //for (i = 1; i <= Emap.Extent(); i++)
1903 } //for (; fexp.More(); fexp.Next())
1904 } //if (myJoin == GeomAbs_Arc)
1906 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
1909 for (; Cone.More(); Cone.Next() ) {
1910 gp_Sphere theSphere;
1911 Handle(Geom_SphericalSurface) aSphSurf;
1912 TopoDS_Wire SphereWire;
1913 BB.MakeWire(SphereWire);
1914 TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
1915 const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
1916 TopTools_ListIteratorOfListOfShape itFaces(Faces);
1917 Standard_Boolean isFirstFace = Standard_True;
1919 TopoDS_Vertex theFirstVertex, CurFirstVertex;
1920 for (; itFaces.More(); itFaces.Next())
1922 TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
1923 TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
1924 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
1926 DegEdge = TopoDS::Edge(Explo.Current());
1927 if (BRep_Tool::Degenerated(DegEdge))
1929 TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
1930 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1931 if (VF.IsSame(anApex))
1935 TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
1936 TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
1937 BB.Degenerated(CurEdge, Standard_False);
1938 BB.SameRange(CurEdge, Standard_False);
1939 BB.SameParameter(CurEdge, Standard_False);
1940 gp_Pnt fPnt, lPnt, mPnt;
1941 GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
1943 BRep_Tool::Range(CurEdge, f, l);
1946 gp_Vec aVec1(fPnt, mPnt);
1947 gp_Vec aVec2(fPnt, lPnt);
1948 gp_Vec aNorm = aVec1.Crossed(aVec2);
1949 gp_Pnt theApex = BRep_Tool::Pnt(anApex);
1950 gp_Vec ApexToFpnt(theApex, fPnt);
1951 gp_Vec Ydir = aNorm ^ ApexToFpnt;
1952 gp_Vec Xdir = Ydir ^ aNorm;
1953 //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
1954 gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
1955 theSphere.SetRadius(myOffset);
1956 theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
1957 aSphSurf = new Geom_SphericalSurface(theSphere);
1959 theFirstVertex = BRepLib_MakeVertex(fPnt);
1960 CurFirstVertex = theFirstVertex;
1963 TopoDS_Vertex v1, v2, FirstVert, EndVert;
1964 TopExp::Vertices(CurEdge, v1, v2);
1965 FirstVert = CurFirstVertex;
1966 if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
1967 EndVert = theFirstVertex;
1969 EndVert = BRepLib_MakeVertex(lPnt);
1970 CurEdge.Free( Standard_True );
1971 BB.Remove(CurEdge, v1);
1972 BB.Remove(CurEdge, v2);
1973 BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
1974 BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
1975 //take the curve from sphere an put it to the edge
1976 Standard_Real Uf, Vf, Ul, Vl;
1977 ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
1978 ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
1979 if (Abs(Ul) <= Precision::Confusion())
1981 Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
1985 gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
1986 if (Abs(Uf - f) > Precision::Confusion())
1988 aCircle.Rotate(aCircle.Axis(), f - Uf);
1989 aCurv = new Geom_Circle(aCircle);
1993 Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
1994 BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
1995 BB.Range(CurEdge, Uf, Ul, Standard_True);
1996 Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
1997 Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
1998 BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
1999 BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
2000 BRepLib::SameParameter(CurEdge);
2001 BB.Add(SphereWire, CurEdge);
2002 //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
2003 BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
2004 gp_Pnt2d fPnt2d, lPnt2d;
2005 fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
2006 lPnt2d = BAc2d.Value(BAc2d.LastParameter());
2007 TopTools_IndexedMapOfShape Emap;
2008 TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
2010 Standard_Integer j = 0, k;
2011 for (k = 1; k <= Emap.Extent(); k++)
2013 const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
2014 if (!BRep_Tool::Degenerated(anEdge))
2016 TopoDS_Vertex V1, V2;
2017 TopExp::Vertices(anEdge, V1, V2);
2018 if (V1.IsSame(v1) || V2.IsSame(v1))
2022 for (k = 0; k < j; k++)
2024 TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
2025 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
2026 Eforward.Free(Standard_True);
2027 TopoDS_Vertex V1, V2;
2028 TopExp::Vertices( Eforward, V1, V2 );
2029 BRepAdaptor_Curve2d EEc( Eforward, aFace );
2030 gp_Pnt2d p2d1, p2d2;
2031 p2d1 = EEc.Value(EEc.FirstParameter());
2032 p2d2 = EEc.Value(EEc.LastParameter());
2035 TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
2036 FirstVert : EndVert;
2037 BB.Remove( Eforward, V1 );
2038 BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
2042 TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
2043 FirstVert : EndVert;
2044 BB.Remove( Eforward, V2 );
2045 BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
2049 isFirstFace = Standard_False;
2050 CurFirstVertex = EndVert;
2052 //Building new spherical face
2053 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2054 gp_Pnt2d p2d1, p2d2;
2055 TopTools_ListOfShape EdgesOfWire;
2056 TopoDS_Iterator itw(SphereWire);
2057 for (; itw.More(); itw.Next())
2059 const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
2060 EdgesOfWire.Append(anEdge);
2062 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
2063 p2d1 = aC2d->Value(f);
2064 p2d2 = aC2d->Value(l);
2065 if (p2d1.X() < Ufirst)
2067 if (p2d1.X() > Ulast)
2069 if (p2d2.X() < Ufirst)
2071 if (p2d2.X() > Ulast)
2074 TopTools_ListOfShape NewEdges;
2075 TopoDS_Edge FirstEdge;
2076 TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
2077 for (; itl.More(); itl.Next())
2079 FirstEdge = TopoDS::Edge(itl.Value());
2081 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
2082 p2d1 = aC2d->Value(f);
2083 p2d2 = aC2d->Value(l);
2084 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
2086 EdgesOfWire.Remove(itl);
2090 NewEdges.Append(FirstEdge);
2091 TopoDS_Vertex Vf1, CurVertex;
2092 TopExp::Vertices(FirstEdge, Vf1, CurVertex);
2093 itl.Initialize(EdgesOfWire);
2096 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2097 TopoDS_Vertex V1, V2;
2098 TopExp::Vertices(anEdge, V1, V2);
2099 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
2101 NewEdges.Append(anEdge);
2102 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2103 EdgesOfWire.Remove(itl);
2109 Standard_Real Vfirst, Vlast;
2112 Vfirst = p2d1.Y(); Vlast = M_PI/2.;
2116 Vfirst = -M_PI/2.; Vlast = p2d1.Y();
2118 TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
2119 TopoDS_Edge OldEdge;
2120 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2122 OldEdge = TopoDS::Edge(Explo.Current());
2123 if (!BRep_Tool::Degenerated(OldEdge))
2125 BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
2126 p2d1 = BAc2d.Value(BAc2d.FirstParameter());
2127 p2d2 = BAc2d.Value(BAc2d.LastParameter());
2128 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
2129 Abs(p2d2.X() - Ulast) <= Precision::Confusion())
2133 TopoDS_Vertex V1, V2;
2134 TopExp::Vertices(OldEdge, V1, V2);
2135 TopTools_ListOfShape LV1, LV2;
2137 LV2.Append(CurVertex);
2138 BRepTools_Substitution theSubstitutor;
2139 theSubstitutor.Substitute(V1, LV1);
2141 theSubstitutor.Substitute(V2, LV2);
2142 theSubstitutor.Substitute(OldEdge, NewEdges);
2143 theSubstitutor.Build(NewSphericalFace);
2144 if (theSubstitutor.IsCopied(NewSphericalFace))
2146 const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
2147 NewSphericalFace = TopoDS::Face(listSh.First());
2150 //Adding NewSphericalFace to the shell
2151 Explo.Init( myOffsetShape, TopAbs_SHELL );
2152 TopoDS_Shape theShell = Explo.Current();
2153 theShell.Free( Standard_True );
2154 BB.Add( theShell, NewSphericalFace );
2157 Explo.Init( myOffsetShape, TopAbs_SHELL );
2160 TopoDS_Shape theShell = Explo.Current();
2161 theShell.Closed( Standard_True );
2167 for (i = 1; i <= Cones.Length(); i++)
2169 TopoDS_Face Cone = TopoDS::Face( Cones(i) );
2170 TopoDS_Edge Circ = TopoDS::Edge( Circs(i) );
2171 TopoDS_Edge Seam = TopoDS::Edge( Seams(i) );
2172 if (Circ.IsNull()) //case 1 with big offset
2174 //ExtraFace is absent
2176 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2178 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2179 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2180 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2181 gp_Pnt apex = theCone.Apex();
2182 Standard_Real Uapex, Vapex;
2183 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2184 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2185 apex = OffSurf->Value( Uapex, Vapex );
2187 //Making new degenerated edge
2188 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
2189 TopoDS_Edge NewEdge;
2190 BB.MakeEdge( NewEdge );
2191 NewEdge.Orientation(TopAbs_FORWARD);
2192 BB.UpdateEdge( NewEdge, theLine, Cone, Precision::Confusion() );
2193 BB.Range( NewEdge, 0., 2.*M_PI );
2194 BB.SameParameter( NewEdge, Standard_True );
2195 BB.SameRange( NewEdge, Standard_True );
2196 BB.Degenerated( NewEdge, Standard_True );
2197 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2198 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2199 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2201 //Reconstructing Seam
2202 Standard_Real f, l, par, cpar;
2203 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2204 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2205 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2206 TopoDS_Shape aLocalShape = Seam.Oriented(TopAbs_FORWARD);
2207 TopoDS_Vertex cver = TopExp::LastVertex( TopoDS::Edge(aLocalShape) );
2208 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2209 if (Abs(f-cpar) < Abs(l-cpar))
2210 BB.Range( Seam, par, l );
2212 BB.Range( Seam, f, par );
2213 Seam.Free( Standard_True );
2215 TopoDS_Iterator iter( Seam );
2216 for (; iter.More(); iter.Next())
2218 cver1 = iter.Value();
2219 if (cver1.IsSame(cver))
2222 BB.Remove( Seam, cver1 );
2223 if (Abs(f-cpar) < Abs(l-cpar))
2224 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2226 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2228 //Adding NewEdge into Cone
2229 TopoDS_Shape theWire;
2230 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2232 theWire = fexp.Current();
2233 Standard_Boolean found = Standard_False;
2234 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2236 if (Seam.IsSame( iter.Value() ))
2238 found = Standard_True;
2245 theWire.Free( Standard_True );
2246 NewEdge.Orientation( TopAbs::Compose(theWire.Orientation(),TopAbs_REVERSED) );
2247 BB.Add( theWire, NewEdge );
2248 } //end of case 1 with big offset
2251 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Circ.TShape());
2252 if (! TE->Degenerated()) //case 1
2255 TopoDS_Face ExtraFace;
2256 for (fexp.Init( myOffsetShape, TopAbs_FACE ); fexp.More(); fexp.Next())
2258 ExtraFace = TopoDS::Face( fexp.Current() );
2259 if (ExtraFace.IsSame( Cone ))
2261 Standard_Boolean found = Standard_False;
2262 TopExp_Explorer eexp( ExtraFace, TopAbs_EDGE );
2263 for (; eexp.More(); eexp.Next())
2264 if (Circ.IsSame( eexp.Current() ))
2266 found = Standard_True;
2273 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2274 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2275 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2276 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2277 gp_Pnt apex = theCone.Apex();
2278 Standard_Real Uapex, Vapex;
2279 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2280 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2281 apex = OffSurf->Value( Uapex, Vapex );
2283 //Making new degenerated edge
2284 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
2285 TopoDS_Edge NewEdge;
2286 BB.MakeEdge( NewEdge );
2287 NewEdge.Orientation(TopAbs_FORWARD);
2288 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
2289 BB.Range( NewEdge, 0., 2.*M_PI );
2290 BB.SameParameter( NewEdge, Standard_True );
2291 BB.SameRange( NewEdge, Standard_True );
2292 BB.Degenerated( NewEdge, Standard_True );
2293 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2294 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2295 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2297 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2299 //Reconstructing Seam
2300 Standard_Real f, l, par, cpar;
2301 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2302 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2303 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2304 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2305 if (Abs(f-cpar) < Abs(l-cpar))
2306 BB.Range( Seam, par, l );
2308 BB.Range( Seam, f, par );
2309 Seam.Free( Standard_True );
2311 TopoDS_Iterator iter( Seam );
2312 for (; iter.More(); iter.Next())
2314 cver1 = iter.Value();
2315 if (cver1.IsSame(cver))
2318 BB.Remove( Seam, cver1 );
2319 if (Abs(f-cpar) < Abs(l-cpar))
2320 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2322 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2324 //Removing ExtraFace from the shell
2325 fexp.Init( myOffsetShape, TopAbs_SHELL );
2326 TopoDS_Shape theShell = fexp.Current();
2327 theShell.Free( Standard_True );
2328 TopoDS_Shape ExtraFace1;
2329 for (iter.Initialize( theShell ); iter.More(); iter.Next())
2331 ExtraFace1 = iter.Value();
2332 if (ExtraFace1.IsSame(ExtraFace))
2335 BB.Remove( theShell, ExtraFace1 );
2337 //Substitute Circ by NewEdge in Cone
2338 TopoDS_Shape theWire;
2340 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2342 theWire = fexp.Current();
2343 Standard_Boolean found = Standard_False;
2344 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2346 Circ1 = iter.Value();
2347 if (Circ1.IsSame(Circ))
2349 found = Standard_True;
2356 TopAbs_Orientation Or = Circ1.Orientation();
2357 theWire.Free( Standard_True );
2358 BB.Remove( theWire, Circ1 );
2359 BB.Add( theWire, NewEdge.Oriented(Or) );
2361 else // Circ is degenerated
2363 if (myOffset > 0. && myJoin == GeomAbs_Arc) //case 2
2365 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2367 TopoDS_Face OrCone = TopoDS::Face( myInitOffsetFace.Root( Cone ) );
2368 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( OrCone ), OffSurf = aSurf;
2369 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2370 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2371 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2372 gp_Pnt apex = theCone.Apex();
2373 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2375 Standard_Real Uapex, Vapex;
2376 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2377 apex = OffSurf->Value( Uapex, Vapex );
2381 Handle(Geom_Curve) ccur = BRep_Tool::Curve( Circ, f, l );
2382 gp_Ax2 Axe2 = (Handle(Geom_Circle)::DownCast(ccur))->Circ().Position();
2383 gp_Ax3 Axe3( Axe2 );
2384 Axe3.SetLocation( apex );
2385 gp_Sphere theSphere( Axe3, myOffset );
2387 gp_Pnt OrPnt = BRep_Tool::Pnt(cver);
2388 Standard_Real Uor, Vor;
2389 ElSLib::Parameters( theSphere, OrPnt, Uor, Vor );
2390 TopoDS_Face NewFace;
2392 NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, Vor, M_PI/2. );
2394 NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, -M_PI/2., Vor );
2396 //Updating the bound of NewFace
2398 TopExp_Explorer eexp( NewFace, TopAbs_EDGE );
2399 for (; eexp.More(); eexp.Next())
2401 Bound = TopoDS::Edge( eexp.Current() );
2402 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Bound.TShape());
2403 if (!TE->Degenerated() && !BRepTools::IsReallyClosed( Bound, NewFace ))
2406 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( Circ, Cone, f, l );
2407 BB.UpdateEdge( Bound, pcurve, Cone, BRep_Tool::Tolerance(Circ) );
2408 TopoDS_Vertex bver = TopExp::FirstVertex( Bound );
2409 BB.UpdateVertex( bver, BRep_Tool::Tolerance(cver) );
2411 //Updating cver in Seam
2412 TopoDS_Vertex cver1;
2413 TopoDS_Iterator iter( Seam );
2414 for (; iter.More(); iter.Next())
2416 cver1 = TopoDS::Vertex( iter.Value() );
2417 if (cver1.IsSame(cver))
2420 TopAbs_Orientation Or = cver1.Orientation();
2421 Seam.Free( Standard_True );
2422 BB.Remove( Seam, cver1 );
2423 BB.Add( Seam, bver.Oriented(Or) );
2425 //Substitute Circ by Bound in Cone
2426 TopoDS_Shape theWire;
2428 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2430 theWire = fexp.Current();
2431 Standard_Boolean found = Standard_False;
2432 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2434 Circ1 = iter.Value();
2435 if (Circ1.IsSame(Circ))
2437 found = Standard_True;
2444 Or = Circ1.Orientation();
2445 theWire.Free( Standard_True );
2446 BB.Remove( theWire, Circ1 );
2447 BB.Add( theWire, Bound.Oriented(Or) );
2449 //Adding NewFace to the shell
2450 fexp.Init( myOffsetShape, TopAbs_SHELL );
2451 TopoDS_Shape theShell = fexp.Current();
2452 theShell.Free( Standard_True );
2453 BB.Add( theShell, NewFace );
2455 theShell.Closed( Standard_True );
2457 else // if ((myOffset > 0. && myJoin == GeomAbs_Intersection) || myOffset < 0.) //case 3, 4
2459 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2460 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2461 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2462 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2463 gp_Pnt apex = theCone.Apex();
2464 Standard_Real Uapex, Vapex;
2465 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2466 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2467 apex = OffSurf->Value( Uapex, Vapex );
2469 //Making new degenerated edge
2470 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
2471 TopoDS_Edge NewEdge;
2472 BB.MakeEdge( NewEdge );
2473 NewEdge.Orientation(TopAbs_FORWARD);
2474 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
2475 BB.Range( NewEdge, 0., 2.*M_PI );
2476 BB.SameParameter( NewEdge, Standard_True );
2477 BB.SameRange( NewEdge, Standard_True );
2478 BB.Degenerated( NewEdge, Standard_True );
2479 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2480 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2481 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2483 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2485 //Reconstructing Seam
2486 Standard_Real f, l, par, cpar;
2487 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2488 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2489 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2490 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2491 if (Abs(f-cpar) < Abs(l-cpar))
2492 BB.Range( Seam, par, l );
2494 BB.Range( Seam, f, par );
2495 Seam.Free( Standard_True );
2497 TopoDS_Iterator iter( Seam );
2498 for (; iter.More(); iter.Next())
2500 cver1 = iter.Value();
2501 if (cver1.IsSame(cver))
2504 BB.Remove( Seam, cver1 );
2505 if (Abs(f-cpar) < Abs(l-cpar))
2506 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2508 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2510 //Substitute Circ by NewEdge in Cone
2511 TopoDS_Shape theWire;
2513 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2515 theWire = fexp.Current();
2516 Standard_Boolean found = Standard_False;
2517 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2519 Circ1 = iter.Value();
2520 if (Circ1.IsSame(Circ))
2522 found = Standard_True;
2529 TopAbs_Orientation Or = Circ1.Orientation();
2530 theWire.Free( Standard_True );
2531 BB.Remove( theWire, Circ1 );
2532 BB.Add( theWire, NewEdge.Oriented(Or) );
2534 fexp.Init( myOffsetShape, TopAbs_SHELL );
2535 TopoDS_Shape theShell = fexp.Current();
2536 theShell.Closed( Standard_True );
2537 } //end of case 3, 4
2539 } //else (! Circ.IsNull())
2543 Standard_Integer NbShell = 0;
2546 BB.MakeCompound (NC);
2548 for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
2549 const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
2555 Sol.Closed(Standard_True);
2557 if (NbShell == 1) S1 = Sol;
2561 if (NbShell == 1) S1 = Sh;
2564 if (NbShell == 1) myOffsetShape = S1;
2565 else myOffsetShape = NC;
2569 //=======================================================================
2570 //function : Intersection3D
2572 //=======================================================================
2574 void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
2578 cout << " INTERSECTION 3D:" << endl;
2583 TopTools_ListOfShape OffsetFaces; // list of faces // created.
2584 MakeList (OffsetFaces,myInitOffsetFace,myFaces);
2586 if (!myFaces.IsEmpty()) {
2587 Standard_Boolean InSide = (myOffset < 0.); // Temporary
2588 // it is necessary to calculate Inside taking account of the concavity or convexity of edges
2589 // between the cap and the part.
2591 if (myJoin == GeomAbs_Arc)
2592 Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
2598 Inter.CompletInt (OffsetFaces,myInitOffsetFace);
2599 TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
2600 if (myJoin == GeomAbs_Intersection) {
2601 BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
2605 //--------------------------------
2606 // Only between neighbor faces.
2607 //--------------------------------
2608 Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
2611 if ( ChronBuild) Clock.Show();
2615 //=======================================================================
2616 //function : Intersection2D
2618 //=======================================================================
2620 void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Modif,
2621 const TopTools_IndexedMapOfShape& NewEdges)
2625 cout << " INTERSECTION 2D:" << endl;
2630 //--------------------------------------------------------
2631 // calculate intersections2d on faces concerned by
2633 //---------------------------------------------------------
2634 //TopTools_MapIteratorOfMapOfShape it(Modif);
2635 //-----------------------------------------------
2636 // Intersection of edges 2 by 2.
2637 //-----------------------------------------------
2639 for (i = 1; i <= Modif.Extent(); i++) {
2640 const TopoDS_Face& F = TopoDS::Face(Modif(i));
2641 BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
2646 DEBVerticesControl (NewEdges,myAsDes);
2648 if ( ChronBuild) Clock.Show();
2653 //=======================================================================
2654 //function : MakeLoops
2656 //=======================================================================
2658 void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
2662 cout << " DEBOUCLAGE 2D:" << endl;
2667 //TopTools_MapIteratorOfMapOfShape it(Modif);
2668 TopTools_ListOfShape LF,LC;
2669 //-----------------------------------------
2670 // unwinding of faces // modified.
2671 //-----------------------------------------
2673 for (i = 1; i <= Modif.Extent(); i++) {
2674 if (!myFaces.Contains(Modif(i)))
2675 LF.Append(Modif(i));
2677 myMakeLoops.Build(LF,myAsDes,myImageOffset);
2679 //-----------------------------------------
2680 // unwinding of caps.
2681 //-----------------------------------------
2682 for (i = 1; i <= myFaces.Extent(); i++)
2683 LC.Append(myFaces(i));
2685 Standard_Boolean InSide = 1;
2686 if (myOffset > 0 ) InSide = 0;
2687 myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
2690 if ( ChronBuild) Clock.Show();
2694 //=======================================================================
2695 //function : MakeFaces
2696 //purpose : Reconstruction of topologically unchanged faces that
2697 // share edges that were reconstructed.
2698 //=======================================================================
2700 void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
2704 cout << " RECONSTRUCTION OF FACES:" << endl;
2709 TopTools_ListIteratorOfListOfShape itr;
2710 const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
2711 TopTools_ListOfShape LOF;
2712 //----------------------------------
2713 // Loop on all faces //.
2714 //----------------------------------
2715 for (itr.Initialize(Roots); itr.More(); itr.Next()) {
2716 TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
2719 myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
2722 if ( ChronBuild) Clock.Show();
2726 //=======================================================================
2727 //function : UpdateInitOffset
2728 //purpose : Update and cleaning of myInitOffset
2729 //=======================================================================
2731 static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
2732 BRepAlgo_Image& myImageOffset,
2733 const TopoDS_Shape& myOffsetShape,
2734 const TopAbs_ShapeEnum &theShapeType) // skv
2736 BRepAlgo_Image NIOF;
2737 const TopTools_ListOfShape& Roots = myInitOffset.Roots();
2738 TopTools_ListIteratorOfListOfShape it(Roots);
2739 for (; it.More(); it.Next()) {
2740 NIOF.SetRoot (it.Value());
2742 for (it.Initialize(Roots); it.More(); it.Next()) {
2743 const TopoDS_Shape& SI = it.Value();
2744 TopTools_ListOfShape LI;
2745 TopTools_ListOfShape L1;
2746 myInitOffset.LastImage(SI,L1);
2747 TopTools_ListIteratorOfListOfShape itL1(L1);
2748 for (; itL1.More(); itL1.Next()) {
2749 const TopoDS_Shape& O1 = itL1.Value();
2750 TopTools_ListOfShape L2;
2751 myImageOffset.LastImage(O1,L2);
2756 // Modified by skv - Mon Apr 4 18:17:27 2005 Begin
2757 // Supporting history.
2758 // NIOF.Filter(myOffsetShape,TopAbs_FACE);
2759 NIOF.Filter(myOffsetShape, theShapeType);
2760 // Modified by skv - Mon Apr 4 18:17:27 2005 End
2761 myInitOffset = NIOF;
2764 //=======================================================================
2765 //function : MakeMissingWalls
2767 //=======================================================================
2769 void BRepOffset_MakeOffset::MakeMissingWalls ()
2771 TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
2772 TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
2773 Standard_Real OffsetVal = Abs(myOffset);
2775 FillContours(myShape, myAnalyse, Contours, MapEF);
2777 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
2778 for (; iter.More(); iter.Next())
2780 TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
2781 TopoDS_Edge StartEdge;
2782 const TopTools_ListOfShape& aContour = iter.Value();
2783 TopTools_ListIteratorOfListOfShape itl(aContour);
2784 Standard_Boolean FirstStep = Standard_True;
2785 TopoDS_Edge PrevEdge;
2786 TopoDS_Vertex PrevVertex = StartVertex;
2787 for (; itl.More(); itl.Next())
2789 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
2790 if (!myInitOffsetEdge.HasImage(anEdge))
2792 //if (BRep_Tool::Degenerated(anEdge))
2794 TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
2795 //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
2796 TopTools_ListOfShape LOE, LOE2;
2797 myInitOffsetEdge.LastImage( anEdge, LOE );
2798 myImageOffset.LastImage( LOE.Last(), LOE2 );
2799 TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
2800 ////////////////////////////////////////////////////////////////////////
2801 TopoDS_Vertex V1, V2, V3, V4;
2802 TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
2803 TopExp::Vertices(OE, V4, V3/*, Standard_True*/);
2804 Standard_Boolean ToReverse = Standard_False;
2805 if (!V1.IsSame(PrevVertex))
2807 TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
2808 aVtx = V3; V3 = V4; V4 = aVtx;
2809 ToReverse = Standard_True;
2813 OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
2817 E4 = BRepLib_MakeEdge( V1, V4 );
2822 Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
2823 if (V2.IsSame(StartVertex) && !ArcOnV2)
2826 E3 = BRepLib_MakeEdge( V2, V3 );
2828 TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
2829 const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
2830 Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
2831 Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
2833 TopoDS_Wire theWire;
2834 BB.MakeWire(theWire);
2837 BB.Add(theWire, anEdge.Reversed());
2838 BB.Add(theWire, E3.Reversed());
2839 BB.Add(theWire, OE.Reversed());
2840 BB.Add(theWire, E4.Reversed());
2844 BB.Add(theWire, anEdge);
2845 BB.Add(theWire, E3);
2846 BB.Add(theWire, OE);
2847 BB.Add(theWire, E4);
2849 BRepLib::BuildCurves3d( theWire, myTol );
2850 theWire.Closed(Standard_True);
2851 TopoDS_Face NewFace;
2852 Handle(Geom_Surface) theSurf;
2853 BRepAdaptor_Curve BAcurve(anEdge);
2854 BRepAdaptor_Curve BAcurveOE(OE);
2855 Standard_Real fpar = BAcurve.FirstParameter();
2856 Standard_Real lpar = BAcurve.LastParameter();
2857 gp_Pnt PonE = BAcurve.Value(fpar);
2858 gp_Pnt PonOE = BAcurveOE.Value(fpar);
2859 gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
2860 Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
2861 Standard_Boolean IsPlanar = Standard_False;
2862 if (BAcurve.GetType() == GeomAbs_Circle &&
2863 BAcurveOE.GetType() == GeomAbs_Circle)
2865 gp_Circ aCirc = BAcurve.Circle();
2866 gp_Circ aCircOE = BAcurveOE.Circle();
2867 gp_Lin anAxisLine(aCirc.Axis());
2868 gp_Dir CircAxisDir = aCirc.Axis().Direction();
2869 if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) &&
2870 anAxisLine.Contains(aCircOE.Location(), Precision::Confusion()))
2871 { //cylinder, plane or cone
2872 if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder
2873 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
2874 else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane
2875 IsPlanar = Standard_True;
2877 gp_Pnt PonEL = BAcurve.Value(lpar);
2878 if (PonEL.Distance(PonE) <= Precision::PConfusion()) {
2879 Standard_Boolean bIsHole;
2880 TopoDS_Edge aE1, aE2;
2881 TopoDS_Wire aW1, aW2;
2882 Handle(Geom_Plane) aPL;
2883 IntTools_FClass2d aClsf;
2885 if (aCirc.Radius()>aCircOE.Radius()) {
2898 aPL = new Geom_Plane(aCirc.Location(), CircAxisDir);
2899 for (Standard_Integer i = 0; i < 2; ++i) {
2900 TopoDS_Wire& aW = (i==0) ? aW1 : aW2;
2901 TopoDS_Edge& aE = (i==0) ? aE1 : aE2;
2904 BB.MakeFace(aFace, aPL, Precision::Confusion());
2906 aClsf.Init(aFace, Precision::Confusion());
2907 bIsHole=aClsf.IsHole();
2908 if ((bIsHole && !i) || (!bIsHole && i)) {
2911 BB.Add(aW, aE.Reversed());
2915 BB.MakeFace(NewFace, aPL, Precision::Confusion());
2916 BB.Add(NewFace, aW1);
2917 BB.Add(NewFace, aW2);
2922 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
2923 aCirc.Radius(), aCircOE.Radius());
2924 gp_Ax3 theAx3(aCirc.Position());
2925 if (CircAxisDir * theCone.Axis().Direction() < 0.)
2928 CircAxisDir.Reverse();
2930 theCone.SetPosition(theAx3);
2931 theSurf = new Geom_ConicalSurface(theCone);
2934 TopLoc_Location Loc;
2935 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
2936 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2937 Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
2938 OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
2939 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2940 aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
2941 aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
2945 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2948 BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
2950 BB.MakeWire(theWire);
2951 BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
2952 BB.Add(theWire, E4);
2953 BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
2954 BB.Add(theWire, E3);
2955 theWire.Closed(Standard_True);
2960 BB.SameParameter(E3, Standard_False);
2961 BB.SameRange(E3, Standard_False);
2962 BB.SameParameter(E4, Standard_False);
2963 BB.SameRange(E4, Standard_False);
2964 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2965 BB.Range(E3, theSurf, Loc, 0., OffsetVal);
2966 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2967 BB.Range(E4, theSurf, Loc, 0., OffsetVal);
2969 NewFace = BRepLib_MakeFace(theSurf, theWire);
2971 } //cylinder or cone
2972 } //if both edges are arcs of circles
2973 if (NewFace.IsNull())
2975 BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
2976 if (MF.Error() == BRepLib_FaceDone)
2978 NewFace = MF.Face();
2979 IsPlanar = Standard_True;
2981 else //Extrusion (by thrusections)
2983 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
2984 Handle(Geom_TrimmedCurve) TrEdgeCurve =
2985 new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
2986 Standard_Real fparOE, lparOE;
2987 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
2988 Handle(Geom_TrimmedCurve) TrOffsetCurve =
2989 new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
2990 GeomFill_Generator ThrusecGenerator;
2991 ThrusecGenerator.AddCurve( TrEdgeCurve );
2992 ThrusecGenerator.AddCurve( TrOffsetCurve );
2993 ThrusecGenerator.Perform( Precision::PConfusion() );
2994 theSurf = ThrusecGenerator.Surface();
2995 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
2996 Standard_Real Uf, Ul, Vf, Vl;
2997 theSurf->Bounds(Uf, Ul, Vf, Vl);
2998 TopLoc_Location Loc;
2999 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
3000 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
3001 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
3002 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
3003 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
3004 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
3005 aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
3006 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
3009 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
3010 Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
3011 BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
3012 BB.Range(E3, Vf, Vl);
3016 BB.SameParameter(E3, Standard_False);
3017 BB.SameRange(E3, Standard_False);
3018 BB.SameParameter(E4, Standard_False);
3019 BB.SameRange(E4, Standard_False);
3020 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
3021 BB.Range(E3, theSurf, Loc, Vf, Vl);
3022 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
3023 BB.Range(E4, theSurf, Loc, Vf, Vl);
3024 Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
3025 BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
3026 BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
3027 Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
3028 BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
3029 BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
3031 NewFace = BRepLib_MakeFace(theSurf, theWire);
3036 Standard_Real fparOE = BAcurveOE.FirstParameter();
3037 Standard_Real lparOE = BAcurveOE.LastParameter();
3038 TopLoc_Location Loc;
3039 if (Abs(fpar - fparOE) > Precision::Confusion())
3041 const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
3042 gp_Pnt2d fp2d = EdgeLine2d->Value(fpar);
3043 gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
3044 aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
3045 Handle(Geom_Curve) aCurve;
3046 Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
3047 Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
3048 GeomAdaptor_Surface GAsurf( theSurf );
3049 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
3050 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
3051 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
3052 Standard_Real max_deviation = 0., average_deviation;
3053 GeomLib::BuildCurve3d(Precision::Confusion(),
3054 ConS, FirstPar, LastPar,
3055 aCurve, max_deviation, average_deviation);
3056 BB.UpdateEdge( anE4, aCurve, max_deviation );
3057 BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
3058 BB.Range( anE4, FirstPar, LastPar );
3060 if (Abs(lpar - lparOE) > Precision::Confusion())
3062 const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
3063 gp_Pnt2d lp2d = EdgeLine2d->Value(lpar);
3064 gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
3065 aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
3066 Handle(Geom_Curve) aCurve;
3067 Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
3068 Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
3069 GeomAdaptor_Surface GAsurf( theSurf );
3070 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
3071 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
3072 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
3073 Standard_Real max_deviation = 0., average_deviation;
3074 GeomLib::BuildCurve3d(Precision::Confusion(),
3075 ConS, FirstPar, LastPar,
3076 aCurve, max_deviation, average_deviation);
3077 BB.UpdateEdge( anE3, aCurve, max_deviation );
3078 BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
3079 BB.Range( anE3, FirstPar, LastPar );
3082 BRepLib::SameParameter(NewFace);
3083 BRepTools::Update(NewFace);
3084 myWalls.Append(NewFace);
3087 TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
3088 TopoDS_Vertex arcV1, arcV2;
3089 TopExp::Vertices(anArc, arcV1, arcV2);
3090 Standard_Boolean ArcReverse = Standard_False;
3091 if (!arcV1.IsSame(V3))
3093 TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
3094 ArcReverse = Standard_True;
3096 TopoDS_Edge EA1, EA2;
3097 //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
3102 //////////////////////////////////////////////////////
3103 if (V2.IsSame(StartVertex))
3106 EA2 = BRepLib_MakeEdge( V2, arcV2 );
3107 anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
3108 if (EA1.Orientation() == TopAbs_REVERSED)
3110 EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
3111 TopoDS_Wire arcWire;
3112 BB.MakeWire(arcWire);
3113 BB.Add(arcWire, EA1);
3114 BB.Add(arcWire, anArc);
3115 BB.Add(arcWire, EA2);
3116 BRepLib::BuildCurves3d( arcWire, myTol );
3117 arcWire.Closed(Standard_True);
3118 TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
3119 BRepTools::Update(arcFace);
3120 myWalls.Append(arcFace);
3121 TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
3122 const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
3131 FirstStep = Standard_False;
3136 //=======================================================================
3137 //function : MakeShells
3139 //=======================================================================
3141 void BRepOffset_MakeOffset::MakeShells ()
3145 cout << " RECONSTRUCTION OF SHELLS:" << endl;
3150 BRepTools_Quilt Glue;
3151 const TopTools_ListOfShape& R = myImageOffset.Roots();
3152 TopTools_ListIteratorOfListOfShape it(R);
3154 for ( ; it.More(); it.Next()) {
3155 TopTools_ListOfShape Image;
3156 myImageOffset.LastImage(it.Value(),Image);
3157 TopTools_ListIteratorOfListOfShape it2(Image);
3158 for ( ; it2.More(); it2.Next()) {
3159 Glue.Add(it2.Value());
3165 TopExp_Explorer Explo(myShape, TopAbs_FACE);
3166 for (; Explo.More(); Explo.Next())
3167 Glue.Add(Explo.Current());
3169 for (it.Initialize(myWalls); it.More(); it.Next())
3170 Glue.Add(it.Value());
3173 myOffsetShape = Glue.Shells();
3176 //=======================================================================
3177 //function : MakeSolid
3179 //=======================================================================
3181 void BRepOffset_MakeOffset::MakeSolid ()
3183 if (myOffsetShape.IsNull()) return;
3185 // Modified by skv - Mon Apr 4 18:17:27 2005 Begin
3186 // Supporting history.
3187 UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
3188 UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
3189 // Modified by skv - Mon Apr 4 18:17:27 2005 End
3190 TopExp_Explorer exp;
3192 Standard_Integer NbShell = 0;
3195 B.MakeCompound (NC);
3197 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
3198 TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
3199 if (myThickening && myOffset > 0.)
3206 Sol.Closed(Standard_True);
3208 if (NbShell == 1) S1 = Sol;
3212 if (NbShell == 1) S1 = Sh;
3215 if (NbShell == 1) myOffsetShape = S1;
3216 else myOffsetShape = NC;
3219 //=======================================================================
3220 //function : SelectShells
3222 //=======================================================================
3224 void BRepOffset_MakeOffset::SelectShells ()
3226 TopTools_MapOfShape FreeEdges;
3227 TopExp_Explorer exp(myShape,TopAbs_EDGE);
3228 //-------------------------------------------------------------
3229 // FreeEdges all edges that can have free border in the
3231 // 1 - free borders of myShape .
3232 //-------------------------------------------------------------
3233 for ( ; exp.More(); exp.Next()) {
3234 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3235 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
3236 if (LA.Extent() < 2) {
3237 if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
3242 // myShape has free borders and there are no caps
3244 if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
3246 myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
3249 //=======================================================================
3250 //function : OffsetFacesFromShapes
3252 //=======================================================================
3254 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
3256 return myInitOffsetFace;
3259 // Modified by skv - Tue Mar 15 16:20:43 2005 Begin
3261 //=======================================================================
3262 //function : GetJoinType
3263 //purpose : Query offset join type.
3264 //=======================================================================
3266 GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
3271 //=======================================================================
3272 //function : OffsetEdgesFromShapes
3274 //=======================================================================
3276 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
3278 return myInitOffsetEdge;
3281 // Modified by skv - Tue Mar 15 16:20:43 2005 End
3283 //=======================================================================
3284 //function : ClosingFaces
3286 //=======================================================================
3288 const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
3295 //=======================================================================
3296 //function : EncodeRegularity
3298 //=======================================================================
3300 void BRepOffset_MakeOffset::EncodeRegularity ()
3304 cout << " CODING OF REGULARITIES:" << endl;
3310 if (myOffsetShape.IsNull()) return;
3311 // find edges G1 in the result
3312 TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
3315 TopTools_MapOfShape MS;
3317 for ( ; exp.More(); exp.Next()) {
3318 TopoDS_Edge OE = TopoDS::Edge(exp.Current());
3319 BRepLib::BuildCurve3d(OE,myTol);
3320 TopoDS_Edge ROE = OE;
3322 if ( !MS.Add(OE)) continue;
3324 if ( myImageOffset.IsImage(OE))
3325 ROE = TopoDS::Edge(myImageOffset.Root(OE));
3327 const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
3329 if (LofOF.Extent() != 2) {
3331 cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
3336 const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
3337 const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
3339 if ( F1.IsNull() || F2.IsNull())
3342 const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
3343 const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
3345 TopAbs_ShapeEnum Type1 = Root1.ShapeType();
3346 TopAbs_ShapeEnum Type2 = Root2.ShapeType();
3348 if (F1.IsSame(F2)) {
3349 if (BRep_Tool::IsClosed(OE,F1)) {
3350 // Temporary Debug for the Bench.
3352 // In mode intersection, the edges are not coded in myInitOffsetEdge
3353 // so, manage case by case
3354 // Note DUB; for Hidden parts, it is NECESSARY to code CN
3355 // Analytic Surfaces.
3356 if (myJoin == GeomAbs_Intersection) {
3357 BRepAdaptor_Surface BS(F1,Standard_False);
3358 GeomAbs_SurfaceType SType = BS.GetType();
3359 if (SType == GeomAbs_Cylinder ||
3360 SType == GeomAbs_Cone ||
3361 SType == GeomAbs_Sphere ||
3362 SType == GeomAbs_Torus ) {
3363 B.Continuity(OE,F1,F1,GeomAbs_CN);
3366 // See YFR : MaJ of myInitOffsetFace
3369 else if (myInitOffsetEdge.IsImage(ROE)) {
3370 if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3371 const TopoDS_Face& FRoot = TopoDS::Face(Root1);
3372 const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
3373 GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
3374 if (Conti == GeomAbs_CN) {
3375 B.Continuity(OE,F1,F1,GeomAbs_CN);
3377 else if ( Conti > GeomAbs_C0) {
3378 B.Continuity(OE,F1,F1,GeomAbs_G1);
3387 // code regularities G1 between :
3388 // - sphere and tube : one root is a vertex, the other is an edge
3389 // and the vertex is included in the edge
3390 // - face and tube : one root is a face, the other an edge
3391 // and the edge is included in the face
3392 // - face and face : if two root faces are tangent in
3393 // the initial shape, they will be tangent in the offset shape
3394 // - tube and tube : if 2 edges generating tubes are
3395 // tangents, the 2 will be tangent either.
3396 if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
3397 TopoDS_Vertex V1,V2;
3398 TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
3399 if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
3400 B.Continuity(OE,F1,F2,GeomAbs_G1);
3403 else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
3404 TopoDS_Vertex V1,V2;
3405 TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
3406 if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
3407 B.Continuity(OE,F1,F2,GeomAbs_G1);
3410 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
3411 TopExp_Explorer exp2(Root1,TopAbs_EDGE);
3412 for ( ; exp2.More(); exp2.Next()) {
3413 if ( exp2.Current().IsSame(Root2)) {
3414 B.Continuity(OE,F1,F2,GeomAbs_G1);
3419 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
3420 TopExp_Explorer exp2(Root2,TopAbs_EDGE);
3421 for ( ; exp2.More(); exp2.Next()) {
3422 if ( exp2.Current().IsSame(Root1)) {
3423 B.Continuity(OE,F1,F2,GeomAbs_G1);
3428 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3429 // if two root faces are tangent in
3430 // the initial shape, they will be tangent in the offset shape
3431 TopTools_ListOfShape LE,LV;
3432 BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
3433 TopoDS::Face(Root2),
3435 if ( LE.Extent() == 1) {
3436 const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
3437 if ( myAnalyse.HasAncestor(Ed)) {
3438 const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
3439 if (LI.Extent() == 1 &&
3440 LI.First().Type() == BRepOffset_Tangent) {
3441 B.Continuity(OE,F1,F2,GeomAbs_G1);
3446 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
3447 TopTools_ListOfShape LV;
3448 TopExp_Explorer exp1,exp2;
3449 for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
3450 TopExp_Explorer exp2(F2,TopAbs_EDGE);
3451 for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
3452 if (exp1.Current().IsSame(exp2.Current())) {
3453 LV.Append(exp1.Current());
3457 if ( LV.Extent() == 1) {
3458 TopTools_ListOfShape LEdTg;
3459 myAnalyse.TangentEdges(TopoDS::Edge(Root1),
3460 TopoDS::Vertex(LV.First()),
3462 TopTools_ListIteratorOfListOfShape it(LEdTg);
3463 for (; it.More(); it.Next()) {
3464 if ( it.Value().IsSame(Root2)) {
3465 B.Continuity(OE,F1,F2,GeomAbs_G1);
3474 if ( ChronBuild) Clock.Show();
3480 //=======================================================================
3481 //function : UpDateTolerance
3483 //=======================================================================
3485 static void UpdateTolerance (TopoDS_Shape& S,
3486 const TopTools_IndexedMapOfShape& Faces)
3489 TopTools_MapOfShape View;
3492 // The edges of caps are not modified.
3494 for (j = 1; j <= Faces.Extent(); j++) {
3495 const TopoDS_Shape& F = Faces(j);
3496 TopExp_Explorer Exp;
3497 for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3498 View.Add(Exp.Current());
3502 TopExp_Explorer Exp;
3503 for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3504 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
3506 Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E);
3507 Standard_Real Tol = EdgeCorrector->Tolerance();
3508 B.UpdateEdge (E,Tol);
3510 // Update the vertices.
3511 TopExp::Vertices(E,V[0],V[1]);
3513 for (Standard_Integer i = 0 ; i <=1 ; i++) {
3514 if (View.Add(V[i])) {
3515 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
3517 Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]);
3518 B.UpdateVertex (V[i],VertexCorrector->Tolerance());
3519 // use the occasion to clean the vertices.
3520 (TV->ChangePoints()).Clear();
3522 B.UpdateVertex(V[i],Tol);