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.
19 // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455
21 #include <Adaptor3d_CurveOnSurface.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
24 #include <BRep_PointRepresentation.hxx>
25 #include <BRep_TEdge.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRep_TVertex.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <BRepAdaptor_Curve2d.hxx>
30 #include <BRepAdaptor_Surface.hxx>
31 #include <BRepAlgo_AsDes.hxx>
32 #include <BRepAlgo_Image.hxx>
33 #include <BRepCheck_Analyzer.hxx>
34 #include <BRepCheck_Edge.hxx>
35 #include <BRepCheck_Vertex.hxx>
36 #include <BRepClass3d_SolidClassifier.hxx>
37 #include <BRepGProp.hxx>
38 #include <BRepLib.hxx>
39 #include <BRepLib_FindSurface.hxx>
40 #include <BRepLib_MakeEdge.hxx>
41 #include <BRepLib_MakeFace.hxx>
42 #include <BRepLib_MakeVertex.hxx>
43 #include <BRepOffset_Analyse.hxx>
44 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
45 #include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
46 #include <BRepOffset_DataMapOfShapeOffset.hxx>
47 #include <BRepOffset_Inter2d.hxx>
48 #include <BRepOffset_Inter3d.hxx>
49 #include <BRepOffset_Interval.hxx>
50 #include <BRepOffset_ListOfInterval.hxx>
51 #include <BRepOffset_MakeLoops.hxx>
52 #include <BRepOffset_MakeOffset.hxx>
53 #include <BRepOffset_Offset.hxx>
54 #include <BRepOffset_Tool.hxx>
55 #include <BRepTools.hxx>
56 #include <BRepTools_Quilt.hxx>
57 #include <BRepTools_Substitution.hxx>
58 #include <BRepTools_WireExplorer.hxx>
61 #include <GC_MakeCylindricalSurface.hxx>
62 #include <GCE2d_MakeLine.hxx>
63 #include <gce_MakeCone.hxx>
64 #include <gce_MakeDir.hxx>
65 #include <Geom2d_Line.hxx>
66 #include <Geom2d_TrimmedCurve.hxx>
67 #include <Geom2dAdaptor_HCurve.hxx>
68 #include <Geom_Circle.hxx>
69 #include <Geom_ConicalSurface.hxx>
70 #include <Geom_CylindricalSurface.hxx>
71 #include <Geom_OffsetSurface.hxx>
72 #include <Geom_Plane.hxx>
73 #include <Geom_SphericalSurface.hxx>
74 #include <Geom_SurfaceOfLinearExtrusion.hxx>
75 #include <Geom_TrimmedCurve.hxx>
76 #include <GeomAdaptor_HSurface.hxx>
77 #include <GeomAPI_ProjectPointOnCurve.hxx>
78 #include <GeomFill_Generator.hxx>
79 #include <GeomLib.hxx>
80 #include <gp_Cone.hxx>
81 #include <gp_Lin2d.hxx>
83 #include <GProp_GProps.hxx>
84 #include <IntTools_FClass2d.hxx>
85 #include <NCollection_List.hxx>
86 #include <Precision.hxx>
87 #include <Standard_ConstructionError.hxx>
88 #include <Standard_NotImplemented.hxx>
89 #include <TColStd_ListIteratorOfListOfInteger.hxx>
91 #include <TopExp_Explorer.hxx>
93 #include <TopoDS_Compound.hxx>
94 #include <TopoDS_Edge.hxx>
95 #include <TopoDS_Face.hxx>
96 #include <TopoDS_Iterator.hxx>
97 #include <TopoDS_Shape.hxx>
98 #include <TopoDS_Shell.hxx>
99 #include <TopoDS_Solid.hxx>
100 #include <TopoDS_Vertex.hxx>
101 #include <TopoDS_Wire.hxx>
102 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
103 #include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
104 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
105 #include <TopTools_DataMapOfShapeShape.hxx>
106 #include <TopTools_IndexedMapOfShape.hxx>
107 #include <TopTools_ListIteratorOfListOfShape.hxx>
108 #include <TopTools_ListOfShape.hxx>
109 #include <TopTools_MapIteratorOfMapOfShape.hxx>
110 #include <TopTools_MapOfShape.hxx>
111 #include <TopTools_SequenceOfShape.hxx>
112 #include <BRepBuilderAPI_Sewing.hxx>
113 #include <Geom_Line.hxx>
114 #include <NCollection_Vector.hxx>
115 #include <NCollection_IncAllocator.hxx>
117 #include <BOPAlgo_MakerVolume.hxx>
118 #include <BOPTools_AlgoTools.hxx>
127 #include <OSD_Chronometer.hxx>
129 Standard_Boolean AffichInt2d = Standard_False;
130 Standard_Boolean AffichOffC = Standard_False;
131 Standard_Boolean ChronBuild = Standard_False;
132 Standard_Integer NbAE = 0;
133 Standard_Integer NbAF = 0;
134 Standard_Integer NVP = 0;
135 Standard_Integer NVM = 0;
136 Standard_Integer NVN = 0;
137 static OSD_Chronometer Clock;
143 //=======================================================================
144 //function : DEBVerticesControl
146 //=======================================================================
148 static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
149 Handle(BRepAlgo_AsDes) AsDes)
151 TopTools_ListOfShape LVP;
152 TopTools_ListIteratorOfListOfShape it1LE ;
153 TopTools_ListIteratorOfListOfShape it2LE ;
156 for (i = 1; i <= NewEdges.Extent(); i++) {
157 const TopoDS_Edge& NE = TopoDS::Edge(NewEdges(i));
158 if (AsDes->HasDescendant(NE)) {
159 for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
160 if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
161 LVP.Append(it1LE.Value());
162 std::cout <<"Vertex on at least 3 edges."<<std::endl;
165 sprintf (name,"VP_%d",NVP++);
166 DBRep::Set(name,it1LE.Value());
170 else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
171 std::cout <<"Vertex on more than 3 edges."<<std::endl;
174 sprintf (name,"VM_%d",NVM++);
175 DBRep::Set(name,it1LE.Value());
183 sprintf (name,"VN_%d",NVN++);
184 DBRep::Set(name,it1LE.Value());
191 //------------------------------------------------
192 // Try to mix spoiled vertices.
193 //------------------------------------------------
195 TopTools_ListIteratorOfListOfShape it1(LVP);
196 Standard_Real TolConf = 1.e-5;
197 Standard_Real Tol = Precision::Confusion();
198 //Standard_Integer i = 1;
201 for ( ; it1.More(); it1.Next()) {
202 TopoDS_Shape V1 = it1.Value();
203 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(V1));
204 Standard_Real distmin = Precision::Infinite();
205 TopTools_ListIteratorOfListOfShape it2(LVP);
206 Standard_Integer j = 1;
208 for ( ; it2.More(); it2.Next()) {
210 TopoDS_Shape V2 = it2.Value();
211 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2));
212 if (!V1.IsSame(V2)) {
213 Standard_Real dist = P1.Distance(P2);
214 if (dist < distmin) distmin = dist;
215 if (dist < TolConf) {
218 const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
219 TopTools_ListIteratorOfListOfShape itAsDes;
220 for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) {
221 EWE2 = TopoDS::Edge(itAsDes.Value());
222 TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL);
223 UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
224 aLocalShape = V1.Oriented(TopAbs_INTERNAL) ;
225 B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
227 // BRep_Tool::Parameter(TopoDS::Vertex(),EWE2);
228 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
231 AsDes->Replace(V2,V1);
238 std::cout <<" distmin between VP : "<<distmin<<std::endl;
244 //=======================================================================
246 //=======================================================================
248 void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
249 const BRepOffset_DataMapOfShapeOffset& theMapSF,
250 const TopTools_DataMapOfShapeShape& theMES,
251 TopTools_DataMapOfShapeShape& theFacesOrigins,
252 BRepAlgo_Image& theImage,
253 TopTools_ListOfShape& theLSF);
256 Standard_Boolean BuildShellsCompleteInter(const TopTools_ListOfShape& theLF,
257 BRepAlgo_Image& theImage,
258 TopoDS_Shape& theShells);
261 Standard_Boolean GetSubShapes(const TopoDS_Shape& theShape,
262 const TopAbs_ShapeEnum theSSType,
263 TopoDS_Shape& theResult);
266 void UpdateInitOffset(BRepAlgo_Image& myInitOffset,
267 BRepAlgo_Image& myImageOffset,
268 const TopoDS_Shape& myOffsetShape,
269 const TopAbs_ShapeEnum &theShapeType);
272 void RemoveShapes(TopoDS_Shape& theS,
273 const TopTools_ListOfShape& theLS);
276 Standard_Boolean IsSolid(const TopoDS_Shape& theS);
279 void UpdateHistory(const TopTools_ListOfShape& theLF,
280 BOPAlgo_Builder& theGF,
281 BRepAlgo_Image& theImage);
284 Standard_Boolean IsPlanar(const TopoDS_Shape& theS);
287 Standard_Boolean TrimEdge(TopoDS_Edge& NE,
288 const Handle(BRepAlgo_AsDes)& AsDes2d,
289 Handle(BRepAlgo_AsDes)& AsDes,
290 TopTools_DataMapOfShapeShape& theETrimEInf);
293 Standard_Boolean TrimEdges(const TopoDS_Shape& theShape,
294 const Standard_Real theOffset,
295 const BRepOffset_Analyse& Analyse,
296 BRepOffset_DataMapOfShapeOffset& theMapSF,
297 TopTools_DataMapOfShapeShape& theMES,
298 TopTools_DataMapOfShapeShape& theBuild,
299 Handle(BRepAlgo_AsDes)& theAsDes,
300 Handle(BRepAlgo_AsDes)& theAsDes2d,
301 TopTools_IndexedMapOfShape& theNewEdges,
302 TopTools_DataMapOfShapeShape& theETrimEInf,
303 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins);
306 void AppendToList(TopTools_ListOfShape& theL,
307 const TopoDS_Shape& theS);
309 static BRepOffset_Error checkSinglePoint(const Standard_Real theUParam,
310 const Standard_Real theVParam,
311 const Handle(Geom_Surface)& theSurf,
312 const NCollection_Vector<gp_Pnt>& theBadPoints);
314 //---------------------------------------------------------------------
315 static void UpdateTolerance ( TopoDS_Shape& myShape,
316 const TopTools_IndexedMapOfShape& myFaces);
317 static Standard_Real ComputeMaxDist(const gp_Pln& thePlane,
318 const Handle(Geom_Curve)& theCrv,
319 const Standard_Real theFirst,
320 const Standard_Real theLast);
322 static void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList);
323 //---------------------------------------------------------------------
325 static TopAbs_Orientation OrientationOfEdgeInFace(const TopoDS_Edge& theEdge,
326 const TopoDS_Face& theFace)
328 TopAbs_Orientation anOr = TopAbs_EXTERNAL;
330 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
331 for (; Explo.More(); Explo.Next())
333 const TopoDS_Shape& anEdge = Explo.Current();
334 if (anEdge.IsSame(theEdge))
336 anOr = anEdge.Orientation();
345 static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
346 const TopoDS_Edge& E,
349 // Search the vertex in the edge
351 Standard_Boolean rev = Standard_False;
353 TopAbs_Orientation orient = TopAbs_INTERNAL;
355 TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
357 // if the edge has no vertices
358 // and is degenerated use the vertex orientation
361 if (!itv.More() && BRep_Tool::Degenerated(E)) {
362 orient = V.Orientation();
366 const TopoDS_Shape& Vcur = itv.Value();
367 if (V.IsSame(Vcur)) {
372 rev = E.Orientation() == TopAbs_REVERSED;
373 if (Vcur.Orientation() == V.Orientation()) {
381 if (!VF.IsNull()) orient = VF.Orientation();
385 if (orient == TopAbs_FORWARD) {
386 BRep_Tool::Range(E,f,l);
387 //return (rev) ? l : f;
389 return Standard_True;
392 else if (orient == TopAbs_REVERSED) {
393 BRep_Tool::Range(E,f,l);
394 //return (rev) ? f : l;
396 return Standard_True;
401 const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
402 L = L.Predivided(V.Location());
403 if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
404 BRep_ListIteratorOfListOfPointRepresentation itpr
405 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
407 while (itpr.More()) {
408 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
409 if (pr->IsPointOnCurve(C,L)) {
410 Standard_Real p = pr->Parameter();
411 Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
413 // Closed curves RLE 16 june 94
414 if (Precision::IsNegativeInfinite(f))
416 //return pr->Parameter();//p;
418 return Standard_True;
420 if (Precision::IsPositiveInfinite(l))
422 //return pr->Parameter();//p;
424 return Standard_True;
426 gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
427 gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
428 Standard_Real tol = BRep_Tool::Tolerance(V);
429 if (Pf.Distance(Pl) < tol) {
430 if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
431 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
432 else res = l;//p = l;
438 return Standard_True;
445 // let us try with the first pcurve
446 Handle(Geom2d_Curve) PC;
447 Handle(Geom_Surface) S;
448 BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
449 L = L.Predivided(V.Location());
450 BRep_ListIteratorOfListOfPointRepresentation itpr
451 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
453 while (itpr.More()) {
454 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
455 if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
456 Standard_Real p = pr->Parameter();
457 // Closed curves RLE 16 june 94
458 if (PC->IsClosed()) {
459 if ((p == PC->FirstParameter()) ||
460 (p == PC->LastParameter())) {
461 if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
462 else p = PC->LastParameter();
467 return Standard_True;
474 //throw Standard_NoSuchObject("BRep_Tool:: no parameter on edge");
475 return Standard_False;
478 //=======================================================================
479 //function : GetEdgePoints
480 //purpose : gets the first, last and middle points of the edge
481 //=======================================================================
482 static void GetEdgePoints(const TopoDS_Edge& anEdge,
483 const TopoDS_Face& aFace,
484 gp_Pnt& fPnt, gp_Pnt& mPnt,
488 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
489 gp_Pnt2d fPnt2d = theCurve->Value(f);
490 gp_Pnt2d lPnt2d = theCurve->Value(l);
491 gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
492 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
493 fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
494 lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
495 mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
498 //=======================================================================
499 //function : FillContours
500 //purpose : fills free boundary contours and faces connected (MapEF)
501 //=======================================================================
502 static void FillContours(const TopoDS_Shape& aShape,
503 const BRepOffset_Analyse& Analyser,
504 TopTools_IndexedDataMapOfShapeListOfShape& Contours,
505 TopTools_DataMapOfShapeShape& MapEF)
507 TopTools_ListOfShape Edges;
509 TopExp_Explorer Explo(aShape, TopAbs_FACE);
510 BRepTools_WireExplorer Wexp;
512 for (; Explo.More(); Explo.Next())
514 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
515 TopoDS_Iterator itf(aFace);
516 for (; itf.More(); itf.Next())
518 TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
519 for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
521 TopoDS_Edge anEdge = Wexp.Current();
522 if (BRep_Tool::Degenerated(anEdge))
524 const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
525 if (!Lint.IsEmpty() && Lint.First().Type() == ChFiDS_FreeBound)
527 MapEF.Bind(anEdge, aFace);
528 Edges.Append(anEdge);
534 TopTools_ListIteratorOfListOfShape itl;
535 while (!Edges.IsEmpty())
537 TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
539 TopoDS_Vertex StartVertex, CurVertex;
540 TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
541 TopTools_ListOfShape aContour;
542 aContour.Append(StartEdge);
543 while (!CurVertex.IsSame(StartVertex))
544 for (itl.Initialize(Edges); itl.More(); itl.Next())
546 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
547 TopoDS_Vertex V1, V2;
548 TopExp::Vertices(anEdge, V1, V2);
549 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
551 aContour.Append(anEdge);
552 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
557 Contours.Add(StartVertex, aContour);
562 //-----------------------------------------------------------------------
564 //=======================================================================
565 //function : BRepOffset_MakeOffset
567 //=======================================================================
569 BRepOffset_MakeOffset::BRepOffset_MakeOffset()
571 myAsDes = new BRepAlgo_AsDes();
575 //=======================================================================
576 //function : BRepOffset_MakeOffset
578 //=======================================================================
580 BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S,
581 const Standard_Real Offset,
582 const Standard_Real Tol,
583 const BRepOffset_Mode Mode,
584 const Standard_Boolean Inter,
585 const Standard_Boolean SelfInter,
586 const GeomAbs_JoinType Join,
587 const Standard_Boolean Thickening,
588 const Standard_Boolean RemoveIntEdges)
595 mySelfInter (SelfInter),
597 myThickening (Thickening),
598 myRemoveIntEdges(RemoveIntEdges),
599 myDone (Standard_False)
601 myAsDes = new BRepAlgo_AsDes();
606 //=======================================================================
607 //function : Initialize
609 //=======================================================================
611 void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
612 const Standard_Real Offset,
613 const Standard_Real Tol,
614 const BRepOffset_Mode Mode,
615 const Standard_Boolean Inter,
616 const Standard_Boolean SelfInter,
617 const GeomAbs_JoinType Join,
618 const Standard_Boolean Thickening,
619 const Standard_Boolean RemoveIntEdges)
626 mySelfInter = SelfInter;
628 myThickening = Thickening;
629 myRemoveIntEdges = RemoveIntEdges;
630 myDone = Standard_False;
631 myIsPerformSewing = Standard_False;
632 myIsPlanar = Standard_False;
637 //=======================================================================
640 //=======================================================================
642 void BRepOffset_MakeOffset::Clear()
644 myOffsetShape.Nullify();
645 myInitOffsetFace .Clear();
646 myInitOffsetEdge .Clear();
647 myImageOffset .Clear();
649 myFaceOffset .Clear();
651 myDone = Standard_False;
656 //=======================================================================
659 //=======================================================================
661 void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
666 myInitOffsetFace.SetRoot (F) ;
667 myInitOffsetFace.Bind (F,F);
668 myImageOffset.SetRoot (F) ;
671 //=======================================================================
672 //function : SetOffsetOnFace
674 //=======================================================================
676 void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F,
677 const Standard_Real Off)
679 if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
680 myFaceOffset.Bind(F,Off);
683 //=======================================================================
684 //function : RemoveCorks
686 //=======================================================================
688 static void RemoveCorks (TopoDS_Shape& S,
689 TopTools_IndexedMapOfShape& Faces)
694 //-----------------------------------------------------
695 // Construction of a shape without caps.
696 // and Orientation of caps as in shape S.
697 //-----------------------------------------------------
698 TopExp_Explorer exp(S,TopAbs_FACE);
699 for (; exp.More(); exp.Next()) {
700 const TopoDS_Shape& Cork = exp.Current();
701 if (!Faces.Contains(Cork)) {
705 Faces.RemoveKey(Cork);
706 Faces.Add(Cork); // to reset it with proper orientation.
712 DBRep::Set("myInit", SS);
717 //=======================================================================
718 //function : IsConnectedShell
720 //=======================================================================
721 static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
723 BRepTools_Quilt Glue;
726 TopoDS_Shape SS = Glue.Shells();
727 TopExp_Explorer Explo( SS, TopAbs_SHELL );
730 return Standard_False;
732 return Standard_True;
736 //=======================================================================
737 //function : MakeList
739 //=======================================================================
741 static void MakeList (TopTools_ListOfShape& OffsetFaces,
742 const BRepAlgo_Image& myInitOffsetFace,
743 const TopTools_IndexedMapOfShape& myFaces)
745 TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
746 for ( ; itLOF.More(); itLOF.Next()) {
747 const TopoDS_Shape& Root = itLOF.Value();
748 if (!myFaces.Contains(Root)) {
749 if (myInitOffsetFace.HasImage(Root)) {
750 TopTools_ListIteratorOfListOfShape aItLS(myInitOffsetFace.Image(Root));
751 for (; aItLS.More(); aItLS.Next()) {
752 OffsetFaces.Append(aItLS.Value());
759 //=======================================================================
762 //=======================================================================
764 static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
767 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
768 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
769 Standard_Real TolV = BRep_Tool::Tolerance(V);
770 if (TolV > Tol) Tol = TolV;
775 //=======================================================================
776 //function : MakeOffsetShape
778 //=======================================================================
780 void BRepOffset_MakeOffset::MakeOffsetShape()
782 myDone = Standard_False;
784 // check if shape consists of only planar faces
785 myIsPlanar = IsPlanar(myShape);
786 //------------------------------------------
787 // Construction of myShape without caps.
788 //------------------------------------------
789 if(!myFaces.IsEmpty())
791 RemoveCorks (myShape,myFaces);
794 if (!CheckInputData())
796 // There is error in input data.
797 // Check Error() method.
800 myError = BRepOffset_NoError;
801 TopAbs_State Side = TopAbs_IN;
802 if (myOffset < 0.) Side = TopAbs_OUT;
807 EvalMax(myShape,myTol);
808 // There are possible second variant: analytical continuation of arcsin.
809 Standard_Real TolAngleCoeff = Min(myTol / (Abs(myOffset * 0.5) + Precision::Confusion()), 1.0);
810 Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
811 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar)
813 myAnalyse.SetOffsetValue (myOffset);
814 myAnalyse.SetFaceOffsetMap (myFaceOffset);
816 myAnalyse.Perform(myShape,TolAngle);
817 //---------------------------------------------------
818 // Construction of Offset from preanalysis.
819 //---------------------------------------------------
820 //----------------------------
821 // MaJ of SD Face - Offset
822 //----------------------------
825 if (myJoin == GeomAbs_Arc)
827 else if (myJoin == GeomAbs_Intersection)
828 BuildOffsetByInter();
829 if (myError != BRepOffset_NoError)
836 // if (mySelfInter) SelfInter(Modif);
840 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
841 Intersection3D (Inter);
845 TopTools_IndexedMapOfShape& Modif = Inter.TouchedFaces();
846 TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
848 if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
849 //-------------------------------------------------------
850 // Unwinding 2D and reconstruction of modified faces
851 //----------------------------------------------------
853 //-----------------------------------------------------
854 // Reconstruction of non modified faces sharing
855 // reconstructed edges
856 //------------------------------------------------------
857 if (!Modif.IsEmpty()) MakeFaces (Modif);
862 //-------------------------
863 // Construction of shells.
864 //-------------------------
866 if (myOffsetShape.IsNull()) {
868 myDone = Standard_False;
875 //----------------------------------
876 // Remove INTERNAL edges if necessary
877 //----------------------------------
878 if (myRemoveIntEdges) {
879 RemoveInternalEdges();
881 //----------------------------------
882 // Coding of regularities.
883 //----------------------------------
885 //----------------------------------
886 // Replace roots in history maps
887 //----------------------------------
889 //----------------------
890 // Creation of solids.
891 //----------------------
894 //-----------------------------
895 // MAJ Tolerance edge and Vertex
896 // ----------------------------
897 if (!myOffsetShape.IsNull()) {
898 UpdateTolerance (myOffsetShape,myFaces);
899 BRepLib::UpdateTolerances( myOffsetShape );
902 CorrectConicalFaces();
904 // Result solid should be computed in MakeOffset scope.
908 BRepBuilderAPI_Sewing aSew(myTol);
909 aSew.Add(myOffsetShape);
911 myOffsetShape = aSew.SewedShape();
914 // Offset shape expected to be really closed after sewing.
915 myOffsetShape.Closed(Standard_True);
919 myDone = Standard_True;
924 //=======================================================================
925 //function : MakeThickSolid
927 //=======================================================================
929 void BRepOffset_MakeOffset::MakeThickSolid()
931 //--------------------------------------------------------------
932 // Construction of shell parallel to shell (initial without cap).
933 //--------------------------------------------------------------
938 // Save return code and myDone state.
942 //--------------------------------------------------------------------
943 // Construction of a solid with the initial shell, parallel shell
945 //--------------------------------------------------------------------
946 if (!myFaces.IsEmpty())
951 Standard_Integer NbF = myFaces.Extent();
955 BRepTools_Quilt Glue;
956 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next())
959 Glue.Add (exp.Current());
961 Standard_Boolean YaResult = 0;
962 if (!myOffsetShape.IsNull())
964 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next())
967 Glue.Add (exp.Current().Reversed());
972 std::cout << "OffsetShape does not contain a FACES." << std::endl;
979 std::cout << "OffsetShape is null!" << std::endl;
985 myDone = Standard_False;
986 myError = BRepOffset_UnknownError;
990 myOffsetShape = Glue.Shells();
991 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next())
993 B.Add(Res,exp.Current());
995 Res.Closed(Standard_True);
998 // Test of Validity of the result of thick Solid
999 // more face than the initial solid.
1000 Standard_Integer NbOF = 0;
1001 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next())
1007 myDone = Standard_False;
1008 myError = BRepOffset_UnknownError;
1013 if (myOffset > 0 ) myOffsetShape.Reverse();
1015 myDone = Standard_True;
1018 //=======================================================================
1021 //=======================================================================
1023 Standard_Boolean BRepOffset_MakeOffset::IsDone() const
1028 //=======================================================================
1031 //=======================================================================
1033 BRepOffset_Error BRepOffset_MakeOffset::Error() const
1038 //=======================================================================
1041 //=======================================================================
1043 const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const
1045 return myOffsetShape;
1048 //=======================================================================
1049 //function : MakeOffsetFaces
1051 //=======================================================================
1052 void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& theMapSF)
1054 Standard_Real aCurOffset;
1055 TopTools_ListOfShape aLF;
1056 TopTools_DataMapOfShapeShape ShapeTgt;
1057 TopTools_ListIteratorOfListOfShape aItLF;
1059 Standard_Boolean OffsetOutside = (myOffset > 0.);
1061 BRepLib::SortFaces(myShape, aLF);
1063 aItLF.Initialize(aLF);
1064 for (; aItLF.More(); aItLF.Next()) {
1065 const TopoDS_Face& aF = TopoDS::Face(aItLF.Value());
1066 aCurOffset = myFaceOffset.IsBound(aF) ? myFaceOffset(aF) : myOffset;
1067 BRepOffset_Offset OF(aF, aCurOffset, ShapeTgt, OffsetOutside, myJoin);
1068 TopTools_ListOfShape Let;
1069 myAnalyse.Edges(aF,ChFiDS_Tangential,Let);
1070 TopTools_ListIteratorOfListOfShape itl(Let);
1071 for (; itl.More(); itl.Next()) {
1072 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
1073 if ( !ShapeTgt.IsBound(Cur) && !myAnalyse.HasGenerated (Cur)) {
1074 TopoDS_Shape aLocalShape = OF.Generated(Cur);
1075 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1076 ShapeTgt.Bind(Cur,OF.Generated(Cur));
1077 TopoDS_Vertex V1,V2,OV1,OV2;
1078 TopExp::Vertices (Cur,V1,V2);
1079 TopExp::Vertices (OTE,OV1,OV2);
1080 TopTools_ListOfShape LE;
1081 if (!ShapeTgt.IsBound(V1)) {
1082 myAnalyse.Edges(V1,ChFiDS_Tangential,LE);
1083 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
1084 if (LE.Extent() == LA.Extent())
1085 ShapeTgt.Bind(V1,OV1);
1087 if (!ShapeTgt.IsBound(V2)) {
1089 myAnalyse.Edges(V2,ChFiDS_Tangential,LE);
1090 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
1091 if (LE.Extent() == LA.Extent())
1092 ShapeTgt.Bind(V2,OV2);
1096 theMapSF.Bind(aF,OF);
1099 const TopTools_ListOfShape& aNewFaces = myAnalyse.NewFaces();
1100 for (TopTools_ListOfShape::Iterator it (aNewFaces); it.More(); it.Next())
1102 const TopoDS_Face& aF = TopoDS::Face (it.Value());
1103 BRepOffset_Offset OF(aF, 0.0, ShapeTgt, OffsetOutside, myJoin);
1104 theMapSF.Bind (aF, OF);
1108 //=======================================================================
1109 //function : BuildOffsetByInter
1111 //=======================================================================
1112 void BRepOffset_MakeOffset::BuildOffsetByInter()
1116 std::cout << " CONSTRUCTION OF OFFSETS :" << std::endl;
1122 TopExp_Explorer Exp, Exp2, ExpC;
1123 TopTools_ListIteratorOfListOfShape itLF;
1125 //--------------------------------------------------------
1126 // Construction of faces parallel to initial faces
1127 //--------------------------------------------------------
1128 BRepOffset_DataMapOfShapeOffset MapSF;
1129 MakeOffsetFaces(MapSF);
1130 //--------------------------------------------------------------------
1131 // MES : Map of OffsetShape -> Extended Shapes.
1132 // Build : Map of Initial SS -> OffsetShape build by Inter.
1133 // can be an edge or a compound of edges
1134 //---------------------------------------------------------------------
1135 TopTools_DataMapOfShapeShape MES;
1136 TopTools_DataMapOfShapeShape Build;
1137 TopTools_ListOfShape Failed;
1138 TopAbs_State Side = TopAbs_IN;
1139 Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
1141 //-------------------------------------------------------------------
1142 // Extension of faces and calculation of new edges of intersection.
1143 //-------------------------------------------------------------------
1144 Standard_Boolean ExtentContext = 0;
1145 if (myOffset > 0) ExtentContext = 1;
1147 BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
1148 // Intersection between parallel faces
1149 Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
1150 // Intersection with caps.
1151 Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
1153 TopTools_ListOfShape aLFaces;
1154 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next())
1155 aLFaces.Append (Exp.Current());
1156 for (TopTools_ListOfShape::Iterator it (myAnalyse.NewFaces()); it.More(); it.Next())
1157 aLFaces.Append (it.Value());
1158 //---------------------------------------------------------------------------------
1159 // Extension of neighbor edges of new edges and intersection between neighbors.
1160 //--------------------------------------------------------------------------------
1161 Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
1162 IntersectEdges(aLFaces, MapSF, MES, Build, AsDes, AsDes2d);
1163 if (myError != BRepOffset_NoError)
1167 //-----------------------------------------------------------
1168 // Great restriction of new edges and update of AsDes.
1169 //------------------------------------------ ----------------
1170 TopTools_DataMapOfShapeListOfShape anEdgesOrigins; // offset edge - initial edges
1171 TopTools_IndexedMapOfShape NewEdges;
1172 TopTools_DataMapOfShapeShape aETrimEInf; // trimmed - not trimmed edges
1174 //Map of edges obtained after FACE-FACE (offsetted) intersection.
1175 //Key1 is edge trimmed by intersection points with other edges;
1176 //Item is not-trimmed edge.
1177 if (!TrimEdges(myShape, myOffset, myAnalyse, MapSF, MES, Build, AsDes, AsDes2d, NewEdges, aETrimEInf, anEdgesOrigins))
1179 myError = BRepOffset_CannotTrimEdges;
1183 //---------------------------------
1184 // Intersection 2D on //
1185 //---------------------------------
1186 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
1187 TopTools_DataMapOfShapeShape aFacesOrigins; // offset face - initial face
1188 TopTools_ListOfShape LFE;
1189 BRepAlgo_Image IMOE;
1190 GetEnlargedFaces(aLFaces, MapSF, MES, aFacesOrigins, IMOE, LFE);
1192 TopTools_ListIteratorOfListOfShape itLFE(LFE);
1193 for (; itLFE.More(); itLFE.Next())
1195 const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
1196 Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
1197 BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
1199 //----------------------------------------------
1200 // Intersections 2d on caps.
1201 //----------------------------------------------
1203 for (i = 1; i <= myFaces.Extent(); i++)
1205 const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
1206 Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
1207 BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
1210 BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
1211 //-------------------------------
1212 // Unwinding of extended Faces.
1213 //-------------------------------
1215 TopTools_MapOfShape aMFDone;
1217 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
1218 BuildSplitsOfExtendedFaces(LFE, myAnalyse, AsDes, anEdgesOrigins, aFacesOrigins, aETrimEInf, IMOE);
1220 TopTools_ListIteratorOfListOfShape aItLF(LFE);
1221 for (; aItLF.More(); aItLF.Next()) {
1222 const TopoDS_Shape& aS = aItLF.Value();
1227 myMakeLoops.Build(LFE, AsDes, IMOE);
1231 TopTools_IndexedMapOfShape COES;
1233 //---------------------------
1234 // MAJ SD. for faces //
1235 //---------------------------
1236 for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
1238 const TopoDS_Shape& FI = it.Value();
1239 myInitOffsetFace.SetRoot(FI);
1240 TopoDS_Face OF = MapSF(FI).Face();
1241 if (MES.IsBound(OF)) {
1242 OF = TopoDS::Face(MES(OF));
1243 if (IMOE.HasImage(OF)) {
1244 const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
1245 myInitOffsetFace.Bind(FI,LOFE);
1246 for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
1247 const TopoDS_Shape& OFE = itLF.Value();
1248 myImageOffset.SetRoot(OFE);
1251 sprintf(name,"AF_%d",NbAF++);
1252 DBRep::Set(name,OFE);
1255 TopTools_MapOfShape View;
1256 for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1257 Exp2.More(); Exp2.Next()) {
1258 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1260 myAsDes->Add (OFE,COE);
1263 sprintf(name,"AE_%d",NbAE++);
1264 DBRep::Set(name,COE);
1269 if (!myAsDes->HasDescendant(COE)) {
1270 TopoDS_Vertex CV1,CV2;
1271 TopExp::Vertices(COE,CV1,CV2);
1272 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1273 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1280 if (aMFDone.Contains(OF)) {
1284 myInitOffsetFace.Bind(FI,OF);
1285 myImageOffset.SetRoot(OF);
1288 sprintf(name,"AF_%d",NbAF++);
1289 DBRep::Set(name,OF);
1292 const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
1293 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1294 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1295 if (IMOE.HasImage(OE)) {
1296 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1297 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1298 for (; itLOE.More(); itLOE.Next()) {
1299 TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
1300 const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
1301 // const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
1302 myAsDes->Add(OF,COE);
1305 sprintf(name,"AE_%d",NbAE++);
1306 DBRep::Set(name,COE);
1311 if (!myAsDes->HasDescendant(COE)) {
1312 TopoDS_Vertex CV1,CV2;
1313 TopExp::Vertices(COE,CV1,CV2);
1314 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1315 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1320 myAsDes->Add(OF,OE);
1323 sprintf(name,"AE_%d",NbAE++);
1324 DBRep::Set(name,OE);
1329 const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
1330 myAsDes->Add(OE,LV);
1336 myInitOffsetFace.Bind(FI,OF);
1337 myImageOffset.SetRoot(OF);
1338 TopTools_MapOfShape View;
1339 for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1340 Exp2.More(); Exp2.Next()) {
1342 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1343 myAsDes->Add (OF,COE);
1346 sprintf(name,"AE_%d",NbAE++);
1347 DBRep::Set(name,COE);
1352 if (View.Add(Exp2.Current())) {
1353 if (!myAsDes->HasDescendant(COE)) {
1354 TopoDS_Vertex CV1,CV2;
1355 TopExp::Vertices(COE,CV1,CV2);
1356 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1357 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1363 // Modified by skv - Tue Mar 15 16:20:43 2005
1364 // Add methods for supporting history.
1365 TopTools_MapOfShape aMapEdges;
1367 for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
1369 const TopoDS_Shape& aFaceRef = it.Value();
1370 Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1372 for (; Exp2.More(); Exp2.Next()) {
1373 const TopoDS_Shape& anEdgeRef = Exp2.Current();
1375 if (aMapEdges.Add(anEdgeRef)) {
1376 myInitOffsetEdge.SetRoot(anEdgeRef);
1377 if (Build.IsBound(anEdgeRef)) {
1378 TopoDS_Shape aNewShape = Build(anEdgeRef);
1380 if (aNewShape.ShapeType() == TopAbs_EDGE) {
1381 if (IMOE.HasImage(aNewShape)) {
1382 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
1384 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1386 myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
1387 } else { // aNewShape != TopAbs_EDGE
1388 TopTools_ListOfShape aListNewEdge;
1390 for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1391 const TopoDS_Shape &aResEdge = ExpC.Current();
1393 if (IMOE.HasImage(aResEdge)) {
1394 const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
1395 TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
1397 for (; aNewEIter.More(); aNewEIter.Next())
1398 aListNewEdge.Append(aNewEIter.Value());
1400 aListNewEdge.Append(aResEdge);
1403 myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
1406 else { // Free boundary.
1407 TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
1409 if (MES.IsBound(aNewEdge))
1410 aNewEdge = MES(aNewEdge);
1412 if (IMOE.HasImage(aNewEdge)) {
1413 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
1415 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1417 myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
1422 // Modified by skv - Tue Mar 15 16:20:43 2005
1424 //---------------------------
1426 //---------------------------
1427 //TopTools_MapOfShape View;
1428 for (i = 1; i <= myFaces.Extent(); i++) {
1429 const TopoDS_Shape& Cork = myFaces(i);
1430 const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
1431 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1432 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1433 if (IMOE.HasImage(OE)) {
1434 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1435 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1436 for (; itLOE.More(); itLOE.Next()) {
1437 const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
1438 myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
1441 sprintf(name,"AE_%d",NbAE++);
1442 DBRep::Set(name,COE);
1447 if (!myAsDes->HasDescendant(COE)) {
1448 TopoDS_Vertex CV1,CV2;
1449 TopExp::Vertices(COE,CV1,CV2);
1450 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1451 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1456 myAsDes->Add(Cork,OE);
1457 if (AsDes->HasDescendant(OE)) {
1458 myAsDes->Add(OE,AsDes->Descendant(OE));
1462 sprintf(name,"AE_%d",NbAE++);
1463 DBRep::Set(name,OE);
1472 DEBVerticesControl (COES,myAsDes);
1473 if ( ChronBuild) Clock.Show();
1478 //=======================================================================
1479 //function : ReplaceRoots
1481 //=======================================================================
1482 void BRepOffset_MakeOffset::ReplaceRoots()
1484 // Replace the artificial faces and edges in InitOffset maps with the original ones.
1485 TopTools_MapOfShape View;
1486 for (TopExp_Explorer anExpF (myShape, TopAbs_EDGE); anExpF.More(); anExpF.Next())
1488 const TopoDS_Shape& aF = anExpF.Current();
1489 for (TopExp_Explorer anExpE (aF, TopAbs_EDGE); anExpE.More(); anExpE.Next())
1491 const TopoDS_Shape& aE = anExpE.Current();
1495 TopoDS_Shape aFGen = myAnalyse.Generated (aE);
1499 myInitOffsetFace.ReplaceRoot (aFGen, aE);
1501 for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
1503 const TopoDS_Shape& aV = itV.Value();
1507 TopoDS_Shape aEGen = myAnalyse.Generated (aV);
1511 myInitOffsetEdge.ReplaceRoot (aEGen, aV);
1517 //=======================================================================
1518 //function : BuildOffsetByArc
1520 //=======================================================================
1521 void BRepOffset_MakeOffset::BuildOffsetByArc()
1525 std::cout << " CONSTRUCTION OF OFFSETS :" << std::endl;
1531 TopExp_Explorer Exp;
1532 TopTools_ListIteratorOfListOfShape itLF;
1533 TopTools_MapOfShape Done;
1535 //--------------------------------------------------------
1536 // Construction of faces parallel to initial faces
1537 //--------------------------------------------------------
1538 BRepOffset_DataMapOfShapeOffset MapSF;
1539 MakeOffsetFaces(MapSF);
1540 //--------------------------------------------------------
1541 // Construction of tubes on edge.
1542 //--------------------------------------------------------
1543 ChFiDS_TypeOfConcavity OT = ChFiDS_Convex;
1544 if (myOffset < 0.) OT = ChFiDS_Concave;
1546 for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1547 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1549 const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
1550 if (Anc.Extent() == 2) {
1551 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1552 if (!L.IsEmpty() && L.First().Type() == OT) {
1553 Standard_Real CurOffset = myOffset;
1554 if ( myFaceOffset.IsBound(Anc.First()))
1555 CurOffset = myFaceOffset(Anc.First());
1556 TopoDS_Shape aLocalShapeGen = MapSF(Anc.First()).Generated(E);
1557 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShapeGen);
1558 aLocalShapeGen = MapSF(Anc.Last()).Generated(E);
1559 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShapeGen);
1560 // TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1561 // TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
1562 // find if exits tangent edges in the original shape
1563 TopoDS_Edge E1f, E1l;
1564 TopoDS_Vertex V1f, V1l;
1565 TopExp::Vertices(E,V1f,V1l);
1566 TopTools_ListOfShape TangE;
1567 myAnalyse.TangentEdges(E,V1f,TangE);
1568 // find if the pipe on the tangent edges are soon created.
1569 TopTools_ListIteratorOfListOfShape itl(TangE);
1570 Standard_Boolean Find = Standard_False;
1571 for ( ; itl.More() && !Find; itl.Next()) {
1572 if ( MapSF.IsBound(itl.Value())) {
1573 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
1574 E1f = TopoDS::Edge(aLocalShape);
1575 // E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
1576 Find = Standard_True;
1580 myAnalyse.TangentEdges(E,V1l,TangE);
1581 // find if the pipe on the tangent edges are soon created.
1582 itl.Initialize(TangE);
1583 Find = Standard_False;
1584 for ( ; itl.More() && !Find; itl.Next()) {
1585 if ( MapSF.IsBound(itl.Value())) {
1586 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
1587 E1l = TopoDS::Edge(aLocalShape);
1588 // E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
1589 Find = Standard_True;
1592 BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
1597 // ----------------------
1599 // ----------------------
1600 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1601 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1602 /// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1603 myInitOffsetEdge.SetRoot(E); // skv: supporting history.
1604 myInitOffsetEdge.Bind (E,EOn1);
1609 //--------------------------------------------------------
1610 // Construction of spheres on vertex.
1611 //--------------------------------------------------------
1613 TopTools_ListIteratorOfListOfShape it;
1615 for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
1616 const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
1618 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
1619 TopTools_ListOfShape LE;
1620 myAnalyse.Edges(V,OT,LE);
1622 if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
1623 TopTools_ListOfShape LOE;
1624 //--------------------------------------------------------
1625 // Return connected edges on tubes.
1626 //--------------------------------------------------------
1627 for (it.Initialize(LE) ; it.More(); it.Next()) {
1628 LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
1630 //----------------------
1631 // construction sphere.
1632 //-----------------------
1633 const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
1634 const TopoDS_Shape& FF = LLA.First();
1635 Standard_Real CurOffset = myOffset;
1636 if ( myFaceOffset.IsBound(FF))
1637 CurOffset = myFaceOffset(FF);
1639 BRepOffset_Offset OF(V,LOE,CurOffset);
1642 //--------------------------------------------------------------
1643 // Particular processing if V is at least a free border.
1644 //-------------------------------------------------------------
1645 TopTools_ListOfShape LBF;
1646 myAnalyse.Edges(V,ChFiDS_FreeBound,LBF);
1647 if (!LBF.IsEmpty()) {
1648 Standard_Boolean First = Standard_True;
1649 for (it.Initialize(LE) ; it.More(); it.Next()) {
1651 myInitOffsetEdge.SetRoot(V); // skv: supporting history.
1652 myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
1653 First = Standard_False;
1656 myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
1663 //------------------------------------------------------------
1664 // Extension of parallel faces to the context.
1665 // Extended faces are ordered in DS and removed from MapSF.
1666 //------------------------------------------------------------
1667 if (!myFaces.IsEmpty()) ToContext (MapSF);
1669 //------------------------------------------------------
1671 //------------------------------------------------------
1672 ChFiDS_TypeOfConcavity RT = ChFiDS_Concave;
1673 if (myOffset < 0.) RT = ChFiDS_Convex;
1674 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
1675 for ( ; It.More(); It.Next()) {
1676 const TopoDS_Shape& SI = It.Key();
1677 const BRepOffset_Offset& SF = It.Value();
1678 if (SF.Status() == BRepOffset_Reversed ||
1679 SF.Status() == BRepOffset_Degenerated ) {
1680 //------------------------------------------------
1681 // Degenerated or returned faces are not stored.
1682 //------------------------------------------------
1686 const TopoDS_Face& OF = It.Value().Face();
1687 myInitOffsetFace.Bind (SI,OF);
1688 myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
1689 myImageOffset.SetRoot (OF); // FaceOffset root of images
1691 if (SI.ShapeType() == TopAbs_FACE) {
1692 for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1693 Exp.More(); Exp.Next()) {
1694 //--------------------------------------------------------------------
1695 // To each face are associatedthe edges that restrict that
1696 // The edges that do not generate tubes or are not tangent
1697 // to two faces are removed.
1698 //--------------------------------------------------------------------
1699 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1700 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1701 if (!L.IsEmpty() && L.First().Type() != RT) {
1702 TopAbs_Orientation OO = E.Orientation();
1703 TopoDS_Shape aLocalShape = It.Value().Generated(E);
1704 TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
1705 // TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
1706 myAsDes->Add (OF,OE.Oriented(OO));
1711 for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1712 Exp.More(); Exp.Next()) {
1713 myAsDes->Add (OF,Exp.Current());
1719 if ( ChronBuild) Clock.Show();
1725 //=======================================================================
1726 //function : SelfInter
1728 //=======================================================================
1730 void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
1734 std::cout << " AUTODEBOUCLAGE:" << std::endl;
1740 throw Standard_NotImplemented();
1744 //=======================================================================
1745 //function : ToContext
1747 //=======================================================================
1749 void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
1751 TopTools_DataMapOfShapeShape Created;
1752 TopTools_DataMapOfShapeShape MEF;
1753 TopTools_IndexedMapOfShape FacesToBuild;
1754 TopTools_ListIteratorOfListOfShape itl;
1755 TopExp_Explorer exp;
1757 // TopAbs_State Side = TopAbs_IN;
1758 // if (myOffset < 0.) Side = TopAbs_OUT;
1760 TopAbs_State Side = TopAbs_OUT;
1764 for (i = 1; i <= myFaces.Extent(); i++) {
1765 const TopoDS_Face& CF = TopoDS::Face(myFaces(i));
1766 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1767 exp.More(); exp.Next()) {
1768 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1769 if (!myAnalyse.HasAncestor(E)) {
1770 //----------------------------------------------------------------
1771 // The edges of context faces that are not in the initial shape
1772 // can appear in the result.
1773 //----------------------------------------------------------------
1774 //myAsDes->Add(CF,E);
1780 //--------------------------------------------------------
1781 // Determine the edges and faces reconstructed by
1783 //---------------------------------------------------------
1785 for (j = 1; j <= myFaces.Extent(); j++) {
1786 const TopoDS_Face& CF = TopoDS::Face(myFaces(j));
1787 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1788 exp.More(); exp.Next()) {
1789 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1790 if (myAnalyse.HasAncestor(E)) {
1791 const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
1792 for (itl.Initialize(LEA); itl.More(); itl.Next()) {
1793 const BRepOffset_Offset& OF = MapSF(itl.Value());
1794 FacesToBuild.Add(itl.Value());
1795 MEF.Bind(OF.Generated(E),CF);
1798 TopExp::Vertices(E,V[0],V[1]);
1799 for (Standard_Integer i = 0; i < 2; i++) {
1800 const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]);
1801 for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
1802 const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
1803 if (MapSF.IsBound(EV)) {
1804 const BRepOffset_Offset& OF = MapSF(EV);
1805 FacesToBuild.Add(EV);
1806 MEF.Bind(OF.Generated(V[i]),CF);
1813 //---------------------------
1814 // Reconstruction of faces.
1815 //---------------------------
1817 ChFiDS_TypeOfConcavity RT = ChFiDS_Concave;
1818 if (myOffset < 0.) RT = ChFiDS_Convex;
1820 TopAbs_Orientation Or;
1822 for (j = 1; j <= FacesToBuild.Extent(); j++) {
1823 const TopoDS_Shape& S = FacesToBuild(j);
1824 BRepOffset_Offset BOF;
1826 F = TopoDS::Face(BOF.Face());
1827 BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
1832 myInitOffsetFace.Bind (S,NF);
1833 myInitOffsetFace.SetRoot (S); // Initial<-> Offset
1834 myImageOffset.SetRoot (NF);
1836 if (S.ShapeType() == TopAbs_FACE) {
1837 for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1838 exp.More(); exp.Next()) {
1840 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1841 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1842 OE = BOF.Generated(E);
1843 Or = E.Orientation();
1845 if (!L.IsEmpty() && L.First().Type() != RT) {
1846 if (Created.IsBound(OE)) {
1848 if (NE.Orientation() == TopAbs_REVERSED)
1849 NE.Orientation(TopAbs::Reverse(Or));
1852 myAsDes->Add(NF,NE);
1855 myAsDes->Add(NF,OE);
1861 //------------------
1863 //---------------------
1864 for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1865 exp.More(); exp.Next()) {
1866 myAsDes->Add (NF,exp.Current());
1872 //------------------
1874 //------------------
1875 TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
1876 for (itc.Initialize(Created); itc.More(); itc.Next()) {
1879 if (myInitOffsetEdge.IsImage(OE)) {
1880 TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
1881 Or = myInitOffsetEdge.Image(E).First().Orientation();
1882 if (NE.Orientation() == TopAbs_REVERSED)
1883 NE.Orientation(TopAbs::Reverse(Or));
1886 myInitOffsetEdge.Remove(OE);
1887 myInitOffsetEdge.Bind(E,NE);
1893 //=======================================================================
1894 //function : UpdateFaceOffset
1896 //=======================================================================
1898 void BRepOffset_MakeOffset::UpdateFaceOffset()
1900 TopTools_MapOfShape M;
1901 TopTools_DataMapOfShapeReal CopiedMap;
1902 CopiedMap.Assign(myFaceOffset);
1903 TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
1905 ChFiDS_TypeOfConcavity RT = ChFiDS_Convex;
1906 if (myOffset < 0.) RT = ChFiDS_Concave;
1908 for ( ; it.More(); it.Next()) {
1909 const TopoDS_Face& F = TopoDS::Face(it.Key());
1910 Standard_Real CurOffset = CopiedMap(F);
1911 if ( !M.Add(F)) continue;
1914 Build.MakeCompound(Co);
1915 TopTools_MapOfShape Dummy;
1917 if (myJoin == GeomAbs_Arc)
1918 myAnalyse.AddFaces(F,Co,Dummy,ChFiDS_Tangential,RT);
1920 myAnalyse.AddFaces(F,Co,Dummy,ChFiDS_Tangential);
1922 TopExp_Explorer exp(Co,TopAbs_FACE);
1923 for (; exp.More(); exp.Next()) {
1924 const TopoDS_Face& FF = TopoDS::Face(exp.Current());
1925 if ( !M.Add(FF)) continue;
1926 if ( myFaceOffset.IsBound(FF))
1927 myFaceOffset.UnBind(FF);
1928 myFaceOffset.Bind(FF,CurOffset);
1933 //=======================================================================
1934 //function : CorrectConicalFaces
1936 //=======================================================================
1938 void BRepOffset_MakeOffset::CorrectConicalFaces()
1940 if(myOffsetShape.IsNull())
1945 TopTools_SequenceOfShape Cones;
1946 TopTools_SequenceOfShape Circs;
1947 TopTools_SequenceOfShape Seams;
1948 Standard_Real TolApex = 1.e-5;
1952 TopTools_DataMapOfShapeListOfShape FacesOfCone;
1953 //TopTools_DataMapOfShapeShape DegEdges;
1954 TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
1955 if (myJoin == GeomAbs_Arc)
1957 for (; Explo.More(); Explo.Next())
1959 TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
1960 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
1961 //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
1962 //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
1964 TopTools_IndexedMapOfShape Emap;
1965 TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
1966 for (i = 1; i <= Emap.Extent(); i++)
1968 TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
1969 //Standard_Real f, l;
1970 //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
1971 //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
1972 if (BRep_Tool::Degenerated(anEdge))
1974 //Check if anEdge is a really degenerated edge or not
1975 BRepAdaptor_Curve BACurve(anEdge, aFace);
1976 gp_Pnt Pfirst, Plast, Pmid;
1977 Pfirst = BACurve.Value(BACurve.FirstParameter());
1978 Plast = BACurve.Value(BACurve.LastParameter());
1979 Pmid = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
1980 if (Pfirst.Distance(Plast) <= TolApex &&
1981 Pfirst.Distance(Pmid) <= TolApex)
1983 //Cones.Append( aFace );
1984 //Circs.Append( anEdge );
1985 //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
1986 TopoDS_Edge OrEdge =
1987 TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
1988 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1989 if ( FacesOfCone.IsBound(VF) )
1991 //add a face to the existing list
1992 TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
1993 aFaces.Append (aFace);
1994 //DegEdges.Bind(aFace, anEdge);
1998 //the vertex is not in the map => create a new key and items
1999 TopTools_ListOfShape aFaces;
2000 aFaces.Append (aFace);
2001 FacesOfCone.Bind(VF, aFaces);
2002 //DegEdges.Bind(aFace, anEdge);
2005 } //for (i = 1; i <= Emap.Extent(); i++)
2006 } //for (; fexp.More(); fexp.Next())
2007 } //if (myJoin == GeomAbs_Arc)
2009 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
2012 Standard_Boolean IsModified = Standard_False;
2013 for (; Cone.More(); Cone.Next() ) {
2014 gp_Sphere theSphere;
2015 Handle(Geom_SphericalSurface) aSphSurf;
2016 TopoDS_Wire SphereWire;
2017 BB.MakeWire(SphereWire);
2018 TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
2019 const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
2020 TopTools_ListIteratorOfListOfShape itFaces(Faces);
2021 Standard_Boolean isFirstFace = Standard_True;
2023 TopoDS_Vertex theFirstVertex, CurFirstVertex;
2024 for (; itFaces.More(); itFaces.Next())
2026 TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
2027 TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
2028 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2030 DegEdge = TopoDS::Edge(Explo.Current());
2031 if (BRep_Tool::Degenerated(DegEdge))
2033 TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
2034 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
2035 if (VF.IsSame(anApex))
2039 TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
2040 TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
2041 BB.Degenerated(CurEdge, Standard_False);
2042 BB.SameRange(CurEdge, Standard_False);
2043 BB.SameParameter(CurEdge, Standard_False);
2044 gp_Pnt fPnt, lPnt, mPnt;
2045 GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
2047 BRep_Tool::Range(CurEdge, f, l);
2050 gp_Vec aVec1(fPnt, mPnt);
2051 gp_Vec aVec2(fPnt, lPnt);
2052 gp_Vec aNorm = aVec1.Crossed(aVec2);
2053 gp_Pnt theApex = BRep_Tool::Pnt(anApex);
2054 gp_Vec ApexToFpnt(theApex, fPnt);
2055 gp_Vec Ydir = aNorm ^ ApexToFpnt;
2056 gp_Vec Xdir = Ydir ^ aNorm;
2057 //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
2058 gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
2059 theSphere.SetRadius(myOffset);
2060 theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
2061 aSphSurf = new Geom_SphericalSurface(theSphere);
2063 theFirstVertex = BRepLib_MakeVertex(fPnt);
2064 CurFirstVertex = theFirstVertex;
2067 TopoDS_Vertex v1, v2, FirstVert, EndVert;
2068 TopExp::Vertices(CurEdge, v1, v2);
2069 FirstVert = CurFirstVertex;
2070 if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
2071 EndVert = theFirstVertex;
2073 EndVert = BRepLib_MakeVertex(lPnt);
2074 CurEdge.Free( Standard_True );
2075 BB.Remove(CurEdge, v1);
2076 BB.Remove(CurEdge, v2);
2077 BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
2078 BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
2079 //take the curve from sphere an put it to the edge
2080 Standard_Real Uf, Vf, Ul, Vl;
2081 ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
2082 ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
2083 if (Abs(Ul) <= Precision::Confusion())
2085 Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
2089 gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
2090 if (Abs(Uf - f) > Precision::Confusion())
2092 aCircle.Rotate(aCircle.Axis(), f - Uf);
2093 aCurv = new Geom_Circle(aCircle);
2097 Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
2098 BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
2099 BB.Range(CurEdge, Uf, Ul, Standard_True);
2100 Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
2101 Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
2102 BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
2103 BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
2104 BRepLib::SameParameter(CurEdge);
2105 BB.Add(SphereWire, CurEdge);
2106 //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
2107 BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
2108 gp_Pnt2d fPnt2d, lPnt2d;
2109 fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
2110 lPnt2d = BAc2d.Value(BAc2d.LastParameter());
2111 TopTools_IndexedMapOfShape Emap;
2112 TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
2114 Standard_Integer j = 0, k;
2115 for (k = 1; k <= Emap.Extent(); k++)
2117 const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
2118 if (!BRep_Tool::Degenerated(anEdge))
2120 TopoDS_Vertex V1, V2;
2121 TopExp::Vertices(anEdge, V1, V2);
2122 if (V1.IsSame(v1) || V2.IsSame(v1))
2126 for (k = 0; k < j; k++)
2128 TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
2129 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
2130 Eforward.Free(Standard_True);
2131 TopoDS_Vertex V1, V2;
2132 TopExp::Vertices( Eforward, V1, V2 );
2133 BRepAdaptor_Curve2d EEc( Eforward, aFace );
2134 gp_Pnt2d p2d1, p2d2;
2135 p2d1 = EEc.Value(EEc.FirstParameter());
2136 p2d2 = EEc.Value(EEc.LastParameter());
2139 TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
2140 FirstVert : EndVert;
2141 BB.Remove( Eforward, V1 );
2142 BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
2146 TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
2147 FirstVert : EndVert;
2148 BB.Remove( Eforward, V2 );
2149 BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
2153 isFirstFace = Standard_False;
2154 CurFirstVertex = EndVert;
2156 //Building new spherical face
2157 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2158 gp_Pnt2d p2d1, p2d2;
2159 TopTools_ListOfShape EdgesOfWire;
2160 TopoDS_Iterator itw(SphereWire);
2161 for (; itw.More(); itw.Next())
2163 const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
2164 EdgesOfWire.Append(anEdge);
2166 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
2167 p2d1 = aC2d->Value(f);
2168 p2d2 = aC2d->Value(l);
2169 if (p2d1.X() < Ufirst)
2171 if (p2d1.X() > Ulast)
2173 if (p2d2.X() < Ufirst)
2175 if (p2d2.X() > Ulast)
2178 TopTools_ListOfShape NewEdges;
2179 TopoDS_Edge FirstEdge;
2180 TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
2181 for (; itl.More(); itl.Next())
2183 FirstEdge = TopoDS::Edge(itl.Value());
2185 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
2186 p2d1 = aC2d->Value(f);
2187 p2d2 = aC2d->Value(l);
2188 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
2190 EdgesOfWire.Remove(itl);
2194 NewEdges.Append(FirstEdge.Oriented(TopAbs_FORWARD));
2195 TopoDS_Vertex Vf1, CurVertex;
2196 TopExp::Vertices(FirstEdge, Vf1, CurVertex);
2197 itl.Initialize(EdgesOfWire);
2200 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2201 TopoDS_Vertex V1, V2;
2202 TopExp::Vertices(anEdge, V1, V2);
2203 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
2205 NewEdges.Append(anEdge.Oriented(TopAbs_FORWARD));
2206 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2207 EdgesOfWire.Remove(itl);
2213 Standard_Real Vfirst, Vlast;
2216 Vfirst = p2d1.Y(); Vlast = M_PI/2.;
2220 Vfirst = -M_PI/2.; Vlast = p2d1.Y();
2222 TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
2223 TopoDS_Edge OldEdge, DegEdge;
2224 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2226 DegEdge = TopoDS::Edge(Explo.Current());
2227 if (BRep_Tool::Degenerated(DegEdge))
2230 TopoDS_Vertex DegVertex = TopExp::FirstVertex(DegEdge);
2231 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2233 OldEdge = TopoDS::Edge(Explo.Current());
2234 TopoDS_Vertex V1, V2;
2235 TopExp::Vertices(OldEdge, V1, V2);
2236 if (!V1.IsSame(DegVertex) && !V2.IsSame(DegVertex))
2239 TopoDS_Vertex V1, V2;
2240 TopExp::Vertices(OldEdge, V1, V2);
2241 TopTools_ListOfShape LV1, LV2;
2242 LV1.Append(Vf1.Oriented(TopAbs_FORWARD));
2243 LV2.Append(CurVertex.Oriented(TopAbs_FORWARD));
2244 BRepTools_Substitution theSubstitutor;
2245 theSubstitutor.Substitute(V1.Oriented(TopAbs_FORWARD), LV1);
2247 theSubstitutor.Substitute(V2.Oriented(TopAbs_FORWARD), LV2);
2248 theSubstitutor.Substitute(OldEdge.Oriented(TopAbs_FORWARD), NewEdges);
2249 theSubstitutor.Build(NewSphericalFace);
2250 if (theSubstitutor.IsCopied(NewSphericalFace))
2252 const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
2253 NewSphericalFace = TopoDS::Face(listSh.First());
2256 //Adding NewSphericalFace to the shell
2257 Explo.Init( myOffsetShape, TopAbs_SHELL );
2258 TopoDS_Shape theShell = Explo.Current();
2259 theShell.Free( Standard_True );
2260 BB.Add( theShell, NewSphericalFace );
2261 IsModified = Standard_True;
2262 if(!theShell.Closed())
2264 if(BRep_Tool::IsClosed(theShell))
2266 theShell.Closed(Standard_True);
2276 if (myShape.ShapeType() == TopAbs_SOLID || myThickening)
2278 //Explo.Init( myOffsetShape, TopAbs_SHELL );
2280 //if (Explo.More()) {
2281 // TopoDS_Shape theShell = Explo.Current();
2282 // theShell.Closed( Standard_True );
2285 Standard_Integer NbShell = 0;
2288 BB.MakeCompound (NC);
2292 Sol.Closed(Standard_True);
2293 for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
2294 TopoDS_Shell Sh = TopoDS::Shell(Explo.Current());
2295 //if (myThickening && myOffset > 0.)
2309 Standard_Integer nbs = Sol.NbChildren();
2310 Standard_Boolean SolIsNull = (nbs == 0);
2314 BRepCheck_Analyzer aCheck (Sol, Standard_False);
2315 if (!aCheck.IsValid ())
2317 TopTools_ListOfShape aSolList;
2318 CorrectSolid (Sol, aSolList);
2319 if (!aSolList.IsEmpty ())
2322 TopTools_ListIteratorOfListOfShape aSLIt (aSolList);
2323 for (; aSLIt.More (); aSLIt.Next ())
2325 BB.Add (NC, aSLIt.Value ());
2327 SolIsNull = Standard_True;
2332 Standard_Boolean NCIsNull = (NC.NbChildren() == 0);
2333 if((!SolIsNull) && (!NCIsNull))
2338 else if(SolIsNull && (!NCIsNull))
2349 else if((!SolIsNull) && NCIsNull)
2351 myOffsetShape = Sol;
2361 //=======================================================================
2362 //function : Intersection3D
2364 //=======================================================================
2366 void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
2370 std::cout << " INTERSECTION 3D:" << std::endl;
2376 // In the Complete Intersection mode, implemented currently for planar
2377 // solids only, there is no need to intersect the faces here.
2378 // This intersection will be performed in the method BuildShellsCompleteInter
2379 // where the special treatment is applied to produced faces.
2381 // Make sure to match the parameters in which the method
2382 // BuildShellsCompleteInter is called.
2383 if (myInter && (myJoin == GeomAbs_Intersection) && myIsPlanar &&
2384 !myThickening && myFaces.IsEmpty() && IsSolid(myShape))
2388 TopTools_ListOfShape OffsetFaces; // list of faces // created.
2389 MakeList (OffsetFaces,myInitOffsetFace,myFaces);
2391 if (!myFaces.IsEmpty()) {
2392 Standard_Boolean InSide = (myOffset < 0.); // Temporary
2393 // it is necessary to calculate Inside taking account of the concavity or convexity of edges
2394 // between the cap and the part.
2396 if (myJoin == GeomAbs_Arc)
2397 Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
2403 Inter.CompletInt (OffsetFaces,myInitOffsetFace);
2404 TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
2405 if (myJoin == GeomAbs_Intersection) {
2406 BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
2410 //--------------------------------
2411 // Only between neighbor faces.
2412 //--------------------------------
2413 Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
2416 if ( ChronBuild) Clock.Show();
2420 //=======================================================================
2421 //function : Intersection2D
2423 //=======================================================================
2425 void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Modif,
2426 const TopTools_IndexedMapOfShape& NewEdges)
2430 std::cout << " INTERSECTION 2D:" << std::endl;
2435 //--------------------------------------------------------
2436 // calculate intersections2d on faces concerned by
2438 //---------------------------------------------------------
2439 //TopTools_MapIteratorOfMapOfShape it(Modif);
2440 //-----------------------------------------------
2441 // Intersection of edges 2 by 2.
2442 //-----------------------------------------------
2443 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
2445 for (i = 1; i <= Modif.Extent(); i++) {
2446 const TopoDS_Face& F = TopoDS::Face(Modif(i));
2447 BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol, aDMVV);
2450 BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
2454 DEBVerticesControl (NewEdges,myAsDes);
2456 if ( ChronBuild) Clock.Show();
2461 //=======================================================================
2462 //function : MakeLoops
2464 //=======================================================================
2466 void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
2470 std::cout << " DEBOUCLAGE 2D:" << std::endl;
2475 //TopTools_MapIteratorOfMapOfShape it(Modif);
2476 TopTools_ListOfShape LF,LC;
2477 //-----------------------------------------
2478 // unwinding of faces // modified.
2479 //-----------------------------------------
2481 for (i = 1; i <= Modif.Extent(); i++) {
2482 if (!myFaces.Contains(Modif(i)))
2483 LF.Append(Modif(i));
2486 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
2487 BuildSplitsOfTrimmedFaces(LF, myAsDes, myImageOffset);
2490 myMakeLoops.Build(LF,myAsDes,myImageOffset);
2493 //-----------------------------------------
2494 // unwinding of caps.
2495 //-----------------------------------------
2496 for (i = 1; i <= myFaces.Extent(); i++)
2497 LC.Append(myFaces(i));
2499 Standard_Boolean InSide = 1;
2500 if (myOffset > 0 ) InSide = 0;
2501 myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
2504 if ( ChronBuild) Clock.Show();
2508 //=======================================================================
2509 //function : MakeFaces
2510 //purpose : Reconstruction of topologically unchanged faces that
2511 // share edges that were reconstructed.
2512 //=======================================================================
2514 void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
2518 std::cout << " RECONSTRUCTION OF FACES:" << std::endl;
2523 TopTools_ListIteratorOfListOfShape itr;
2524 const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
2525 TopTools_ListOfShape LOF;
2526 //----------------------------------
2527 // Loop on all faces //.
2528 //----------------------------------
2529 for (itr.Initialize(Roots); itr.More(); itr.Next()) {
2530 TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
2531 if (!myImageOffset.HasImage(F)) {
2536 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
2537 BuildSplitsOfTrimmedFaces(LOF, myAsDes, myImageOffset);
2540 myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
2544 if ( ChronBuild) Clock.Show();
2548 //=======================================================================
2549 //function : UpdateInitOffset
2550 //purpose : Update and cleaning of myInitOffset
2551 //=======================================================================
2552 static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
2553 BRepAlgo_Image& myImageOffset,
2554 const TopoDS_Shape& myOffsetShape,
2555 const TopAbs_ShapeEnum &theShapeType) // skv
2557 BRepAlgo_Image NIOF;
2558 const TopTools_ListOfShape& Roots = myInitOffset.Roots();
2559 TopTools_ListIteratorOfListOfShape it(Roots);
2560 for (; it.More(); it.Next()) {
2561 NIOF.SetRoot (it.Value());
2563 for (it.Initialize(Roots); it.More(); it.Next()) {
2564 const TopoDS_Shape& SI = it.Value();
2565 TopTools_ListOfShape LI;
2566 TopTools_ListOfShape L1;
2567 myInitOffset.LastImage(SI,L1);
2568 TopTools_ListIteratorOfListOfShape itL1(L1);
2569 for (; itL1.More(); itL1.Next()) {
2570 const TopoDS_Shape& O1 = itL1.Value();
2571 TopTools_ListOfShape L2;
2572 myImageOffset.LastImage(O1,L2);
2577 // Modified by skv - Mon Apr 4 18:17:27 2005 Begin
2578 // Supporting history.
2579 // NIOF.Filter(myOffsetShape,TopAbs_FACE);
2580 NIOF.Filter(myOffsetShape, theShapeType);
2581 // Modified by skv - Mon Apr 4 18:17:27 2005 End
2582 myInitOffset = NIOF;
2585 //=======================================================================
2586 //function : MakeMissingWalls
2588 //=======================================================================
2589 void BRepOffset_MakeOffset::MakeMissingWalls ()
2591 TopTools_IndexedDataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
2592 TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
2593 Standard_Real OffsetVal = Abs(myOffset);
2595 FillContours(myShape, myAnalyse, Contours, MapEF);
2597 for (Standard_Integer ic = 1; ic <= Contours.Extent(); ic++)
2599 TopoDS_Vertex StartVertex = TopoDS::Vertex(Contours.FindKey(ic));
2600 TopoDS_Edge StartEdge;
2601 const TopTools_ListOfShape& aContour = Contours(ic);
2602 TopTools_ListIteratorOfListOfShape itl(aContour);
2603 Standard_Boolean FirstStep = Standard_True;
2604 TopoDS_Edge PrevEdge;
2605 TopoDS_Vertex PrevVertex = StartVertex;
2606 Standard_Boolean isBuildFromScratch = Standard_False; // Problems with edges.
2607 for (; itl.More(); itl.Next())
2609 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
2610 TopoDS_Face aFaceOfEdge = TopoDS::Face(MapEF(anEdge));
2612 // Check for offset existence.
2613 if (!myInitOffsetEdge.HasImage(anEdge))
2616 // Check for existence of two different vertices.
2617 TopTools_ListOfShape LOE, LOE2;
2618 myInitOffsetEdge.LastImage( anEdge, LOE );
2619 myImageOffset.LastImage( LOE.Last(), LOE2 );
2620 TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
2621 TopoDS_Vertex V1, V2, V3, V4;
2622 TopExp::Vertices(OE, V4, V3);
2623 TopExp::Vertices(anEdge, V1, V2);
2624 Standard_Real aF, aL;
2625 const Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aF, aL);
2627 (!aC->IsClosed() && !aC->IsPeriodic()))
2629 gp_Pnt aPntF = BRep_Tool::Pnt(V1);
2630 gp_Pnt aPntL = BRep_Tool::Pnt(V2);
2631 Standard_Real aDistE = aPntF.SquareDistance(aPntL);
2632 if ( aDistE < Precision::SquareConfusion())
2634 // Bad case: non closed, but vertexes mapped to same 3d point.
2638 Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
2639 if (aDistE < anEdgeTol)
2641 // Potential problems not detected via checkshape.
2642 gp_Pnt aPntOF = BRep_Tool::Pnt(V4);
2643 gp_Pnt aPntOL = BRep_Tool::Pnt(V3);
2644 if (aPntOF.SquareDistance(aPntOL) > gp::Resolution())
2646 // To avoid computation of complex analytical continuation of Sin / ArcSin.
2647 Standard_Real aSinValue = Min(2 * anEdgeTol / aPntOF.Distance(aPntOL), 1.0);
2648 Standard_Real aMaxAngle = Min(Abs(ASin(aSinValue)), M_PI_4); // Maximal angle.
2649 Standard_Real aCurrentAngle = gp_Vec(aPntF, aPntL).Angle(gp_Vec(aPntOF, aPntOL));
2650 if (aC->IsKind(STANDARD_TYPE(Geom_Line)) &&
2651 Abs (aCurrentAngle) > aMaxAngle)
2653 // anEdge not collinear to offset edge.
2654 isBuildFromScratch = Standard_True;
2655 myIsPerformSewing = Standard_True;
2662 Standard_Boolean ToReverse = Standard_False;
2663 if (!V1.IsSame(PrevVertex))
2665 TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
2666 aVtx = V3; V3 = V4; V4 = aVtx;
2667 ToReverse = Standard_True;
2670 OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
2672 Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
2673 if (FirstStep || isBuildFromScratch)
2675 E4 = BRepLib_MakeEdge( V1, V4 );
2681 if (V2.IsSame(StartVertex) && !ArcOnV2)
2684 E3 = BRepLib_MakeEdge( V2, V3 );
2687 if (isBuildFromScratch)
2693 TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
2694 const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
2695 Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
2696 Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
2698 TopoDS_Wire theWire;
2699 BB.MakeWire(theWire);
2702 BB.Add(theWire, anEdge.Reversed());
2703 BB.Add(theWire, E3.Reversed());
2704 BB.Add(theWire, OE.Reversed());
2705 BB.Add(theWire, E4.Reversed());
2709 BB.Add(theWire, anEdge);
2710 BB.Add(theWire, E3);
2711 BB.Add(theWire, OE);
2712 BB.Add(theWire, E4);
2715 BRepLib::BuildCurves3d( theWire, myTol );
2716 theWire.Closed(Standard_True);
2717 TopoDS_Face NewFace;
2718 Handle(Geom_Surface) theSurf;
2719 BRepAdaptor_Curve BAcurve(anEdge);
2720 BRepAdaptor_Curve BAcurveOE(OE);
2721 Standard_Real fpar = BAcurve.FirstParameter();
2722 Standard_Real lpar = BAcurve.LastParameter();
2723 gp_Pnt PonE = BAcurve.Value(fpar);
2724 gp_Pnt PonOE = BAcurveOE.Value(fpar);
2725 gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
2726 Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
2727 Standard_Boolean IsPlanar = Standard_False;
2728 if (BAcurve.GetType() == GeomAbs_Circle &&
2729 BAcurveOE.GetType() == GeomAbs_Circle)
2731 gp_Circ aCirc = BAcurve.Circle();
2732 gp_Circ aCircOE = BAcurveOE.Circle();
2733 gp_Lin anAxisLine(aCirc.Axis());
2734 gp_Dir CircAxisDir = aCirc.Axis().Direction();
2735 if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) &&
2736 anAxisLine.Contains(aCircOE.Location(), Precision::Confusion()))
2737 { //cylinder, plane or cone
2738 if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder
2739 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
2740 else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane
2741 IsPlanar = Standard_True;
2743 gp_Pnt PonEL = BAcurve.Value(lpar);
2744 if (PonEL.Distance(PonE) <= Precision::PConfusion()) {
2745 Standard_Boolean bIsHole;
2746 TopoDS_Edge aE1, aE2;
2747 TopoDS_Wire aW1, aW2;
2748 Handle(Geom_Plane) aPL;
2749 IntTools_FClass2d aClsf;
2751 if (aCirc.Radius()>aCircOE.Radius()) {
2764 aPL = new Geom_Plane(aCirc.Location(), CircAxisDir);
2765 for (Standard_Integer i = 0; i < 2; ++i) {
2766 TopoDS_Wire& aW = (i==0) ? aW1 : aW2;
2767 TopoDS_Edge& aE = (i==0) ? aE1 : aE2;
2770 BB.MakeFace(aFace, aPL, Precision::Confusion());
2772 aClsf.Init(aFace, Precision::Confusion());
2773 bIsHole=aClsf.IsHole();
2774 if ((bIsHole && !i) || (!bIsHole && i)) {
2777 BB.Add(aW, aE.Reversed());
2781 BB.MakeFace(NewFace, aPL, Precision::Confusion());
2782 BB.Add(NewFace, aW1);
2783 BB.Add(NewFace, aW2);
2788 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
2789 aCirc.Radius(), aCircOE.Radius());
2790 gp_Ax3 theAx3(aCirc.Position());
2791 if (CircAxisDir * theCone.Axis().Direction() < 0.)
2794 CircAxisDir.Reverse();
2796 theCone.SetPosition(theAx3);
2797 theSurf = new Geom_ConicalSurface(theCone);
2800 TopLoc_Location Loc;
2801 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
2802 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2803 Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
2804 OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
2805 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2806 aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
2807 aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
2811 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2814 BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
2816 BB.MakeWire(theWire);
2817 BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
2818 BB.Add(theWire, E4);
2819 BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
2820 BB.Add(theWire, E3);
2821 theWire.Closed(Standard_True);
2826 BB.SameParameter(E3, Standard_False);
2827 BB.SameRange(E3, Standard_False);
2828 BB.SameParameter(E4, Standard_False);
2829 BB.SameRange(E4, Standard_False);
2830 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2831 BB.Range(E3, theSurf, Loc, 0., OffsetVal);
2832 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2833 BB.Range(E4, theSurf, Loc, 0., OffsetVal);
2835 NewFace = BRepLib_MakeFace(theSurf, theWire);
2837 } //cylinder or cone
2838 } //if both edges are arcs of circles
2839 if (NewFace.IsNull())
2841 BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
2842 if (MF.Error() == BRepLib_FaceDone)
2844 NewFace = MF.Face();
2845 IsPlanar = Standard_True;
2847 else //Extrusion (by thrusections)
2849 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
2850 Handle(Geom_TrimmedCurve) TrEdgeCurve =
2851 new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
2852 Standard_Real fparOE, lparOE;
2853 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
2854 Handle(Geom_TrimmedCurve) TrOffsetCurve =
2855 new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
2856 GeomFill_Generator ThrusecGenerator;
2857 ThrusecGenerator.AddCurve( TrEdgeCurve );
2858 ThrusecGenerator.AddCurve( TrOffsetCurve );
2859 ThrusecGenerator.Perform( Precision::PConfusion() );
2860 theSurf = ThrusecGenerator.Surface();
2861 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
2862 Standard_Real Uf, Ul, Vf, Vl;
2863 theSurf->Bounds(Uf, Ul, Vf, Vl);
2864 TopLoc_Location Loc;
2865 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
2866 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2867 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
2868 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2869 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
2870 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
2871 aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
2872 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
2875 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2876 Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
2877 BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
2878 BB.Range(E3, Vf, Vl);
2882 BB.SameParameter(E3, Standard_False);
2883 BB.SameRange(E3, Standard_False);
2884 BB.SameParameter(E4, Standard_False);
2885 BB.SameRange(E4, Standard_False);
2886 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2887 BB.Range(E3, theSurf, Loc, Vf, Vl);
2888 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2889 BB.Range(E4, theSurf, Loc, Vf, Vl);
2890 Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
2891 BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
2892 BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
2893 Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
2894 BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
2895 BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
2897 NewFace = BRepLib_MakeFace(theSurf, theWire);
2902 Standard_Real fparOE = BAcurveOE.FirstParameter();
2903 Standard_Real lparOE = BAcurveOE.LastParameter();
2904 TopLoc_Location Loc;
2905 if (Abs(fpar - fparOE) > Precision::Confusion())
2907 const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
2908 gp_Pnt2d fp2d = EdgeLine2d->Value(fpar);
2909 gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
2910 aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
2911 Handle(Geom_Curve) aCurve;
2912 Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
2913 Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
2914 GeomAdaptor_Surface GAsurf( theSurf );
2915 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2916 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2917 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2918 Standard_Real max_deviation = 0., average_deviation;
2919 GeomLib::BuildCurve3d(Precision::Confusion(),
2920 ConS, FirstPar, LastPar,
2921 aCurve, max_deviation, average_deviation);
2922 BB.UpdateEdge( anE4, aCurve, max_deviation );
2923 BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
2924 BB.Range( anE4, FirstPar, LastPar );
2926 if (Abs(lpar - lparOE) > Precision::Confusion())
2928 const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
2929 gp_Pnt2d lp2d = EdgeLine2d->Value(lpar);
2930 gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
2931 aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
2932 Handle(Geom_Curve) aCurve;
2933 Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
2934 Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
2935 GeomAdaptor_Surface GAsurf( theSurf );
2936 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2937 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2938 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2939 Standard_Real max_deviation = 0., average_deviation;
2940 GeomLib::BuildCurve3d(Precision::Confusion(),
2941 ConS, FirstPar, LastPar,
2942 aCurve, max_deviation, average_deviation);
2943 BB.UpdateEdge( anE3, aCurve, max_deviation );
2944 BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
2945 BB.Range( anE3, FirstPar, LastPar );
2948 BRepLib::SameParameter(NewFace);
2949 BRepTools::Update(NewFace);
2951 TopAbs_Orientation anOr = OrientationOfEdgeInFace(anEdge, aFaceOfEdge);
2952 TopAbs_Orientation OrInNewFace = OrientationOfEdgeInFace(anEdge, NewFace);
2953 if (OrInNewFace != TopAbs::Reverse(anOr))
2956 myWalls.Append(NewFace);
2959 TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
2960 TopoDS_Vertex arcV1, arcV2;
2961 TopExp::Vertices(anArc, arcV1, arcV2);
2962 Standard_Boolean ArcReverse = Standard_False;
2963 if (!arcV1.IsSame(V3))
2965 TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
2966 ArcReverse = Standard_True;
2968 TopoDS_Edge EA1, EA2;
2969 //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
2974 //////////////////////////////////////////////////////
2975 if (V2.IsSame(StartVertex))
2978 EA2 = BRepLib_MakeEdge( V2, arcV2 );
2979 anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
2980 if (EA1.Orientation() == TopAbs_REVERSED)
2982 EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
2983 TopoDS_Wire arcWire;
2984 BB.MakeWire(arcWire);
2985 BB.Add(arcWire, EA1);
2986 BB.Add(arcWire, anArc);
2987 BB.Add(arcWire, EA2);
2988 BRepLib::BuildCurves3d( arcWire, myTol );
2989 arcWire.Closed(Standard_True);
2990 TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
2991 BRepTools::Update(arcFace);
2992 myWalls.Append(arcFace);
2993 TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
2994 const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
3000 if (isBuildFromScratch)
3002 PrevEdge = TopoDS::Edge(E4);
3004 isBuildFromScratch = Standard_False;
3012 FirstStep = Standard_False;
3017 //=======================================================================
3018 //function : MakeShells
3020 //=======================================================================
3022 void BRepOffset_MakeOffset::MakeShells ()
3026 std::cout << " RECONSTRUCTION OF SHELLS:" << std::endl;
3032 // Prepare list of splits of the offset faces to make the shells
3033 TopTools_ListOfShape aLSF;
3034 const TopTools_ListOfShape& R = myImageOffset.Roots();
3035 TopTools_ListIteratorOfListOfShape it(R);
3037 for (; it.More(); it.Next()) {
3038 TopoDS_Shape aF = it.Value();
3039 if (myThickening) //offsetted faces must change their orientations
3042 TopTools_ListOfShape Image;
3043 myImageOffset.LastImage(aF,Image);
3044 TopTools_ListIteratorOfListOfShape it2(Image);
3045 for (; it2.More(); it2.Next()) {
3046 const TopoDS_Shape& aFIm = it2.Value();
3052 TopExp_Explorer Explo(myShape, TopAbs_FACE);
3053 for (; Explo.More(); Explo.Next()) {
3054 const TopoDS_Shape& aF = Explo.Current();
3058 it.Initialize(myWalls);
3059 for (; it.More(); it.Next()) {
3060 const TopoDS_Shape& aF = it.Value();
3065 if (aLSF.IsEmpty()) {
3069 Standard_Boolean bDone = Standard_False;
3070 if ((myJoin == GeomAbs_Intersection) && myInter &&
3071 !myThickening && myFaces.IsEmpty() &&
3072 IsSolid(myShape) && myIsPlanar) {
3074 TopoDS_Shape aShells;
3075 bDone = BuildShellsCompleteInter(aLSF, myImageOffset, aShells);
3077 myOffsetShape = aShells;
3082 BRepTools_Quilt Glue;
3083 TopTools_ListIteratorOfListOfShape aItLS(aLSF);
3084 for (; aItLS.More(); aItLS.Next()) {
3085 Glue.Add(aItLS.Value());
3087 myOffsetShape = Glue.Shells();
3090 //Set correct value for closed flag
3091 TopExp_Explorer Explo(myOffsetShape, TopAbs_SHELL);
3092 for(; Explo.More(); Explo.Next())
3094 TopoDS_Shape aS = Explo.Current();
3097 if(BRep_Tool::IsClosed(aS))
3099 aS.Closed(Standard_True);
3105 //=======================================================================
3106 //function : MakeSolid
3108 //=======================================================================
3110 void BRepOffset_MakeOffset::MakeSolid ()
3112 if (myOffsetShape.IsNull()) return;
3114 // Modified by skv - Mon Apr 4 18:17:27 2005 Begin
3115 // Supporting history.
3116 UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
3117 UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
3118 // Modified by skv - Mon Apr 4 18:17:27 2005 End
3119 TopExp_Explorer exp;
3121 Standard_Integer NbShell = 0;
3124 B.MakeCompound (NC);
3128 Sol.Closed(Standard_True);
3129 Standard_Boolean aMakeSolid = (myShape.ShapeType() == TopAbs_SOLID) || myThickening;
3130 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
3131 TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
3132 if (myThickening && myOffset > 0.)
3135 if (Sh.Closed() && aMakeSolid) {
3146 Standard_Integer nbs = Sol.NbChildren();
3147 Standard_Boolean SolIsNull = (nbs == 0);
3151 BRepCheck_Analyzer aCheck (Sol, Standard_False);
3152 if (!aCheck.IsValid ())
3154 TopTools_ListOfShape aSolList;
3155 CorrectSolid (Sol, aSolList);
3156 if (!aSolList.IsEmpty ())
3159 TopTools_ListIteratorOfListOfShape aSLIt (aSolList);
3160 for (; aSLIt.More (); aSLIt.Next ())
3162 B.Add (NC, aSLIt.Value ());
3164 SolIsNull = Standard_True;
3168 Standard_Boolean NCIsNull = (NC.NbChildren() == 0);
3169 if((!SolIsNull) && (!NCIsNull))
3174 else if(SolIsNull && (!NCIsNull))
3185 else if((!SolIsNull) && NCIsNull)
3187 myOffsetShape = Sol;
3195 //=======================================================================
3196 //function : SelectShells
3198 //=======================================================================
3200 void BRepOffset_MakeOffset::SelectShells ()
3202 TopTools_MapOfShape FreeEdges;
3203 TopExp_Explorer exp(myShape,TopAbs_EDGE);
3204 //-------------------------------------------------------------
3205 // FreeEdges all edges that can have free border in the
3207 // 1 - free borders of myShape .
3208 //-------------------------------------------------------------
3209 for ( ; exp.More(); exp.Next()) {
3210 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3211 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
3212 if (LA.Extent() < 2) {
3213 if (myAnalyse.Type(E).First().Type() == ChFiDS_FreeBound) {
3218 // myShape has free borders and there are no caps
3220 if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
3222 myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
3225 //=======================================================================
3226 //function : OffsetFacesFromShapes
3228 //=======================================================================
3230 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
3232 return myInitOffsetFace;
3235 // Modified by skv - Tue Mar 15 16:20:43 2005 Begin
3237 //=======================================================================
3238 //function : GetJoinType
3239 //purpose : Query offset join type.
3240 //=======================================================================
3242 GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
3247 //=======================================================================
3248 //function : OffsetEdgesFromShapes
3250 //=======================================================================
3252 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
3254 return myInitOffsetEdge;
3257 // Modified by skv - Tue Mar 15 16:20:43 2005 End
3259 //=======================================================================
3260 //function : ClosingFaces
3262 //=======================================================================
3264 const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
3271 //=======================================================================
3272 //function : EncodeRegularity
3274 //=======================================================================
3276 void BRepOffset_MakeOffset::EncodeRegularity ()
3280 std::cout << " CODING OF REGULARITIES:" << std::endl;
3286 if (myOffsetShape.IsNull()) return;
3287 // find edges G1 in the result
3288 TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
3291 TopTools_MapOfShape MS;
3293 for ( ; exp.More(); exp.Next()) {
3294 TopoDS_Edge OE = TopoDS::Edge(exp.Current());
3295 BRepLib::BuildCurve3d(OE,myTol);
3296 TopoDS_Edge ROE = OE;
3298 if ( !MS.Add(OE)) continue;
3300 if ( myImageOffset.IsImage(OE))
3301 ROE = TopoDS::Edge(myImageOffset.Root(OE));
3303 const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
3305 if (LofOF.Extent() != 2) {
3306 #ifdef OCCT_DEBUG_VERB
3307 std::cout << " Edge shared by " << LofOF.Extent() << " Faces" << std::endl;
3312 const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
3313 const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
3315 if ( F1.IsNull() || F2.IsNull())
3318 const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
3319 const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
3321 TopAbs_ShapeEnum Type1 = Root1.ShapeType();
3322 TopAbs_ShapeEnum Type2 = Root2.ShapeType();
3324 if (F1.IsSame(F2)) {
3325 if (BRep_Tool::IsClosed(OE,F1)) {
3326 // Temporary Debug for the Bench.
3328 // In mode intersection, the edges are not coded in myInitOffsetEdge
3329 // so, manage case by case
3330 // Note DUB; for Hidden parts, it is NECESSARY to code CN
3331 // Analytic Surfaces.
3332 if (myJoin == GeomAbs_Intersection) {
3333 BRepAdaptor_Surface BS(F1,Standard_False);
3334 GeomAbs_SurfaceType SType = BS.GetType();
3335 if (SType == GeomAbs_Cylinder ||
3336 SType == GeomAbs_Cone ||
3337 SType == GeomAbs_Sphere ||
3338 SType == GeomAbs_Torus ) {
3339 B.Continuity(OE,F1,F1,GeomAbs_CN);
3342 // See YFR : MaJ of myInitOffsetFace
3345 else if (myInitOffsetEdge.IsImage(ROE)) {
3346 if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3347 const TopoDS_Face& FRoot = TopoDS::Face(Root1);
3348 const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
3349 GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
3350 if (Conti == GeomAbs_CN) {
3351 B.Continuity(OE,F1,F1,GeomAbs_CN);
3353 else if ( Conti > GeomAbs_C0) {
3354 B.Continuity(OE,F1,F1,GeomAbs_G1);
3363 // code regularities G1 between :
3364 // - sphere and tube : one root is a vertex, the other is an edge
3365 // and the vertex is included in the edge
3366 // - face and tube : one root is a face, the other an edge
3367 // and the edge is included in the face
3368 // - face and face : if two root faces are tangent in
3369 // the initial shape, they will be tangent in the offset shape
3370 // - tube and tube : if 2 edges generating tubes are
3371 // tangents, the 2 will be tangent either.
3372 if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
3373 TopoDS_Vertex V1,V2;
3374 TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
3375 if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
3376 B.Continuity(OE,F1,F2,GeomAbs_G1);
3379 else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
3380 TopoDS_Vertex V1,V2;
3381 TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
3382 if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
3383 B.Continuity(OE,F1,F2,GeomAbs_G1);
3386 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
3387 TopExp_Explorer exp2(Root1,TopAbs_EDGE);
3388 for ( ; exp2.More(); exp2.Next()) {
3389 if ( exp2.Current().IsSame(Root2)) {
3390 B.Continuity(OE,F1,F2,GeomAbs_G1);
3395 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
3396 TopExp_Explorer exp2(Root2,TopAbs_EDGE);
3397 for ( ; exp2.More(); exp2.Next()) {
3398 if ( exp2.Current().IsSame(Root1)) {
3399 B.Continuity(OE,F1,F2,GeomAbs_G1);
3404 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3405 // if two root faces are tangent in
3406 // the initial shape, they will be tangent in the offset shape
3407 TopTools_ListOfShape LE;
3408 BRepOffset_Tool::FindCommonShapes(Root1, Root2, TopAbs_EDGE, LE);
3409 if ( LE.Extent() == 1) {
3410 const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
3411 if ( myAnalyse.HasAncestor(Ed)) {
3412 const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
3413 if (LI.Extent() == 1 &&
3414 LI.First().Type() == ChFiDS_Tangential) {
3415 B.Continuity(OE,F1,F2,GeomAbs_G1);
3420 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
3421 TopTools_ListOfShape LV;
3422 BRepOffset_Tool::FindCommonShapes(Root1, Root2, TopAbs_VERTEX, LV);
3423 if ( LV.Extent() == 1) {
3424 TopTools_ListOfShape LEdTg;
3425 myAnalyse.TangentEdges(TopoDS::Edge(Root1),
3426 TopoDS::Vertex(LV.First()),
3428 TopTools_ListIteratorOfListOfShape it(LEdTg);
3429 for (; it.More(); it.Next()) {
3430 if ( it.Value().IsSame(Root2)) {
3431 B.Continuity(OE,F1,F2,GeomAbs_G1);
3440 if ( ChronBuild) Clock.Show();
3444 //=======================================================================
3445 //function : ComputeMaxDist
3447 //=======================================================================
3448 Standard_Real ComputeMaxDist(const gp_Pln& thePlane,
3449 const Handle(Geom_Curve)& theCrv,
3450 const Standard_Real theFirst,
3451 const Standard_Real theLast)
3453 Standard_Real aMaxDist = 0.;
3454 Standard_Integer i, NCONTROL = 23;
3455 Standard_Real aPrm, aDist2;
3457 for (i = 0; i< NCONTROL; i++) {
3458 aPrm = ((NCONTROL - 1 - i)*theFirst + i*theLast) / (NCONTROL - 1);
3459 aP = theCrv->Value(aPrm);
3460 if (Precision::IsInfinite(aP.X()) || Precision::IsInfinite(aP.Y())
3461 || Precision::IsInfinite(aP.Z()))
3463 return Precision::Infinite();
3465 aDist2 = thePlane.SquareDistance(aP);
3466 if (aDist2 > aMaxDist) aMaxDist = aDist2;
3468 return sqrt(aMaxDist)*1.05;
3470 //=======================================================================
3471 //function : UpDateTolerance
3473 //=======================================================================
3475 void UpdateTolerance (TopoDS_Shape& S,
3476 const TopTools_IndexedMapOfShape& Faces)
3479 TopTools_MapOfShape View;
3482 // The edges of caps are not modified.
3484 for (j = 1; j <= Faces.Extent(); j++) {
3485 const TopoDS_Shape& F = Faces(j);
3486 TopExp_Explorer Exp;
3487 for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3488 View.Add(Exp.Current());
3493 TopExp_Explorer ExpF;
3494 for (ExpF.Init(S, TopAbs_FACE); ExpF.More(); ExpF.Next())
3496 const TopoDS_Shape& F = ExpF.Current();
3497 if (Faces.Contains(F))
3501 BRepAdaptor_Surface aBAS(TopoDS::Face(F), Standard_False);
3502 TopExp_Explorer Exp;
3503 for (Exp.Init(F, TopAbs_EDGE); Exp.More(); Exp.Next()) {
3504 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
3505 Standard_Boolean isUpdated = Standard_False;
3506 if (aBAS.GetType() == GeomAbs_Plane)
3508 //Edge does not seem to have pcurve on plane,
3509 //so EdgeCorrector does not include it in tolerance calculation
3510 Standard_Real aFirst, aLast;
3511 Handle(Geom_Curve) aCrv = BRep_Tool::Curve(E, aFirst, aLast);
3512 Standard_Real aMaxDist = ComputeMaxDist(aBAS.Plane(), aCrv, aFirst, aLast);
3513 B.UpdateEdge(E, aMaxDist);
3514 isUpdated = Standard_True;
3519 BRepCheck_Edge EdgeCorrector(E);
3520 Tol = EdgeCorrector.Tolerance();
3521 B.UpdateEdge(E, Tol);
3522 isUpdated = Standard_True;
3526 Tol = BRep_Tool::Tolerance(E);
3527 // Update the vertices.
3528 TopExp::Vertices(E, V[0], V[1]);
3530 for (Standard_Integer i = 0; i <= 1; i++) {
3531 if (View.Add(V[i])) {
3532 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
3534 BRepCheck_Vertex VertexCorrector(V[i]);
3535 B.UpdateVertex(V[i], VertexCorrector.Tolerance());
3536 // use the occasion to clean the vertices.
3537 (TV->ChangePoints()).Clear();
3539 B.UpdateVertex(V[i], Tol);
3546 //=======================================================================
3547 //function : CorrectSolid
3549 //=======================================================================
3550 void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
3553 TopoDS_Shape anOuterShell;
3554 NCollection_List<Standard_Real> aVols;
3555 Standard_Real aVolMax = 0., anOuterVol = 0.;
3557 TopoDS_Iterator anIt(theSol);
3558 for(; anIt.More(); anIt.Next())
3560 const TopoDS_Shape& aSh = anIt.Value();
3561 GProp_GProps aVProps;
3562 BRepGProp::VolumeProperties(aSh, aVProps, Standard_True);
3563 if(Abs(aVProps.Mass()) > aVolMax)
3565 anOuterVol = aVProps.Mass();
3566 aVolMax = Abs(anOuterVol);
3569 aVols.Append(aVProps.Mass());
3572 if (Abs(anOuterVol) < Precision::Confusion()) {
3577 anOuterShell.Reverse();
3579 TopoDS_Solid aNewSol;
3580 aBB.MakeSolid(aNewSol);
3581 aNewSol.Closed(Standard_True);
3582 aBB.Add(aNewSol, anOuterShell);
3583 BRepClass3d_SolidClassifier aSolClass(aNewSol);
3585 anIt.Initialize(theSol);
3586 NCollection_List<Standard_Real>::Iterator aVIt(aVols);
3587 for(; anIt.More(); anIt.Next(), aVIt.Next())
3589 TopoDS_Shell aSh = TopoDS::Shell(anIt.Value());
3590 if(aSh.IsSame(anOuterShell))
3596 TopExp_Explorer aVExp(aSh, TopAbs_VERTEX);
3597 const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current());
3598 gp_Pnt aP = BRep_Tool::Pnt(aV);
3599 aSolClass.Perform(aP, BRep_Tool::Tolerance(aV));
3600 if(aSolClass.State() == TopAbs_IN)
3602 if(aVIt.Value() > 0.)
3606 aBB.Add(aNewSol, aSh);
3610 if(aVIt.Value() < 0.)
3615 aBB.MakeSolid(aSol);
3616 aSol.Closed(Standard_True);
3618 theSolList.Append(aSol);
3625 //=======================================================================
3626 //function : CheckInputData
3627 //purpose : Check input data for possiblity of offset perform.
3628 //=======================================================================
3629 Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
3631 // Set initial error state.
3632 myError = BRepOffset_NoError;
3633 TopoDS_Shape aTmpShape;
3634 myBadShape = aTmpShape;
3637 if (Abs(myOffset) <= myTol)
3639 Standard_Boolean isFound = Standard_False;
3640 TopTools_DataMapIteratorOfDataMapOfShapeReal anIter(myFaceOffset);
3641 for( ; anIter.More(); anIter.Next())
3643 if (Abs(anIter.Value()) > myTol)
3645 isFound = Standard_True;
3652 // No face with non-null offset found.
3653 myError = BRepOffset_NullOffset;
3654 return Standard_False;
3658 // Connectivity of input shape.
3659 if (!IsConnectedShell(myShape))
3661 myError = BRepOffset_NotConnectedShell;
3662 return Standard_False;
3665 // Normals check and continuity check.
3666 const Standard_Integer aPntPerDim = 20; // 21 points on each dimension.
3667 Standard_Real aUmin, aUmax, aVmin, aVmax;
3668 TopExp_Explorer anExpSF(myShape, TopAbs_FACE);
3669 NCollection_Map<Handle(TopoDS_TShape)> aPresenceMap;
3672 for( ; anExpSF.More(); anExpSF.Next())
3674 const TopoDS_Face& aF = TopoDS::Face(anExpSF.Current());
3676 if (aPresenceMap.Contains(aF.TShape()))
3678 // Not perform computations with partner shapes,
3679 // since they are contain same geometry.
3682 aPresenceMap.Add(aF.TShape());
3684 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aF, L);
3685 BRepTools::UVBounds(aF, aUmin, aUmax, aVmin, aVmax);
3687 // Continuity check.
3688 if (aSurf->Continuity() == GeomAbs_C0)
3690 myError = BRepOffset_C0Geometry;
3691 return Standard_False;
3694 // Get degenerated points, to avoid check them.
3695 NCollection_Vector<gp_Pnt> aBad3dPnts;
3696 TopExp_Explorer anExpFE(aF, TopAbs_EDGE);
3697 for( ; anExpFE.More(); anExpFE.Next())
3699 const TopoDS_Edge &aE = TopoDS::Edge(anExpFE.Current());
3700 if (BRep_Tool::Degenerated(aE))
3702 aBad3dPnts.Append(BRep_Tool::Pnt((TopExp::FirstVertex(aE))));
3706 // Geometry grid check.
3707 for(Standard_Integer i = 0; i <= aPntPerDim; i++)
3709 Standard_Real aUParam = aUmin + (aUmax - aUmin) * i / aPntPerDim;
3710 for(Standard_Integer j = 0; j <= aPntPerDim; j++)
3712 Standard_Real aVParam = aVmin + (aVmax - aVmin) * j / aPntPerDim;
3714 myError = checkSinglePoint(aUParam, aVParam, aSurf, aBad3dPnts);
3715 if (myError != BRepOffset_NoError)
3716 return Standard_False;
3720 // Vertex list check.
3721 TopExp_Explorer anExpFV(aF, TopAbs_VERTEX);
3722 for( ; anExpFV.More(); anExpFV.Next())
3724 const TopoDS_Vertex &aV = TopoDS::Vertex(anExpFV.Current());
3725 aPnt2d = BRep_Tool::Parameters(aV, aF);
3727 myError = checkSinglePoint(aPnt2d.X(), aPnt2d.Y(), aSurf, aBad3dPnts);
3728 if (myError != BRepOffset_NoError)
3729 return Standard_False;
3733 return Standard_True;
3737 //=======================================================================
3738 //function : GetBadShape
3739 //purpose : Get shape where problems detected.
3740 //=======================================================================
3741 const TopoDS_Shape& BRepOffset_MakeOffset::GetBadShape() const
3746 //=======================================================================
3747 //function : RemoveInternalEdges
3749 //=======================================================================
3750 void BRepOffset_MakeOffset::RemoveInternalEdges()
3752 Standard_Boolean bRemoveWire, bRemoveEdge;
3753 TopExp_Explorer aExpF, aExpW, aExpE;
3754 TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
3756 TopExp::MapShapesAndAncestors(myOffsetShape, TopAbs_EDGE, TopAbs_FACE, aDMELF);
3758 aExpF.Init(myOffsetShape, TopAbs_FACE);
3759 for (; aExpF.More(); aExpF.Next()) {
3760 TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
3762 TopTools_ListOfShape aLIW;
3764 aExpW.Init(aF, TopAbs_WIRE);
3765 for (; aExpW.More(); aExpW.Next()) {
3766 TopoDS_Wire& aW = *(TopoDS_Wire*)&aExpW.Current();
3768 bRemoveWire = Standard_True;
3769 TopTools_ListOfShape aLIE;
3771 aExpE.Init(aW, TopAbs_EDGE);
3772 for (; aExpE.More(); aExpE.Next()) {
3773 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
3774 if (aE.Orientation() != TopAbs_INTERNAL) {
3775 bRemoveWire = Standard_False;
3779 const TopTools_ListOfShape& aLF = aDMELF.FindFromKey(aE);
3780 bRemoveEdge = (aLF.Extent() == 1);
3785 bRemoveWire = Standard_False;
3792 else if (aLIE.Extent()) {
3793 RemoveShapes(aW, aLIE);
3797 if (aLIW.Extent()) {
3798 RemoveShapes(aF, aLIW);
3803 //=======================================================================
3804 // static methods implementation
3805 //=======================================================================
3807 //=======================================================================
3808 //function : checkSinglePoint
3809 //purpose : Check single point on surface for bad normals
3810 //=======================================================================
3811 BRepOffset_Error checkSinglePoint(const Standard_Real theUParam,
3812 const Standard_Real theVParam,
3813 const Handle(Geom_Surface)& theSurf,
3814 const NCollection_Vector<gp_Pnt>& theBadPoints)
3818 theSurf->D1(theUParam, theVParam, aPnt, aD1U, aD1V);
3820 if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
3821 aD1V.SquareMagnitude() < Precision::SquareConfusion() )
3823 Standard_Boolean isKnownBadPnt = Standard_False;
3824 for(Standard_Integer anIdx = theBadPoints.Lower();
3825 anIdx <= theBadPoints.Upper();
3828 if (aPnt.SquareDistance(theBadPoints(anIdx)) < Precision::SquareConfusion())
3830 isKnownBadPnt = Standard_True;
3833 } // for(Standard_Integer anIdx = theBadPoints.Lower();
3837 return BRepOffset_BadNormalsOnGeometry;
3841 return BRepOffset_NoError;
3843 } // if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
3845 if (aD1U.IsParallel(aD1V, Precision::Confusion()))
3847 // Isolines are collinear.
3848 return BRepOffset_BadNormalsOnGeometry;
3851 return BRepOffset_NoError;
3854 //=======================================================================
3855 //function : RemoveShapes
3856 //purpose : Removes the shapes <theLS> from the shape <theS>
3857 //=======================================================================
3858 void RemoveShapes(TopoDS_Shape& theS,
3859 const TopTools_ListOfShape& theLS)
3863 Standard_Boolean bFree = theS.Free();
3864 theS.Free(Standard_True);
3866 TopTools_ListIteratorOfListOfShape aIt(theLS);
3867 for (; aIt.More(); aIt.Next()) {
3868 const TopoDS_Shape& aSI = aIt.Value();
3869 aBB.Remove(theS, aSI);
3875 //=======================================================================
3876 //function : UpdateHistory
3877 //purpose : Updates the history information
3878 //=======================================================================
3879 void UpdateHistory(const TopTools_ListOfShape& theLF,
3880 BOPAlgo_Builder& theGF,
3881 BRepAlgo_Image& theImage)
3883 TopTools_ListIteratorOfListOfShape aIt(theLF);
3884 for (; aIt.More(); aIt.Next()) {
3885 const TopoDS_Shape& aF = aIt.Value();
3886 const TopTools_ListOfShape& aLFIm = theGF.Modified(aF);
3887 if (aLFIm.Extent()) {
3888 if (theImage.HasImage(aF)) {
3889 theImage.Add(aF, aLFIm);
3892 theImage.Bind(aF, aLFIm);
3898 //=======================================================================
3899 //function : IntersectEdges
3901 //=======================================================================
3902 void BRepOffset_MakeOffset::IntersectEdges(const TopTools_ListOfShape& theFaces,
3903 BRepOffset_DataMapOfShapeOffset& theMapSF,
3904 TopTools_DataMapOfShapeShape& theMES,
3905 TopTools_DataMapOfShapeShape& theBuild,
3906 Handle(BRepAlgo_AsDes)& theAsDes,
3907 Handle(BRepAlgo_AsDes)& theAsDes2d)
3909 Standard_Real aTolF;
3910 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
3911 // intersect edges created from edges
3912 TopTools_IndexedMapOfShape aMFV;
3913 for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
3915 const TopoDS_Face& aF = TopoDS::Face (it.Value());
3916 aTolF = BRep_Tool::Tolerance (aF);
3917 if (!BRepOffset_Inter2d::ConnexIntByInt(aF, theMapSF(aF), theMES, theBuild, theAsDes2d,
3918 myOffset, aTolF, myAnalyse, aMFV, aDMVV))
3920 myError = BRepOffset_CannotExtentEdge;
3924 // intersect edges created from vertices
3925 Standard_Integer i, aNbF = aMFV.Extent();
3926 for (i = 1; i <= aNbF; ++i) {
3927 const TopoDS_Face& aF = TopoDS::Face(aMFV(i));
3928 aTolF = BRep_Tool::Tolerance(aF);
3929 BRepOffset_Inter2d::ConnexIntByIntInVert
3930 (aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, aTolF, myAnalyse, aDMVV);
3933 // fuse vertices on edges
3934 if (!BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d))
3936 myError = BRepOffset_CannotFuseVertices;
3941 //=======================================================================
3942 //function : TrimEdges
3944 //=======================================================================
3945 Standard_Boolean TrimEdges(const TopoDS_Shape& theShape,
3946 const Standard_Real theOffset,
3947 const BRepOffset_Analyse& Analyse,
3948 BRepOffset_DataMapOfShapeOffset& theMapSF,
3949 TopTools_DataMapOfShapeShape& theMES,
3950 TopTools_DataMapOfShapeShape& theBuild,
3951 Handle(BRepAlgo_AsDes)& theAsDes,
3952 Handle(BRepAlgo_AsDes)& theAsDes2d,
3953 TopTools_IndexedMapOfShape& theNewEdges,
3954 TopTools_DataMapOfShapeShape& theETrimEInf,
3955 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins)
3957 TopExp_Explorer Exp,Exp2,ExpC;
3962 TopTools_ListOfShape aLFaces;
3963 for (Exp.Init (theShape, TopAbs_FACE); Exp.More(); Exp.Next())
3964 aLFaces.Append (Exp.Current());
3966 TopTools_MapOfShape aMFGenerated;
3967 TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
3968 for (TopTools_ListOfShape::Iterator it (Analyse.NewFaces()); it.More(); it.Next())
3970 const TopoDS_Shape& aFG = it.Value();
3971 aLFaces.Append (aFG);
3972 aMFGenerated.Add (aFG);
3973 TopExp::MapShapesAndUniqueAncestors (aFG, TopAbs_EDGE, TopAbs_FACE, aDMEF);
3976 for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
3978 const TopoDS_Face& FI = TopoDS::Face (it.Value());
3979 NF = theMapSF(FI).Face();
3980 if (theMES.IsBound(NF)) {
3981 NF = TopoDS::Face(theMES(NF));
3984 TopTools_MapOfShape View;
3985 TopTools_IndexedMapOfShape VEmap;
3986 Standard_Integer i, aNb;
3988 TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
3989 TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
3991 aNb = VEmap.Extent();
3992 for (i = 1; i <= aNb; ++i) {
3993 const TopoDS_Shape& aS = VEmap(i);
3994 if (!View.Add(aS)) {
3998 if (theBuild.IsBound(aS)) {
4000 // keep connection to original edges
4001 ExpC.Init(NE, TopAbs_EDGE);
4002 for (; ExpC.More(); ExpC.Next()) {
4003 const TopoDS_Edge& NEC = TopoDS::Edge(ExpC.Current());
4004 TopTools_ListOfShape* pLEOr = theEdgesOrigins.ChangeSeek(NEC);
4006 pLEOr = theEdgesOrigins.Bound(NEC, TopTools_ListOfShape());
4008 AppendToList(*pLEOr, aS);
4011 if (NE.ShapeType() == TopAbs_EDGE) {
4012 if (theNewEdges.Add(NE)) {
4013 if (!TrimEdge (TopoDS::Edge(NE),theAsDes2d,theAsDes, theETrimEInf))
4014 return Standard_False;
4018 //------------------------------------------------------------
4019 // The Intersections are on several edges.
4020 // The pieces without intersections with neighbors
4021 // are removed from AsDes.
4022 //------------------------------------------------------------
4023 for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
4024 TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
4025 if (theNewEdges.Add(NEC)) {
4026 if (!theAsDes2d->Descendant(NEC).IsEmpty()) {
4027 if(!TrimEdge (NEC,theAsDes2d, theAsDes, theETrimEInf))
4028 return Standard_False;
4031 if (theAsDes->HasAscendant(NEC)) {
4032 theAsDes->Remove(NEC);
4040 if (aS.ShapeType() != TopAbs_EDGE) {
4043 if (aMFGenerated.Contains (FI) && aDMEF.FindFromKey (aS).Extent() == 1)
4046 NE = theMapSF(FI).Generated(aS);
4047 //// modified by jgv, 19.12.03 for OCC4455 ////
4048 NE.Orientation(aS.Orientation());
4050 TopTools_ListOfShape* pLEOr = theEdgesOrigins.ChangeSeek(NE);
4052 pLEOr = theEdgesOrigins.Bound(NE, TopTools_ListOfShape());
4054 AppendToList(*pLEOr, aS);
4056 if (theMES.IsBound(NE)) {
4058 NE.Orientation(aS.Orientation());
4059 if (theNewEdges.Add(NE)) {
4060 if (!TrimEdge (TopoDS::Edge(NE), theAsDes2d, theAsDes, theETrimEInf))
4061 return Standard_False;
4065 TopoDS_Edge& anEdge = TopoDS::Edge(NE);
4066 BRepAdaptor_Curve aBAC(anEdge);
4067 if (aBAC.GetType() == GeomAbs_Line) {
4068 TopoDS_Edge aNewEdge;
4069 BRepOffset_Inter2d::ExtentEdge(anEdge, aNewEdge, theOffset);
4070 theETrimEInf.Bind(anEdge, aNewEdge);
4073 theAsDes->Add(NF,NE);
4077 return Standard_True;
4080 //=======================================================================
4081 //function : TrimEdge
4082 //purpose : Trim the edge of the largest of descendants in AsDes2d.
4083 // Order in AsDes two vertices that have trimmed the edge.
4084 //=======================================================================
4085 Standard_Boolean TrimEdge(TopoDS_Edge& NE,
4086 const Handle(BRepAlgo_AsDes)& AsDes2d,
4087 Handle(BRepAlgo_AsDes)& AsDes,
4088 TopTools_DataMapOfShapeShape& theETrimEInf)
4090 TopoDS_Edge aSourceEdge;
4091 TopoDS_Vertex V1,V2;
4092 Standard_Real aT1, aT2;
4094 TopExp::Vertices(NE, V1, V2);
4095 BRep_Tool::Range(NE, aT1, aT2);
4097 BOPTools_AlgoTools::MakeSplitEdge(NE, V1, aT1, V2, aT2, aSourceEdge);
4100 Standard_Real aSameParTol = Precision::Confusion();
4102 Standard_Real U = 0.;
4103 Standard_Real UMin = Precision::Infinite();
4104 Standard_Real UMax = -UMin;
4106 const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
4108 Standard_Boolean bTrim = Standard_False;
4110 if (LE.Extent() > 1) {
4111 TopTools_ListIteratorOfListOfShape it (LE);
4112 for (; it.More(); it.Next()) {
4113 TopoDS_Vertex V = TopoDS::Vertex(it.Value());
4114 if (NE.Orientation() == TopAbs_REVERSED)
4116 //V.Orientation(TopAbs_INTERNAL);
4117 if (!FindParameter(V, NE, U)) {
4119 Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
4120 gp_Pnt thePoint = BRep_Tool::Pnt(V);
4121 GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
4122 if (Projector.NbPoints() == 0)
4124 return Standard_False;
4126 U = Projector.LowerDistanceParameter();
4136 if (V1.IsNull() || V2.IsNull()) {
4137 return Standard_False;
4139 if (!V1.IsSame(V2)) {
4140 NE.Free( Standard_True );
4142 TopAbs_Orientation Or = NE.Orientation();
4143 NE.Orientation(TopAbs_FORWARD);
4144 TopoDS_Vertex VF,VL;
4145 TopExp::Vertices (NE,VF,VL);
4148 B.Add (NE,V1.Oriented(TopAbs_FORWARD));
4149 B.Add (NE,V2.Oriented(TopAbs_REVERSED));
4150 B.Range(NE,UMin,UMax);
4152 AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
4153 AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
4154 BRepLib::SameParameter(NE, aSameParTol, Standard_True);
4156 bTrim = Standard_True;
4161 BRepAdaptor_Curve aBAC(NE);
4162 if (aBAC.GetType() == GeomAbs_Line) {
4163 if (AsDes->HasAscendant(NE)) {
4170 if (!theETrimEInf.IsBound(NE)) {
4171 theETrimEInf.Bind(NE, aSourceEdge);
4174 return Standard_True;
4177 //=======================================================================
4178 //function : GetEnlargedFaces
4180 //=======================================================================
4181 void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
4182 const BRepOffset_DataMapOfShapeOffset& theMapSF,
4183 const TopTools_DataMapOfShapeShape& theMES,
4184 TopTools_DataMapOfShapeShape& theFacesOrigins,
4185 BRepAlgo_Image& theImage,
4186 TopTools_ListOfShape& theLSF)
4188 for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
4190 const TopoDS_Shape& FI = it.Value();
4191 const TopoDS_Shape& OFI = theMapSF(FI).Face();
4192 if (theMES.IsBound(OFI)) {
4193 const TopoDS_Face& aLocalFace = TopoDS::Face(theMES(OFI));
4194 theLSF.Append(aLocalFace);
4195 theImage.SetRoot(aLocalFace);
4196 theFacesOrigins.Bind(aLocalFace, FI);
4201 //=======================================================================
4202 //function : BuildShellsCompleteInter
4203 //purpose : Make the shells from list of faces using MakerVolume algorithm.
4204 // In case there will be more than just one solid, it will be
4205 // rebuilt using only outer faces.
4206 //=======================================================================
4207 Standard_Boolean BuildShellsCompleteInter(const TopTools_ListOfShape& theLF,
4208 BRepAlgo_Image& theImage,
4209 TopoDS_Shape& theShells)
4212 BOPAlgo_MakerVolume aMV1;
4213 aMV1.SetArguments(theLF);
4214 // we need to intersect the faces to process the tangential faces
4215 aMV1.SetIntersect(Standard_True);
4216 aMV1.SetAvoidInternalShapes(Standard_True);
4219 Standard_Boolean bDone = ! aMV1.HasErrors();
4224 UpdateHistory(theLF, aMV1, theImage);
4226 const TopoDS_Shape& aResult1 = aMV1.Shape();
4227 if (aResult1.ShapeType() == TopAbs_SOLID) {
4228 // result is the alone solid, nothing to do
4229 return GetSubShapes(aResult1, TopAbs_SHELL, theShells);
4232 // Allocators for effective memory allocations
4233 // Global allocator for the long-living containers
4234 Handle(NCollection_IncAllocator) anAllocGlob = new NCollection_IncAllocator;
4235 // Local allocator for the local containers
4236 Handle(NCollection_IncAllocator) anAllocLoc = new NCollection_IncAllocator;
4238 // Since the <theImage> object does not support multiple ancestors,
4239 // prepare local copy of the origins, which will be used to resolve
4240 // non-manifold solids produced by Maker Volume algorithm by comparison
4241 // of the normal directions of the split faces with their origins.
4242 TopTools_DataMapOfShapeListOfShape anOrigins(1, anAllocGlob);
4243 TopTools_ListIteratorOfListOfShape aItLR(theImage.Roots());
4244 for (; aItLR.More(); aItLR.Next())
4246 const TopoDS_Shape& aFR = aItLR.Value();
4248 // Reset the local allocator
4249 anAllocLoc->Reset();
4250 // Find the last splits of the root face, including the ones
4251 // created during MakeVolume operation
4252 TopTools_ListOfShape aLFIm(anAllocLoc);
4253 theImage.LastImage(aFR, aLFIm);
4255 TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm);
4256 for (; aItLFIm.More(); aItLFIm.Next())
4258 const TopoDS_Shape& aFIm = aItLFIm.Value();
4259 TopTools_ListOfShape *pLFOr = anOrigins.ChangeSeek(aFIm);
4261 pLFOr = anOrigins.Bound(aFIm, TopTools_ListOfShape(anAllocGlob));
4267 // Reset the local allocator
4268 anAllocLoc->Reset();
4269 // It is necessary to rebuild the solids, avoiding internal faces
4270 // Map faces to solids
4271 TopTools_IndexedDataMapOfShapeListOfShape aDMFS(1, anAllocLoc);
4272 TopExp::MapShapesAndAncestors(aResult1, TopAbs_FACE, TopAbs_SOLID, aDMFS);
4274 Standard_Integer i, aNb = aDMFS.Extent();
4277 // unable to build any solid
4281 // get faces attached to only one solid
4282 TopTools_ListOfShape aLF(anAllocLoc);
4283 for (i = 1; i <= aNb; ++i) {
4284 const TopTools_ListOfShape& aLS = aDMFS(i);
4285 if (aLS.Extent() == 1) {
4286 const TopoDS_Shape& aF = aDMFS.FindKey(i);
4291 // make solids from the new list
4292 BOPAlgo_MakerVolume aMV2;
4293 aMV2.SetArguments(aLF);
4294 // no need to intersect this time
4295 aMV2.SetIntersect(Standard_False);
4296 aMV2.SetAvoidInternalShapes(Standard_True);
4298 bDone = ! aMV2.HasErrors();
4303 const TopoDS_Shape& aResult2 = aMV2.Shape();
4304 if (aResult2.ShapeType() == TopAbs_SOLID) {
4305 return GetSubShapes(aResult2, TopAbs_SHELL, theShells);
4308 TopExp_Explorer aExp(aResult2, TopAbs_FACE);
4309 bDone = aExp.More();
4316 anAllocLoc->Reset();
4318 // the result is non-manifold - resolve it comparing normal
4319 // directions of the offset faces and original faces
4320 for (; aExp.More(); aExp.Next())
4322 const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
4323 const TopTools_ListOfShape* pLFOr = anOrigins.Seek(aF);
4326 Standard_ASSERT_INVOKE("BRepOffset_MakeOffset::BuildShellsCompleteInterSplit(): "
4327 "Origins map does not contain the split face");
4330 // Check orientation
4331 TopTools_ListIteratorOfListOfShape aItLOr(*pLFOr);
4332 for (; aItLOr.More(); aItLOr.Next())
4334 const TopoDS_Face& aFOr = TopoDS::Face(aItLOr.Value());
4335 if (BRepOffset_Tool::CheckPlanesNormals(aF, aFOr))
4343 // make solid from most outer faces with correct normal direction
4344 BOPAlgo_MakerVolume aMV3;
4345 aMV3.SetArguments(aLF);
4346 aMV3.SetIntersect(Standard_False);
4347 aMV3.SetAvoidInternalShapes(Standard_True);
4349 bDone = ! aMV3.HasErrors();
4354 const TopoDS_Shape& aResult3 = aMV3.Shape();
4355 return GetSubShapes(aResult3, TopAbs_SHELL, theShells);
4358 //=======================================================================
4359 //function : Generated
4361 //=======================================================================
4362 const TopTools_ListOfShape& BRepOffset_MakeOffset::Generated (const TopoDS_Shape& theS)
4364 myGenerated.Clear();
4365 const TopAbs_ShapeEnum aType = theS.ShapeType();
4370 if (myAnalyse.HasAncestor (theS))
4372 TopTools_MapOfShape aMFence;
4373 const TopTools_ListOfShape& aLA = myAnalyse.Ancestors (theS);
4374 TopTools_ListOfShape::Iterator itLA (aLA);
4375 for (; myGenerated.IsEmpty() && itLA.More(); itLA.Next())
4377 const TopoDS_Shape& aE = itLA.Value();
4378 if (!myInitOffsetEdge.HasImage (aE))
4380 TopTools_ListOfShape aLEIm;
4381 myInitOffsetEdge.LastImage (aE, aLEIm);
4382 TopTools_ListOfShape::Iterator itLEIm (aLEIm);
4383 for (; myGenerated.IsEmpty() && itLEIm.More(); itLEIm.Next())
4385 TopoDS_Iterator itV (itLEIm.Value());
4386 for (; itV.More(); itV.Next())
4388 if (!aMFence.Add (itV.Value()))
4390 myGenerated.Append (itV.Value());
4398 Standard_FALLTHROUGH
4401 if (myInitOffsetEdge.HasImage (theS))
4403 myInitOffsetEdge.LastImage (theS, myGenerated);
4406 Standard_FALLTHROUGH
4409 if (myInitOffsetFace.HasImage (theS))
4411 myInitOffsetFace.LastImage (theS, myGenerated);
4417 if (theS.IsSame (myShape))
4418 myGenerated.Append (myOffsetShape);
4425 if (myResMap.IsEmpty())
4426 TopExp::MapShapes (myOffsetShape, myResMap);
4428 for (TopTools_ListOfShape::Iterator it (myGenerated); it.More();)
4430 if (myResMap.Contains (it.Value()))
4433 myGenerated.Remove (it);
4439 //=======================================================================
4440 //function : Modified
4442 //=======================================================================
4443 const TopTools_ListOfShape& BRepOffset_MakeOffset::Modified (const TopoDS_Shape&)
4445 myGenerated.Clear();
4449 //=======================================================================
4450 //function : IsDeleted
4452 //=======================================================================
4453 Standard_Boolean BRepOffset_MakeOffset::IsDeleted (const TopoDS_Shape& theS)
4455 if (myResMap.IsEmpty())
4456 TopExp::MapShapes (myOffsetShape, myResMap);
4458 if (myResMap.Contains (theS))
4459 return Standard_False;
4461 return Generated (theS).IsEmpty()
4462 && Modified (theS).IsEmpty();
4465 //=======================================================================
4466 //function : GetSubShapes
4468 //=======================================================================
4469 Standard_Boolean GetSubShapes(const TopoDS_Shape& theShape,
4470 const TopAbs_ShapeEnum theSSType,
4471 TopoDS_Shape& theResult)
4473 TopExp_Explorer aExp(theShape, theSSType);
4475 return Standard_False;
4478 TopoDS_Compound aResult;
4479 BRep_Builder().MakeCompound(aResult);
4481 for (; aExp.More(); aExp.Next()) {
4482 const TopoDS_Shape& aSS = aExp.Current();
4483 BRep_Builder().Add(aResult, aSS);
4485 theResult = aResult;
4486 return Standard_True;
4489 //=======================================================================
4490 //function : IsPlanar
4491 //purpose : Checks if all the faces of the shape are planes
4492 //=======================================================================
4493 Standard_Boolean IsPlanar(const TopoDS_Shape& theS)
4495 TopExp_Explorer aExp(theS, TopAbs_FACE);
4496 for (; aExp.More(); aExp.Next()) {
4497 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
4498 BRepAdaptor_Surface aBAS(aF, Standard_False);
4499 if (aBAS.GetType() != GeomAbs_Plane) {
4503 return !aExp.More();
4506 //=======================================================================
4507 //function : IsSolid
4508 //purpose : Checks if the shape is solid
4509 //=======================================================================
4510 Standard_Boolean IsSolid(const TopoDS_Shape& theS)
4512 TopExp_Explorer aExp(theS, TopAbs_SOLID);
4516 //=======================================================================
4517 //function : AppendToList
4518 //purpose : Add to a list only unique elements
4519 //=======================================================================
4520 void AppendToList(TopTools_ListOfShape& theList,
4521 const TopoDS_Shape& theShape)
4523 TopTools_ListIteratorOfListOfShape aIt(theList);
4524 for (; aIt.More(); aIt.Next()) {
4525 const TopoDS_Shape& aS = aIt.Value();
4526 if (aS.IsSame(theShape)) {
4530 theList.Append(theShape);