From: emv Date: Fri, 10 Jul 2015 09:52:58 +0000 (+0300) Subject: Corrections in splitting faces and making shells functions. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=7a38094a2b8cff5ed10353fc198abadcb073799a;p=occt-copy.git Corrections in splitting faces and making shells functions. --- diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index 6bb8342992..f7f99de611 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -62,6 +62,8 @@ #include #include #include +#include +#include #include #include @@ -90,7 +92,6 @@ #include #include -#include #include #include #include @@ -113,6 +114,23 @@ #include #include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + // POP for NT #include @@ -239,242 +257,114 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges, #endif -static void UpdateTolerance ( TopoDS_Shape& myShape, - const TopTools_IndexedMapOfShape& myFaces); - - -static Standard_Boolean FindParameter(const TopoDS_Vertex& V, - const TopoDS_Edge& E, - Standard_Real& U) -{ - // Search the vertex in the edge - - Standard_Boolean rev = Standard_False; - TopoDS_Shape VF; - TopAbs_Orientation orient = TopAbs_INTERNAL; - - TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD)); - - // if the edge has no vertices - // and is degenerated use the vertex orientation - // RLE, june 94 - - if (!itv.More() && BRep_Tool::Degenerated(E)) { - orient = V.Orientation(); - } - - while (itv.More()) { - const TopoDS_Shape& Vcur = itv.Value(); - if (V.IsSame(Vcur)) { - if (VF.IsNull()) { - VF = Vcur; - } - else { - rev = E.Orientation() == TopAbs_REVERSED; - if (Vcur.Orientation() == V.Orientation()) { - VF = Vcur; - } - } - } - itv.Next(); - } - - if (!VF.IsNull()) orient = VF.Orientation(); - - Standard_Real f,l; - - if (orient == TopAbs_FORWARD) { - BRep_Tool::Range(E,f,l); - //return (rev) ? l : f; - U = (rev) ? l : f; - return Standard_True; - } - - else if (orient == TopAbs_REVERSED) { - BRep_Tool::Range(E,f,l); - //return (rev) ? f : l; - U = (rev) ? f : l; - return Standard_True; - } - - else { - TopLoc_Location L; - const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l); - L = L.Predivided(V.Location()); - if (!C.IsNull() || BRep_Tool::Degenerated(E)) { - BRep_ListIteratorOfListOfPointRepresentation itpr - ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); - - while (itpr.More()) { - const Handle(BRep_PointRepresentation)& pr = itpr.Value(); - if (pr->IsPointOnCurve(C,L)) { - Standard_Real p = pr->Parameter(); - Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux - if (!C.IsNull()) { - // Closed curves RLE 16 june 94 - if (Precision::IsNegativeInfinite(f)) - { - //return pr->Parameter();//p; - U = pr->Parameter(); - return Standard_True; - } - if (Precision::IsPositiveInfinite(l)) - { - //return pr->Parameter();//p; - U = pr->Parameter(); - return Standard_True; - } - gp_Pnt Pf = C->Value(f).Transformed(L.Transformation()); - gp_Pnt Pl = C->Value(l).Transformed(L.Transformation()); - Standard_Real tol = BRep_Tool::Tolerance(V); - if (Pf.Distance(Pl) < tol) { - if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) { - if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f; - else res = l;//p = l; - } - } - } - //return res;//p; - U = res; - return Standard_True; - } - itpr.Next(); - } - } - else { - // no 3d curve !! - // let us try with the first pcurve - Handle(Geom2d_Curve) PC; - Handle(Geom_Surface) S; - BRep_Tool::CurveOnSurface(E,PC,S,L,f,l); - L = L.Predivided(V.Location()); - BRep_ListIteratorOfListOfPointRepresentation itpr - ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); - - while (itpr.More()) { - const Handle(BRep_PointRepresentation)& pr = itpr.Value(); - if (pr->IsPointOnCurveOnSurface(PC,S,L)) { - Standard_Real p = pr->Parameter(); - // Closed curves RLE 16 june 94 - if (PC->IsClosed()) { - if ((p == PC->FirstParameter()) || - (p == PC->LastParameter())) { - if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter(); - else p = PC->LastParameter(); - } - } - //return p; - U = p; - return Standard_True; - } - itpr.Next(); - } - } - } - - //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge"); - return Standard_False; -} - //======================================================================= -//function : GetEdgePoints -//purpose : gets the first, last and middle points of the edge +// static methods //======================================================================= -static void GetEdgePoints(const TopoDS_Edge& anEdge, - const TopoDS_Face& aFace, - gp_Pnt& fPnt, gp_Pnt& mPnt, - gp_Pnt& lPnt) -{ - Standard_Real f, l; - Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l ); - gp_Pnt2d fPnt2d = theCurve->Value(f); - gp_Pnt2d lPnt2d = theCurve->Value(l); - gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l)); - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); - fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y()); - lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y()); - mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y()); -} +static + void UpdateTolerance(TopoDS_Shape& myShape, + const TopTools_IndexedMapOfShape& myFaces); + +static + Standard_Boolean FindParameter(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& U); + +static + void GetEdgePoints(const TopoDS_Edge& anEdge, + const TopoDS_Face& aFace, + gp_Pnt& fPnt, gp_Pnt& mPnt, + gp_Pnt& lPnt); + +static + void FillContours(const TopoDS_Shape& aShape, + const BRepOffset_Analyse& Analyser, + TopTools_DataMapOfShapeListOfShape& Contours, + TopTools_DataMapOfShapeShape& MapEF); + +static + void RemoveCorks(TopoDS_Shape& S, + TopTools_IndexedMapOfShape& Faces); + +static + Standard_Boolean IsConnectedShell(const TopoDS_Shape& S); + +static + void MakeList(TopTools_ListOfShape& OffsetFaces, + const BRepAlgo_Image& myInitOffsetFace, + const TopTools_IndexedMapOfShape& myFaces); + +static + void EvalMax(const TopoDS_Shape& S, + Standard_Real& Tol); + +static + void TrimEdge(TopoDS_Edge& NE, + const Handle(BRepAlgo_AsDes)& AsDes2d, + Handle(BRepAlgo_AsDes)& AsDes); + +static + void SortFaces(const TopTools_ListOfShape& theLIm, + TopTools_ListOfShape& theLFImages, + const Standard_Boolean bKeepFirst); + +static + Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, + const TopoDS_Shape& theSWhere, + TopoDS_Shape& theRes); + +static + void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + BOPAlgo_Builder& theGF); + +static + Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx, + Standard_Real& theFuzz); + +static + Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF, + const TopoDS_Edge& theE, + gp_Dir& theDB); +static + Standard_Boolean CheckBiNormals(const TopoDS_Face& aFIm, + const TopoDS_Face& aFOr, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + const TopTools_MapOfShape& theMFence, + Standard_Boolean& bKeep, + Standard_Boolean& bRem); + +static + void CheckBiNormals(TopTools_ListOfShape& theLFImages, + const TopoDS_Face& theF, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + TopTools_ListOfShape& theLFKeep); + +static + Standard_Boolean CheckNormals(const TopoDS_Face& theFIm, + const TopoDS_Face& theFOr); + +static + void UpdateInitOffset(BRepAlgo_Image& myInitOffset, + BRepAlgo_Image& myImageOffset, + const TopoDS_Shape& myOffsetShape, + const TopAbs_ShapeEnum &theShapeType); //======================================================================= -//function : FillContours -//purpose : fills free boundary contours and faces connected (MapEF) -//======================================================================= -static void FillContours(const TopoDS_Shape& aShape, - const BRepOffset_Analyse& Analyser, - TopTools_DataMapOfShapeListOfShape& Contours, - TopTools_DataMapOfShapeShape& MapEF) -{ - TopTools_ListOfShape Edges; - - TopExp_Explorer Explo(aShape, TopAbs_FACE); - BRepTools_WireExplorer Wexp; - - for (; Explo.More(); Explo.Next()) - { - TopoDS_Face aFace = TopoDS::Face(Explo.Current()); - TopoDS_Iterator itf(aFace); - for (; itf.More(); itf.Next()) - { - TopoDS_Wire aWire = TopoDS::Wire(itf.Value()); - for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next()) - { - TopoDS_Edge anEdge = Wexp.Current(); - if (BRep_Tool::Degenerated(anEdge)) - continue; - const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge); - if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary) - { - MapEF.Bind(anEdge, aFace); - Edges.Append(anEdge); - } - } - } - } - TopTools_ListIteratorOfListOfShape itl; - while (!Edges.IsEmpty()) - { - TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First()); - Edges.RemoveFirst(); - TopoDS_Vertex StartVertex, CurVertex; - TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True); - TopTools_ListOfShape aContour; - aContour.Append(StartEdge); - while (!CurVertex.IsSame(StartVertex)) - for (itl.Initialize(Edges); itl.More(); itl.Next()) - { - TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); - TopoDS_Vertex V1, V2; - TopExp::Vertices(anEdge, V1, V2); - if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex)) - { - aContour.Append(anEdge); - CurVertex = (V1.IsSame(CurVertex))? V2 : V1; - Edges.Remove(itl); - break; - } - } - Contours.Bind(StartVertex, aContour); - } -} //======================================================================= //function : BRepOffset_MakeOffset //purpose : //======================================================================= - BRepOffset_MakeOffset::BRepOffset_MakeOffset() { myAsDes = new BRepAlgo_AsDes(); } - //======================================================================= //function : BRepOffset_MakeOffset //purpose : //======================================================================= - BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S, const Standard_Real Offset, const Standard_Real Tol, @@ -499,12 +389,10 @@ myDone (Standard_False) MakeOffsetShape(); } - //======================================================================= //function : Initialize //purpose : //======================================================================= - void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S, const Standard_Real Offset, const Standard_Real Tol, @@ -526,12 +414,10 @@ void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S, Clear(); } - //======================================================================= //function : Clear //purpose : //======================================================================= - void BRepOffset_MakeOffset::Clear() { myOffsetShape.Nullify(); @@ -548,7 +434,6 @@ void BRepOffset_MakeOffset::Clear() //function : AddFace //purpose : //======================================================================= - void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) { myFaces.Add(F); //------------- @@ -563,7 +448,6 @@ void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) { //function : SetOffsetOnFace //purpose : //======================================================================= - void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F, const Standard_Real Off) { @@ -572,103 +456,10 @@ void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F, } //======================================================================= -//function : RemoveCorks +//function : MakeOffsetShape //purpose : //======================================================================= - -static void RemoveCorks (TopoDS_Shape& S, - TopTools_IndexedMapOfShape& Faces) -{ - TopoDS_Compound SS; - BRep_Builder B; - B.MakeCompound (SS); - //----------------------------------------------------- - // Construction of a shape without caps. - // and Orientation of caps as in shape S. - //----------------------------------------------------- - TopExp_Explorer exp(S,TopAbs_FACE); - for (; exp.More(); exp.Next()) { - const TopoDS_Shape& Cork = exp.Current(); - if (!Faces.Contains(Cork)) { - B.Add(SS,Cork); - } - else { - //Faces.Remove (Cork); - //begin instead of Remove// - TopoDS_Shape LastShape = Faces(Faces.Extent()); - Faces.RemoveLast(); - if (Faces.FindIndex(Cork) != 0) - Faces.Substitute(Faces.FindIndex(Cork), LastShape); - //end instead of Remove // - Faces.Add(Cork); // to reset it with proper orientation. - } - } - S = SS; -#ifdef DRAW - if ( AffichOffC) - DBRep::Set("myInit", SS); -#endif - -} - -static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S ) -{ - BRepTools_Quilt Glue; - Glue.Add( S ); - - TopoDS_Shape SS = Glue.Shells(); - TopExp_Explorer Explo( SS, TopAbs_SHELL ); - Explo.Next(); - if (Explo.More()) - return Standard_False; - - return Standard_True; -} - - -//======================================================================= -//function : MakeList -//purpose : -//======================================================================= - -static void MakeList (TopTools_ListOfShape& OffsetFaces, - const BRepAlgo_Image& myInitOffsetFace, - const TopTools_IndexedMapOfShape& myFaces) -{ - TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots()); - for ( ; itLOF.More(); itLOF.Next()) { - const TopoDS_Shape& Root = itLOF.Value(); - if (myInitOffsetFace.HasImage(Root)) { - if (!myFaces.Contains(Root)) { - OffsetFaces.Append(myInitOffsetFace.Image(Root).First()); - } - } - } -} - -//======================================================================= -//function : EvalMax -//purpose : -//======================================================================= - -static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol) -{ - TopExp_Explorer exp; - for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { - const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); - Standard_Real TolV = BRep_Tool::Tolerance(V); - if (TolV > Tol) Tol = TolV; - } - //Patch - Tol *= 5.; -} - -//======================================================================= -//function : MakeOffsetShape -//purpose : -//======================================================================= - -void BRepOffset_MakeOffset::MakeOffsetShape() +void BRepOffset_MakeOffset::MakeOffsetShape() { myDone = Standard_False; //------------------------------------------ @@ -769,13 +560,10 @@ void BRepOffset_MakeOffset::MakeOffsetShape() myDone = Standard_True; } - - //======================================================================= //function : MakeThickSolid //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeThickSolid() { //-------------------------------------------------------------- @@ -857,7 +645,6 @@ void BRepOffset_MakeOffset::MakeThickSolid() //function : IsDone //purpose : //======================================================================= - Standard_Boolean BRepOffset_MakeOffset::IsDone() const { return myDone; @@ -867,7 +654,6 @@ Standard_Boolean BRepOffset_MakeOffset::IsDone() const //function : Error //purpose : //======================================================================= - BRepOffset_Error BRepOffset_MakeOffset::Error() const { return myError; @@ -877,416 +663,529 @@ BRepOffset_Error BRepOffset_MakeOffset::Error() const //function : Shape //purpose : //======================================================================= - const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const { return myOffsetShape; } //======================================================================= -//function : TrimEdge -//purpose : Trim the edge of the largest of descendants in AsDes2d. -// Order in AsDes two vertices that have trimmed the edge. +//function : BuildOffsetByInter +//purpose : //======================================================================= - -static void TrimEdge (TopoDS_Edge& NE, - const Handle(BRepAlgo_AsDes)& AsDes2d, - Handle(BRepAlgo_AsDes)& AsDes) +void BRepOffset_MakeOffset::BuildOffsetByInter() { - Standard_Real aSameParTol = Precision::Confusion(); - - TopoDS_Vertex V1,V2; - Standard_Real U = 0.; - Standard_Real UMin = Precision::Infinite(); - Standard_Real UMax = -UMin; - - const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE); - // - Standard_Boolean bTrim = Standard_False; - // - if (LE.Extent() > 1) { - TopTools_ListIteratorOfListOfShape it (LE); - for (; it.More(); it.Next()) { - TopoDS_Vertex V = TopoDS::Vertex(it.Value()); - if (NE.Orientation() == TopAbs_REVERSED) - V.Reverse(); - //V.Orientation(TopAbs_INTERNAL); - if (!FindParameter(V, NE, U)) { - Standard_Real f, l; - Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); - gp_Pnt thePoint = BRep_Tool::Pnt(V); - GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); - if (Projector.NbPoints() == 0) - Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); - U = Projector.LowerDistanceParameter(); - } - if (U < UMin) { - UMin = U; V1 = V; - } - if (U > UMax) { - UMax = U; V2 = V; - } - } - // - if (V1.IsNull() || V2.IsNull()) { - Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge"); - } - if (!V1.IsSame(V2)) { - NE.Free( Standard_True ); - BRep_Builder B; - TopAbs_Orientation Or = NE.Orientation(); - NE.Orientation(TopAbs_FORWARD); - TopoDS_Vertex VF,VL; - TopExp::Vertices (NE,VF,VL); - B.Remove(NE,VF); - B.Remove(NE,VL); - B.Add (NE,V1.Oriented(TopAbs_FORWARD)); - B.Add (NE,V2.Oriented(TopAbs_REVERSED)); - B.Range(NE,UMin,UMax); - NE.Orientation(Or); - AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD)); - AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED)); - BRepLib::SameParameter(NE, aSameParTol, Standard_True); - // - bTrim = Standard_True; - } +#ifdef OCCT_DEBUG + if ( ChronBuild) { + cout << " CONSTRUCTION OF OFFSETS :" << endl; + Clock.Reset(); + Clock.Start(); } - // - if (!bTrim) { - if (!BRep_Tool::Degenerated(NE)) { - BRepAdaptor_Curve aBAC(NE); - if (!aBAC.IsClosed()) { - if (AsDes->HasAscendant(NE)) { - AsDes->Remove(NE); +#endif + + BRepOffset_DataMapOfShapeOffset MapSF; + TopTools_MapOfShape Done; + Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False; + //-------------------------------------------------------- + // Construction of faces parallel to initial faces + //-------------------------------------------------------- + TopExp_Explorer Exp; + TopTools_ListOfShape LF; + TopTools_ListIteratorOfListOfShape itLF; + + BRepLib::SortFaces(myShape,LF); + + TopTools_DataMapOfShapeShape ShapeTgt; + for (itLF.Initialize(LF); itLF.More(); itLF.Next()) { + const TopoDS_Face& F = TopoDS::Face(itLF.Value()); + Standard_Real CurOffset = myOffset; + if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F); + BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin); + TopTools_ListOfShape Let; + myAnalyse.Edges(F,BRepOffset_Tangent,Let); + TopTools_ListIteratorOfListOfShape itl(Let); + + for ( ; itl.More(); itl.Next()) { + const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value()); + if ( !ShapeTgt.IsBound(Cur)) { + TopoDS_Shape aLocalShape = OF.Generated(Cur); + const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); +// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); + ShapeTgt.Bind(Cur,OF.Generated(Cur)); + TopoDS_Vertex V1,V2,OV1,OV2; + TopExp::Vertices (Cur,V1,V2); + TopExp::Vertices (OTE,OV1,OV2); + TopTools_ListOfShape LE; + if (!ShapeTgt.IsBound(V1)) { + myAnalyse.Edges(V1,BRepOffset_Tangent,LE); + const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); + if (LE.Extent() == LA.Extent()) + ShapeTgt.Bind(V1,OV1); + } + if (!ShapeTgt.IsBound(V2)) { + LE.Clear(); + myAnalyse.Edges(V2,BRepOffset_Tangent,LE); + const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); + if (LE.Extent() == LA.Extent()) + ShapeTgt.Bind(V2,OV2); } } } + MapSF.Bind(F,OF); } -} + //-------------------------------------------------------------------- + // MES : Map of OffsetShape -> Extended Shapes. + // Build : Map of Initial SS -> OffsetShape build by Inter. + // can be an edge or a compound of edges + //--------------------------------------------------------------------- + TopTools_DataMapOfShapeShape MES; + TopTools_DataMapOfShapeShape Build; + TopTools_ListOfShape Failed; + TopAbs_State Side = TopAbs_IN; + Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes(); + //------------------------------------------------------------------- + // Extension of faces and calculation of new edges of intersection. + //------------------------------------------------------------------- + Standard_Boolean ExtentContext = 0; + if (myOffset > 0) ExtentContext = 1; -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + BRepOffset_Inter3d Inter3 (AsDes,Side,myTol); + // Intersection between parallel faces + Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed ); + // Intersection with caps. + Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed ); -//======================================================================= -//function : SortFaces -//purpose : -//======================================================================= -static void SortFaces(const TopTools_ListOfShape& theLIm, - TopTools_ListOfShape& theLFImages, - const Standard_Boolean bKeepFirst) -{ - Standard_Integer bKeep; // 1 - keep; -1 - remove - Standard_Boolean bFlag; - TopTools_IndexedDataMapOfShapeListOfShape aDMELF; - TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp; - TopTools_MapOfShape aMV; - TopTools_ListIteratorOfListOfShape aItLF; - TopExp_Explorer aExp; - // - aLFLeft = theLIm; - // - bKeep = bKeepFirst ? 1 : -1; - for (;;) { - aLFTmp = aLFLeft; - // - aLFLeft.Clear(); - aLFKeep.Clear(); - aDMELF.Clear(); - // - // map list of images edge - faces - aItLF.Initialize(aLFTmp); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); - TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); - } - // - // find images that have edge attached to only one face - aItLF.Initialize(aLFTmp); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); - aExp.Init(aFIm, TopAbs_EDGE); - for (bFlag = Standard_False; aExp.More(); aExp.Next()) { - const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); - const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE); - if (aLEF.Extent() == 1) { - TopoDS_Vertex aV1, aV2; - TopExp::Vertices(aE, aV1, aV2); - aMV.Add(aV1); - aMV.Add(aV2); - // - bFlag = Standard_True; - } - } - // - if (bFlag) { - aLFKeep.Append(aFIm); - } - else { - aLFLeft.Append(aFIm); - } + + //--------------------------------------------------------------------------------- + // Extension of neighbor edges of new edges and intersection between neighbors. + //-------------------------------------------------------------------------------- + Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes(); + for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { + const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); +// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin +// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol); + BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes,AsDes2d,myOffset, myTol); +// Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End + } + //----------------------------------------------------------- + // Great restriction of new edges and update of AsDes. + //------------------------------------------ ---------------- + TopTools_IndexedMapOfShape NewEdges; + TopExp_Explorer Exp2,ExpC; + TopoDS_Shape NE; + TopoDS_Edge TNE; + TopoDS_Face NF; + TopTools_IndexedDataMapOfShapeListOfShape anOrigins; + + for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { + const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); + NF = MapSF(FI).Face(); + if (MES.IsBound(NF)) { + NF = TopoDS::Face(MES(NF)); } // - // map shapes left for processing - aDMELF.Clear(); - aLFTmp = aLFLeft; - aLFLeft.Clear(); + TopTools_MapOfShape View; + TopTools_IndexedMapOfShape VEmap; + Standard_Integer i, aNb; // - aItLF.Initialize(aLFTmp); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); - TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); - } + TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); + TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); // - // find outer edges and check if they touch the first part of edges - aItLF.Initialize(aLFTmp); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); - aExp.Init(aFIm, TopAbs_EDGE); - for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) { - const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); - const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE); - if (aLEF.Extent() == 1) { - TopoDS_Vertex aV1, aV2; - TopExp::Vertices(aE, aV1, aV2); + aNb = VEmap.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aS = VEmap(i); + if (!View.Add(aS)) { + continue; + } + // + if (Build.IsBound(aS)) { + NE = Build(aS); + if (NE.ShapeType() == TopAbs_EDGE) { + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NE, aLSx); + } // - bFlag = aMV.Contains(aV1) || aMV.Contains(aV2); + if (NewEdges.Add(NE)) { + TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes); + } + } + else { + //------------------------------------------------------------ + // The Intersections are on several edges. + // The pieces without intersections with neighbors + // are removed from AsDes. + //------------------------------------------------------------ + for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { + TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); + if (NewEdges.Add(NEC)) { + NEC.Free(Standard_True); + if (anOrigins.Contains(NEC)) { + anOrigins.ChangeFromKey(NEC).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NEC, aLSx); + } + // + if (!AsDes2d->Descendant(NEC).IsEmpty()) { + TrimEdge (NEC,AsDes2d,AsDes); + } + else { + if (AsDes->HasAscendant(NEC)) { + AsDes->Remove(NEC); + } + } + } + } } } + else { + if (aS.ShapeType() != TopAbs_EDGE) { + continue; + } + // + NE = MapSF(FI).Generated(aS); + //// modified by jgv, 19.12.03 for OCC4455 //// + NE.Orientation(aS.Orientation()); + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NE, aLSx); + } + // + if (MES.IsBound(NE)) { + NE = MES(NE); + NE.Orientation(aS.Orientation()); + if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} + } + AsDes->Add(NF,NE); + } + } + } + + //--------------------------------- + // Intersection 2D on // + //--------------------------------- + TopTools_ListOfShape LFE; + BRepAlgo_Image IMOE; + for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { + const TopoDS_Shape& FI = Exp.Current(); + const TopoDS_Shape& OFI = MapSF(FI).Face(); + if (MES.IsBound(OFI)) { + const TopoDS_Face& NF = TopoDS::Face(MES(OFI)); + LFE.Append(NF); + IMOE.SetRoot(NF); // - if (bFlag) { - aLFKeep.Append(aFIm); + if (anOrigins.Contains(NF)) { + anOrigins.ChangeFromKey(NF).Append(FI); } else { - aLFLeft.Append(aFIm); - } - } - // - if (bKeep == 1) { - // aLFKeep should be kept - // aLFLeft left for further processing - aItLF.Initialize(aLFKeep); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); - theLFImages.Append(aFIm); + TopTools_ListOfShape aLSx; + aLSx.Append(FI); + anOrigins.Add(NF, aLSx); } } - // - if (aLFLeft.IsEmpty()) { - break; - } - // - bKeep *= -1; } -} - -//======================================================================= -//function : FindShape -//purpose : -//======================================================================= -static Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, - const TopoDS_Shape& theSWhere, - TopoDS_Shape& theRes) -{ - Standard_Boolean bFound = Standard_False; - TopAbs_ShapeEnum aType = theSWhat.ShapeType(); - TopExp_Explorer aExp(theSWhere, aType); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aS = aExp.Current(); - if (aS.IsSame(theSWhat)) { - theRes = aS; - bFound = Standard_True; - break; - } + + TopTools_ListIteratorOfListOfShape itLFE(LFE); + for (; itLFE.More(); itLFE.Next()) { + const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value()); + BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol); + } + //---------------------------------------------- + // Intersections 2d on caps. + //---------------------------------------------- + Standard_Integer i; + for (i = 1; i <= myFaces.Extent(); i++) { + const TopoDS_Face& Cork = TopoDS::Face(myFaces(i)); + BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol); } - return bFound; -} -//======================================================================= -//function : ComputeBiNormal -//purpose : -//======================================================================= -static Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF, - const TopoDS_Edge& theE, - gp_Dir& theDB) -{ - Standard_Boolean bDone = Standard_False; - Standard_Real aT1, aT2, aTm; + //------------------------------- + // Unwinding of extended Faces. + //------------------------------- // - const Handle(Geom2d_Curve)& aC2d = - BRep_Tool::CurveOnSurface(theE, theF, aT1, aT2); - if (aC2d.IsNull()) { - return bDone; + if ((myJoin == GeomAbs_Intersection) && myInter) { + TopTools_ListOfShape aLFailed; + BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False); + if (aLFailed.Extent()) { + myMakeLoops.Build(aLFailed, AsDes, IMOE); + } + } + else { + myMakeLoops.Build(LFE, AsDes, IMOE); } // - gp_Pnt2d aP2dNear; - gp_Pnt aP, aPNear; - // - const Handle(Geom_Curve)& aC3d = - BRep_Tool::Curve(theE, aT1, aT2); - // - aTm = (aT1 + aT2) * 0.5; - aP = aC3d->Value(aTm); - // - BOPTools_AlgoTools3D::PointNearEdge(theE, theF, aTm, 1.e-5, aP2dNear, aPNear); - // - gp_Vec aVB(aP, aPNear); - theDB = gp_Dir(aVB); - return !bDone; -} - -//======================================================================= -//function : UpdateOrigins -//purpose : -//======================================================================= -static void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, - BOPAlgo_Builder& theGF) -{ - TopTools_ListOfShape aLSTmp; - TopTools_MapOfShape aMFence; - BOPCol_ListIteratorOfListOfShape aItA; - TopTools_ListIteratorOfListOfShape aIt, aIt1; - // - const BOPCol_ListOfShape& aLSU = theGF.Arguments(); - aItA.Initialize(aLSU); - for (; aItA.More(); aItA.Next()) { - const TopoDS_Shape& aS = aItA.Value(); - // - if (!theOrigins.Contains(aS)) { - continue; - } - // - const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); - if (aLSIm.IsEmpty()) { - continue; - } - // - const TopTools_ListOfShape& aLS = theOrigins.FindFromKey(aS); - // - aIt.Initialize(aLSIm); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aSIm = aIt.Value(); - // - if (!theOrigins.Contains(aSIm)) { - theOrigins.Add(aSIm, aLS); - continue; - } - // - aMFence.Clear(); - // - TopTools_ListOfShape& aLS1 = theOrigins.ChangeFromKey(aSIm); - aLSTmp.Assign(aLS1); - // - aLS1.Clear(); - aIt1.Initialize(aLSTmp); - for (; aIt1.More(); aIt1.Next()) { - const TopoDS_Shape& aS1 = aIt1.Value(); - if (aMFence.Add(aS1)) { - aLS1.Append(aS1); +#ifdef OCCT_DEBUG + TopTools_IndexedMapOfShape COES; +#endif + //--------------------------- + // MAJ SD. for faces // + //--------------------------- + for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { + const TopoDS_Shape& FI = Exp.Current(); + myInitOffsetFace.SetRoot(FI); + TopoDS_Face OF = MapSF(FI).Face(); + if (MES.IsBound(OF)) { + OF = TopoDS::Face(MES(OF)); + if (IMOE.HasImage(OF)) { + const TopTools_ListOfShape& LOFE = IMOE.Image(OF); + myInitOffsetFace.Bind(FI,LOFE); + for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) { + const TopoDS_Shape& OFE = itLF.Value(); + myImageOffset.SetRoot(OFE); +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AF_%d",NbAF++); + DBRep::Set(name,OFE); + } +#endif + TopTools_MapOfShape View; + for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); + Exp2.More(); Exp2.Next()) { + const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); + + myAsDes->Add (OFE,COE); +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } +#endif + if (View.Add(COE)){ + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } + } } } - // - aIt1.Initialize(aLS); - for (; aIt1.More(); aIt1.Next()) { - const TopoDS_Shape& aS1 = aIt1.Value(); - if (aMFence.Add(aS1)) { - aLS1.Append(aS1); + else { + /*myInitOffsetFace.Bind(FI,OF); + myImageOffset.SetRoot(OF); +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AF_%d",NbAF++); + DBRep::Set(name,OF); } +#endif + const TopTools_ListOfShape& LE = AsDes->Descendant(OF); + for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { + const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); + if (IMOE.HasImage(OE)) { + const TopTools_ListOfShape& LOE = IMOE.Image(OE); + TopTools_ListIteratorOfListOfShape itLOE(LOE); + for (; itLOE.More(); itLOE.Next()) { + TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation()); + const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape); +// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation())); + myAsDes->Add(OF,COE); +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } +#endif + + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } + } + else { + myAsDes->Add(OF,OE); +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,OE); + COES.Add(OE); + } +#endif + + const TopTools_ListOfShape& LV = AsDes->Descendant(OE); + myAsDes->Add(OE,LV); + } + }*/ } } - } -} + else { + myInitOffsetFace.Bind(FI,OF); + myImageOffset.SetRoot(OF); + TopTools_MapOfShape View; + for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); + Exp2.More(); Exp2.Next()) { -//======================================================================= -//function : IsMicroEdge -//purpose : -//======================================================================= -static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge, - const Handle(IntTools_Context)& theCtx, - Standard_Real& theFuzz) -{ - TopoDS_Vertex aV1, aV2; - TopExp::Vertices(theEdge, aV1, aV2); - Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull(); - if (bNull) { - return Standard_False; - } - // - Standard_Boolean bMicro; - Standard_Real aT1, aT2; - IntTools_ShrunkRange aSR; - // - BRepAdaptor_Curve aBAC(theEdge); - // - aT1 = BRep_Tool::Parameter(aV1, theEdge); - aT2 = BRep_Tool::Parameter(aV2, theEdge); - if (aT2 < aT1) { - Standard_Real aTmp = aT1; - aT1 = aT2; - aT2 = aTmp; - } - // - aSR.SetContext(theCtx); - aSR.SetData(theEdge, aT1, aT2, aV1, aV2); - aSR.Perform(); - bMicro = (aSR.ErrorStatus() != 0); - if (!bMicro) { - Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2; - // - aTolV1 = BRep_Tool::Tolerance(aV1); - aTolV2 = BRep_Tool::Tolerance(aV2); - // - anEps = aBAC.Resolution(aTolV1 + aTolV2); - if (anEps < 1.e-8) { - anEps = 1.e-8; - } - // - aSR.ShrunkRange(aTS1, aTS2); - bMicro = (aTS2 - aTS1) <= anEps; - } - // - if (bMicro) { - Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC); - if (aLen > theFuzz) { - theFuzz = aLen; + const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); + myAsDes->Add (OF,COE); +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } +#endif + + if (View.Add(Exp2.Current())) { + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } + } } } - // - return bMicro; -} + // Modified by skv - Tue Mar 15 16:20:43 2005 + // Add methods for supporting history. + TopTools_MapOfShape aMapEdges; -//======================================================================= -//function : BuildSplitsOfFaces -//purpose : -//======================================================================= -void BRepOffset_MakeOffset::BuildSplitsOfFaces - (const TopTools_ListOfShape& theLF, - const Handle(BRepAlgo_AsDes)& theAsDes, - TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, - BRepAlgo_Image& theImage, - TopTools_ListOfShape& theLFailed, - const Standard_Boolean bLimited) -{ - BOPCol_ListOfShape aLS; - BOPCol_ListIteratorOfListOfShape aIt; - TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1; - TopTools_DataMapOfShapeListOfShape anEImages; - BRep_Builder aBB; - TopoDS_Compound aFaces; - // + for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { + const TopoDS_Shape& aFaceRef = Exp.Current(); + + Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE); + + for (; Exp2.More(); Exp2.Next()) { + const TopoDS_Shape& anEdgeRef = Exp2.Current(); + + if (aMapEdges.Add(anEdgeRef)) { + myInitOffsetEdge.SetRoot(anEdgeRef); + if (Build.IsBound(anEdgeRef)) { + TopoDS_Shape aNewShape = Build(anEdgeRef); + + if (aNewShape.ShapeType() == TopAbs_EDGE) { + if (IMOE.HasImage(aNewShape)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape); + + myInitOffsetEdge.Bind (anEdgeRef, aListNewE); + } else + myInitOffsetEdge.Bind (anEdgeRef, aNewShape); + } else { // aNewShape != TopAbs_EDGE + TopTools_ListOfShape aListNewEdge; + + for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) { + const TopoDS_Shape &aResEdge = ExpC.Current(); + + if (IMOE.HasImage(aResEdge)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge); + TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE); + + for (; aNewEIter.More(); aNewEIter.Next()) + aListNewEdge.Append(aNewEIter.Value()); + } else + aListNewEdge.Append(aResEdge); + } + + myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge); + } + } + else { // Free boundary. + TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef); + + if (MES.IsBound(aNewEdge)) + aNewEdge = MES(aNewEdge); + + if (IMOE.HasImage(aNewEdge)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge); + + myInitOffsetEdge.Bind (anEdgeRef, aListNewE); + } else + myInitOffsetEdge.Bind (anEdgeRef, aNewEdge); + } + } + } + } +// Modified by skv - Tue Mar 15 16:20:43 2005 + + //--------------------------- + // MAJ SD. for caps + //--------------------------- + //TopTools_MapOfShape View; + for (i = 1; i <= myFaces.Extent(); i++) { + const TopoDS_Shape& Cork = myFaces(i); + const TopTools_ListOfShape& LE = AsDes->Descendant(Cork); + for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { + const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); + if (IMOE.HasImage(OE)) { + const TopTools_ListOfShape& LOE = IMOE.Image(OE); + TopTools_ListIteratorOfListOfShape itLOE(LOE); + for (; itLOE.More(); itLOE.Next()) { + const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value()); + myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ; +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } +#endif + + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } + } + else { + myAsDes->Add(Cork,OE); + if (AsDes->HasDescendant(OE)) { + myAsDes->Add(OE,AsDes->Descendant(OE)); + } +#ifdef DRAW + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,OE); + COES.Add(OE); + } +#endif + } + } + } + +#ifdef OCCT_DEBUG + DEBVerticesControl (COES,myAsDes); + if ( ChronBuild) Clock.Show(); +#endif +} + +//======================================================================= +//function : BuildSplitsOfFaces +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::BuildSplitsOfFaces + (const TopTools_ListOfShape& theLF, + const Handle(BRepAlgo_AsDes)& theAsDes, + TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + BRepAlgo_Image& theImage, + TopTools_ListOfShape& theLFailed, + const Standard_Boolean bLimited) +{ + BOPCol_ListOfShape aLS; + BOPCol_ListIteratorOfListOfShape aIt; + TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1; + TopTools_DataMapOfShapeListOfShape anEImages; + BRep_Builder aBB; + TopoDS_Compound aFaces; + // aBB.MakeCompound(aFaces); // // firstly it is necessary to fuse all the edges @@ -1507,129 +1406,38 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces } } // - // check offset faces on the coincidence of the - // bi-normal directions with the original faces - // UpdateOrigins(theOrigins, aGF); // - Standard_Real anAngle; - Standard_Boolean bRem; - TopTools_ListOfShape aLFKeep; - // - const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(aF).First(); - // - aItLE.Initialize(aLFImages); - for (; aItLE.More(); ) { - const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLE.Value(); - const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); + if (aLFImages.Extent() > 1) { + TopTools_ListOfShape aLFKeep; // - bKeep = Standard_True; - bRem = Standard_True; + // check offset faces on the coincidence of the + // bi-normal directions with the original faces + CheckBiNormals(aLFImages, aF, theOrigins, aLFKeep); // - TopExp_Explorer aExp(aWIm, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); - // - if (BRep_Tool::Degenerated(aEIm)) { - continue; - } - // - if (!theOrigins.Contains(aEIm)) { - continue; - } + // limit the face + if (aLFImages.Extent() > 1) { + TopTools_ListOfShape aLFTmp = aLFImages; + aLFImages.Clear(); // - const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm); - const TopoDS_Shape& aSOr = aLEOr.First(); - if (aSOr.ShapeType() != TopAbs_EDGE) { - bRem = Standard_False; - break; + SortFaces(aLFTmp, aLFImages, Standard_True); + } + // + if (aLFKeep.Extent()) { + TopTools_MapOfShape aMFence; + aItLE.Initialize(aLFImages); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aFIm = aItLE.Value(); + aMFence.Add(aFIm); } // - if (aLEOr.Extent() > 1) { - TopTools_MapOfShape aME, aMV; - Standard_Integer aNbE, aNbV; - // - TopTools_ListIteratorOfListOfShape aItLS1(aLEOr); - for (; aItLS1.More(); aItLS1.Next()) { - const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS1.Value(); - aME.Add(aEOr); - // - TopExp_Explorer aExpE(aEOr, TopAbs_VERTEX); - for (; aExpE.More(); aExpE.Next()) { - const TopoDS_Shape& aV = aExpE.Current(); - aMV.Add(aV); - } - } - // - aNbV = aMV.Extent(); - aNbE = aME.Extent(); - // - if ((aNbE > 1) && (aNbV == 2*aNbE)) { - continue; + aItLE.Initialize(aLFKeep); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aFIm = aItLE.Value(); + if (aMFence.Add(aFIm)) { + aLFImages.Append(aFIm); } } - // - const TopoDS_Shape& aEOr = *(TopoDS_Edge*)&aLEOr.First(); - TopoDS_Edge aEOrF; - if (!FindShape(aEOr, aFOr, aEOrF)) { - continue; - } - // - // compute bi-normal for face aFIm on the edge aEIm - gp_Dir aDB1; - if (!ComputeBiNormal(aFIm, aEIm, aDB1)) { - continue; - } - // - // compute bi-normal for face aFOr on the edge aEOrF - gp_Dir aDB2; - if (!ComputeBiNormal(aFOr, aEOrF, aDB2)) { - continue; - } - // - // check coincidence of bi-normals - anAngle = aDB1.Angle(aDB2); - if (Abs(anAngle - M_PI) < Precision::Confusion()) { - bKeep = Standard_False; - bRem = bRem && Standard_True; - } - else { - bRem = Standard_False; - } - // - if (!bKeep && !bRem) { - break; - } - } - // - if (bRem && !bKeep) { - aLFImages.Remove(aItLE); - } - else { - if (!bRem && bKeep) { - aLFKeep.Append(aFIm); - } - aItLE.Next(); - } - } - // - TopTools_ListOfShape aLFTmp = aLFImages; - aLFImages.Clear(); - // limit the face - SortFaces(aLFTmp, aLFImages, Standard_True); - // - TopTools_MapOfShape aMFence; - aItLE.Initialize(aLFImages); - for (; aItLE.More(); aItLE.Next()) { - const TopoDS_Shape& aFIm = aItLE.Value(); - aMFence.Add(aFIm); - } - // - aItLE.Initialize(aLFKeep); - for (; aItLE.More(); aItLE.Next()) { - const TopoDS_Shape& aFIm = aItLE.Value(); - if (aMFence.Add(aFIm)) { - aLFImages.Append(aFIm); } } } @@ -1679,10 +1487,10 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces } //======================================================================= -//function : BuildOffsetByInter +//function : BuildOffsetByArc //purpose : //======================================================================= -void BRepOffset_MakeOffset::BuildOffsetByInter() +void BRepOffset_MakeOffset::BuildOffsetByArc() { #ifdef OCCT_DEBUG if ( ChronBuild) { @@ -1704,734 +1512,231 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() BRepLib::SortFaces(myShape,LF); - TopTools_DataMapOfShapeShape ShapeTgt; + TopTools_DataMapOfShapeShape EdgeTgt; for (itLF.Initialize(LF); itLF.More(); itLF.Next()) { const TopoDS_Face& F = TopoDS::Face(itLF.Value()); Standard_Real CurOffset = myOffset; if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F); - BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin); + BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin); TopTools_ListOfShape Let; myAnalyse.Edges(F,BRepOffset_Tangent,Let); TopTools_ListIteratorOfListOfShape itl(Let); for ( ; itl.More(); itl.Next()) { const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value()); - if ( !ShapeTgt.IsBound(Cur)) { + if ( !EdgeTgt.IsBound(Cur)) { TopoDS_Shape aLocalShape = OF.Generated(Cur); const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); // const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); - ShapeTgt.Bind(Cur,OF.Generated(Cur)); + EdgeTgt.Bind(Cur,OF.Generated(Cur)); TopoDS_Vertex V1,V2,OV1,OV2; TopExp::Vertices (Cur,V1,V2); TopExp::Vertices (OTE,OV1,OV2); TopTools_ListOfShape LE; - if (!ShapeTgt.IsBound(V1)) { + if (!EdgeTgt.IsBound(V1)) { myAnalyse.Edges(V1,BRepOffset_Tangent,LE); const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); if (LE.Extent() == LA.Extent()) - ShapeTgt.Bind(V1,OV1); + EdgeTgt.Bind(V1,OV1); } - if (!ShapeTgt.IsBound(V2)) { + if (!EdgeTgt.IsBound(V2)) { LE.Clear(); myAnalyse.Edges(V2,BRepOffset_Tangent,LE); const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); if (LE.Extent() == LA.Extent()) - ShapeTgt.Bind(V2,OV2); + EdgeTgt.Bind(V2,OV2); } } } MapSF.Bind(F,OF); } - //-------------------------------------------------------------------- - // MES : Map of OffsetShape -> Extended Shapes. - // Build : Map of Initial SS -> OffsetShape build by Inter. - // can be an edge or a compound of edges - //--------------------------------------------------------------------- - TopTools_DataMapOfShapeShape MES; - TopTools_DataMapOfShapeShape Build; - TopTools_ListOfShape Failed; - TopAbs_State Side = TopAbs_IN; - Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes(); - - //------------------------------------------------------------------- - // Extension of faces and calculation of new edges of intersection. - //------------------------------------------------------------------- - Standard_Boolean ExtentContext = 0; - if (myOffset > 0) ExtentContext = 1; - - BRepOffset_Inter3d Inter3 (AsDes,Side,myTol); - // Intersection between parallel faces - Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed ); - // Intersection with caps. - Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed ); - - - //--------------------------------------------------------------------------------- - // Extension of neighbor edges of new edges and intersection between neighbors. - //-------------------------------------------------------------------------------- - Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes(); - for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { - const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); -// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin -// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol); - BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes,AsDes2d,myOffset, myTol); -// Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End - } - //----------------------------------------------------------- - // Great restriction of new edges and update of AsDes. - //------------------------------------------ ---------------- - TopTools_IndexedMapOfShape NewEdges; - TopExp_Explorer Exp2,ExpC; - TopoDS_Shape NE; - TopoDS_Edge TNE; - TopoDS_Face NF; - TopTools_IndexedDataMapOfShapeListOfShape anOrigins; - - for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { - const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); - NF = MapSF(FI).Face(); - if (MES.IsBound(NF)) { - NF = TopoDS::Face(MES(NF)); - } - // - TopTools_MapOfShape View; - TopTools_IndexedMapOfShape VEmap; - Standard_Integer i, aNb; - // - TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); - TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); - // - aNb = VEmap.Extent(); - for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aS = VEmap(i); - if (!View.Add(aS)) { - continue; - } - // - if (Build.IsBound(aS)) { - NE = Build(aS); - if (NE.ShapeType() == TopAbs_EDGE) { - if (anOrigins.Contains(NE)) { - anOrigins.ChangeFromKey(NE).Append(aS); - } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(aS); - anOrigins.Add(NE, aLSx); - } - // - if (NewEdges.Add(NE)) { - TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes); + //-------------------------------------------------------- + // Construction of tubes on edge. + //-------------------------------------------------------- + BRepOffset_Type OT = BRepOffset_Convex; + if (myOffset < 0.) OT = BRepOffset_Concave; + + for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); + if (Done.Add(E)) { + const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E); + if (Anc.Extent() == 2) { + const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); + if (!L.IsEmpty() && L.First().Type() == OT) { + Standard_Real CurOffset = myOffset; + if ( myFaceOffset.IsBound(Anc.First())) + CurOffset = myFaceOffset(Anc.First()); + TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); + TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); + aLocalShape = MapSF(Anc.Last()).Generated(E); + TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape); +// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); +// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E)); + // find if exits tangent edges in the original shape + TopoDS_Edge E1f, E1l; + TopoDS_Vertex V1f, V1l; + TopExp::Vertices(E,V1f,V1l); + TopTools_ListOfShape TangE; + myAnalyse.TangentEdges(E,V1f,TangE); + // find if the pipe on the tangent edges are soon created. + TopTools_ListIteratorOfListOfShape itl(TangE); + Standard_Boolean Find = Standard_False; + for ( ; itl.More() && !Find; itl.Next()) { + if ( MapSF.IsBound(itl.Value())) { + TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f); + E1f = TopoDS::Edge(aLocalShape); +// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f)); + Find = Standard_True; + } } - } - else { - //------------------------------------------------------------ - // The Intersections are on several edges. - // The pieces without intersections with neighbors - // are removed from AsDes. - //------------------------------------------------------------ - for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { - TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); - if (NewEdges.Add(NEC)) { - NEC.Free(Standard_True); - if (anOrigins.Contains(NEC)) { - anOrigins.ChangeFromKey(NEC).Append(aS); - } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(aS); - anOrigins.Add(NEC, aLSx); - } - // - if (!AsDes2d->Descendant(NEC).IsEmpty()) { - TrimEdge (NEC,AsDes2d,AsDes); - } - else { - if (AsDes->HasAscendant(NEC)) { - AsDes->Remove(NEC); - } - } + TangE.Clear(); + myAnalyse.TangentEdges(E,V1l,TangE); + // find if the pipe on the tangent edges are soon created. + itl.Initialize(TangE); + Find = Standard_False; + for ( ; itl.More() && !Find; itl.Next()) { + if ( MapSF.IsBound(itl.Value())) { + TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l); + E1l = TopoDS::Edge(aLocalShape); +// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l)); + Find = Standard_True; } } + BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l); + MapSF.Bind(E,OF); } } else { - if (aS.ShapeType() != TopAbs_EDGE) { - continue; - } - // - NE = MapSF(FI).Generated(aS); - //// modified by jgv, 19.12.03 for OCC4455 //// - NE.Orientation(aS.Orientation()); - if (anOrigins.Contains(NE)) { - anOrigins.ChangeFromKey(NE).Append(aS); - } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(aS); - anOrigins.Add(NE, aLSx); - } - // - if (MES.IsBound(NE)) { - NE = MES(NE); - NE.Orientation(aS.Orientation()); - if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} - } - AsDes->Add(NF,NE); - } + // ---------------------- + // free border. + // ---------------------- + TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); + TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); +/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); + myInitOffsetEdge.SetRoot(E); // skv: supporting history. + myInitOffsetEdge.Bind (E,EOn1); + } } } - - //--------------------------------- - // Intersection 2D on // - //--------------------------------- - TopTools_ListOfShape LFE; - BRepAlgo_Image IMOE; - for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { - const TopoDS_Shape& FI = Exp.Current(); - const TopoDS_Shape& OFI = MapSF(FI).Face(); - if (MES.IsBound(OFI)) { - const TopoDS_Face& NF = TopoDS::Face(MES(OFI)); - LFE.Append(NF); - IMOE.SetRoot(NF); - // - if (anOrigins.Contains(NF)) { - anOrigins.ChangeFromKey(NF).Append(FI); + + //-------------------------------------------------------- + // Construction of spheres on vertex. + //-------------------------------------------------------- + Done.Clear(); + TopTools_ListIteratorOfListOfShape it; + + for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) { + const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current()); + if (Done.Add(V)) { + const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V); + TopTools_ListOfShape LE; + myAnalyse.Edges(V,OT,LE); + + if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) { + TopTools_ListOfShape LOE; + //-------------------------------------------------------- + // Return connected edges on tubes. + //-------------------------------------------------------- + for (it.Initialize(LE) ; it.More(); it.Next()) { + LOE.Append(MapSF(it.Value()).Generated(V).Reversed()); + } + //---------------------- + // construction sphere. + //----------------------- + const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First()); + const TopoDS_Shape& FF = LLA.First(); + Standard_Real CurOffset = myOffset; + if ( myFaceOffset.IsBound(FF)) + CurOffset = myFaceOffset(FF); + + BRepOffset_Offset OF(V,LOE,CurOffset); + MapSF.Bind(V,OF); } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(FI); - anOrigins.Add(NF, aLSx); + //-------------------------------------------------------------- + // Particular processing if V is at least a free border. + //------------------------------------------------------------- + TopTools_ListOfShape LBF; + myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF); + if (!LBF.IsEmpty()) { + Standard_Boolean First = Standard_True; + for (it.Initialize(LE) ; it.More(); it.Next()) { + if (First) { + myInitOffsetEdge.SetRoot(V); // skv: supporting history. + myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V)); + First = Standard_False; + } + else { + myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V)); + } + } } } } - - TopTools_ListIteratorOfListOfShape itLFE(LFE); - for (; itLFE.More(); itLFE.Next()) { - const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value()); - BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol); - } - //---------------------------------------------- - // Intersections 2d on caps. - //---------------------------------------------- - Standard_Integer i; - for (i = 1; i <= myFaces.Extent(); i++) { - const TopoDS_Face& Cork = TopoDS::Face(myFaces(i)); - BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol); - } - //------------------------------- - // Unwinding of extended Faces. - //------------------------------- - // - if ((myJoin == GeomAbs_Intersection) && myInter) { - TopTools_ListOfShape aLFailed; - BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False); - if (aLFailed.Extent()) { - myMakeLoops.Build(aLFailed, AsDes, IMOE); - } - } - else { - myMakeLoops.Build(LFE, AsDes, IMOE); - } - // -#ifdef OCCT_DEBUG - TopTools_IndexedMapOfShape COES; -#endif - //--------------------------- - // MAJ SD. for faces // - //--------------------------- - for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { - const TopoDS_Shape& FI = Exp.Current(); - myInitOffsetFace.SetRoot(FI); - TopoDS_Face OF = MapSF(FI).Face(); - if (MES.IsBound(OF)) { - OF = TopoDS::Face(MES(OF)); - if (IMOE.HasImage(OF)) { - const TopTools_ListOfShape& LOFE = IMOE.Image(OF); - myInitOffsetFace.Bind(FI,LOFE); - for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) { - const TopoDS_Shape& OFE = itLF.Value(); - myImageOffset.SetRoot(OFE); -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AF_%d",NbAF++); - DBRep::Set(name,OFE); - } -#endif - TopTools_MapOfShape View; - for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp2.More(); Exp2.Next()) { - const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); - - myAsDes->Add (OFE,COE); -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } -#endif - if (View.Add(COE)){ - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } - } - } - } - else { - /*myInitOffsetFace.Bind(FI,OF); - myImageOffset.SetRoot(OF); -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AF_%d",NbAF++); - DBRep::Set(name,OF); - } -#endif - const TopTools_ListOfShape& LE = AsDes->Descendant(OF); - for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { - const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); - if (IMOE.HasImage(OE)) { - const TopTools_ListOfShape& LOE = IMOE.Image(OE); - TopTools_ListIteratorOfListOfShape itLOE(LOE); - for (; itLOE.More(); itLOE.Next()) { - TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation()); - const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape); -// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation())); - myAsDes->Add(OF,COE); -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } -#endif - - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } - } - else { - myAsDes->Add(OF,OE); -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,OE); - COES.Add(OE); - } -#endif - - const TopTools_ListOfShape& LV = AsDes->Descendant(OE); - myAsDes->Add(OE,LV); - } - }*/ - } - } - else { - myInitOffsetFace.Bind(FI,OF); - myImageOffset.SetRoot(OF); - TopTools_MapOfShape View; - for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp2.More(); Exp2.Next()) { - - const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); - myAsDes->Add (OF,COE); -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } -#endif - - if (View.Add(Exp2.Current())) { - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } - } - } - } - // Modified by skv - Tue Mar 15 16:20:43 2005 - // Add methods for supporting history. - TopTools_MapOfShape aMapEdges; - - for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { - const TopoDS_Shape& aFaceRef = Exp.Current(); - - Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE); - - for (; Exp2.More(); Exp2.Next()) { - const TopoDS_Shape& anEdgeRef = Exp2.Current(); - - if (aMapEdges.Add(anEdgeRef)) { - myInitOffsetEdge.SetRoot(anEdgeRef); - if (Build.IsBound(anEdgeRef)) { - TopoDS_Shape aNewShape = Build(anEdgeRef); - - if (aNewShape.ShapeType() == TopAbs_EDGE) { - if (IMOE.HasImage(aNewShape)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape); - - myInitOffsetEdge.Bind (anEdgeRef, aListNewE); - } else - myInitOffsetEdge.Bind (anEdgeRef, aNewShape); - } else { // aNewShape != TopAbs_EDGE - TopTools_ListOfShape aListNewEdge; - - for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) { - const TopoDS_Shape &aResEdge = ExpC.Current(); - - if (IMOE.HasImage(aResEdge)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge); - TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE); - - for (; aNewEIter.More(); aNewEIter.Next()) - aListNewEdge.Append(aNewEIter.Value()); - } else - aListNewEdge.Append(aResEdge); - } - - myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge); - } - } - else { // Free boundary. - TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef); - - if (MES.IsBound(aNewEdge)) - aNewEdge = MES(aNewEdge); + //------------------------------------------------------------ + // Extension of parallel faces to the context. + // Extended faces are ordered in DS and removed from MapSF. + //------------------------------------------------------------ + if (!myFaces.IsEmpty()) ToContext (MapSF); - if (IMOE.HasImage(aNewEdge)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge); + //------------------------------------------------------ + // MAJ SD. + //------------------------------------------------------ + BRepOffset_Type RT = BRepOffset_Concave; + if (myOffset < 0.) RT = BRepOffset_Convex; + BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF); + for ( ; It.More(); It.Next()) { + const TopoDS_Shape& SI = It.Key(); + const BRepOffset_Offset& SF = It.Value(); + if (SF.Status() == BRepOffset_Reversed || + SF.Status() == BRepOffset_Degenerated ) { + //------------------------------------------------ + // Degenerated or returned faces are not stored. + //------------------------------------------------ + continue; + } - myInitOffsetEdge.Bind (anEdgeRef, aListNewE); - } else - myInitOffsetEdge.Bind (anEdgeRef, aNewEdge); + const TopoDS_Face& OF = It.Value().Face(); + myInitOffsetFace.Bind (SI,OF); + myInitOffsetFace.SetRoot (SI); // Initial<-> Offset + myImageOffset.SetRoot (OF); // FaceOffset root of images + + if (SI.ShapeType() == TopAbs_FACE) { + for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); + Exp.More(); Exp.Next()) { + //-------------------------------------------------------------------- + // To each face are associatedthe edges that restrict that + // The edges that do not generate tubes or are not tangent + // to two faces are removed. + //-------------------------------------------------------------------- + const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); + const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); + if (!L.IsEmpty() && L.First().Type() != RT) { + TopAbs_Orientation OO = E.Orientation(); + TopoDS_Shape aLocalShape = It.Value().Generated(E); + TopoDS_Edge OE = TopoDS::Edge(aLocalShape); +// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E)); + myAsDes->Add (OF,OE.Oriented(OO)); } } } - } -// Modified by skv - Tue Mar 15 16:20:43 2005 - - //--------------------------- - // MAJ SD. for caps - //--------------------------- - //TopTools_MapOfShape View; - for (i = 1; i <= myFaces.Extent(); i++) { - const TopoDS_Shape& Cork = myFaces(i); - const TopTools_ListOfShape& LE = AsDes->Descendant(Cork); - for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { - const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); - if (IMOE.HasImage(OE)) { - const TopTools_ListOfShape& LOE = IMOE.Image(OE); - TopTools_ListIteratorOfListOfShape itLOE(LOE); - for (; itLOE.More(); itLOE.Next()) { - const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value()); - myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ; -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } -#endif - - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } - } - else { - myAsDes->Add(Cork,OE); - if (AsDes->HasDescendant(OE)) { - myAsDes->Add(OE,AsDes->Descendant(OE)); - } -#ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,OE); - COES.Add(OE); - } -#endif + else { + for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); + Exp.More(); Exp.Next()) { + myAsDes->Add (OF,Exp.Current()); } } } - + #ifdef OCCT_DEBUG - DEBVerticesControl (COES,myAsDes); if ( ChronBuild) Clock.Show(); #endif } - //======================================================================= -//function : BuildOffsetByArc +//function : SelfInter //purpose : //======================================================================= -void BRepOffset_MakeOffset::BuildOffsetByArc() -{ -#ifdef OCCT_DEBUG - if ( ChronBuild) { - cout << " CONSTRUCTION OF OFFSETS :" << endl; - Clock.Reset(); - Clock.Start(); - } -#endif - - BRepOffset_DataMapOfShapeOffset MapSF; - TopTools_MapOfShape Done; - Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False; - //-------------------------------------------------------- - // Construction of faces parallel to initial faces - //-------------------------------------------------------- - TopExp_Explorer Exp; - TopTools_ListOfShape LF; - TopTools_ListIteratorOfListOfShape itLF; - - BRepLib::SortFaces(myShape,LF); - - TopTools_DataMapOfShapeShape EdgeTgt; - for (itLF.Initialize(LF); itLF.More(); itLF.Next()) { - const TopoDS_Face& F = TopoDS::Face(itLF.Value()); - Standard_Real CurOffset = myOffset; - if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F); - BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin); - TopTools_ListOfShape Let; - myAnalyse.Edges(F,BRepOffset_Tangent,Let); - TopTools_ListIteratorOfListOfShape itl(Let); - - for ( ; itl.More(); itl.Next()) { - const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value()); - if ( !EdgeTgt.IsBound(Cur)) { - TopoDS_Shape aLocalShape = OF.Generated(Cur); - const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); -// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); - EdgeTgt.Bind(Cur,OF.Generated(Cur)); - TopoDS_Vertex V1,V2,OV1,OV2; - TopExp::Vertices (Cur,V1,V2); - TopExp::Vertices (OTE,OV1,OV2); - TopTools_ListOfShape LE; - if (!EdgeTgt.IsBound(V1)) { - myAnalyse.Edges(V1,BRepOffset_Tangent,LE); - const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); - if (LE.Extent() == LA.Extent()) - EdgeTgt.Bind(V1,OV1); - } - if (!EdgeTgt.IsBound(V2)) { - LE.Clear(); - myAnalyse.Edges(V2,BRepOffset_Tangent,LE); - const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); - if (LE.Extent() == LA.Extent()) - EdgeTgt.Bind(V2,OV2); - } - } - } - MapSF.Bind(F,OF); - } - //-------------------------------------------------------- - // Construction of tubes on edge. - //-------------------------------------------------------- - BRepOffset_Type OT = BRepOffset_Convex; - if (myOffset < 0.) OT = BRepOffset_Concave; - - for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) { - const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); - if (Done.Add(E)) { - const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E); - if (Anc.Extent() == 2) { - const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); - if (!L.IsEmpty() && L.First().Type() == OT) { - Standard_Real CurOffset = myOffset; - if ( myFaceOffset.IsBound(Anc.First())) - CurOffset = myFaceOffset(Anc.First()); - TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); - TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); - aLocalShape = MapSF(Anc.Last()).Generated(E); - TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape); -// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); -// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E)); - // find if exits tangent edges in the original shape - TopoDS_Edge E1f, E1l; - TopoDS_Vertex V1f, V1l; - TopExp::Vertices(E,V1f,V1l); - TopTools_ListOfShape TangE; - myAnalyse.TangentEdges(E,V1f,TangE); - // find if the pipe on the tangent edges are soon created. - TopTools_ListIteratorOfListOfShape itl(TangE); - Standard_Boolean Find = Standard_False; - for ( ; itl.More() && !Find; itl.Next()) { - if ( MapSF.IsBound(itl.Value())) { - TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f); - E1f = TopoDS::Edge(aLocalShape); -// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f)); - Find = Standard_True; - } - } - TangE.Clear(); - myAnalyse.TangentEdges(E,V1l,TangE); - // find if the pipe on the tangent edges are soon created. - itl.Initialize(TangE); - Find = Standard_False; - for ( ; itl.More() && !Find; itl.Next()) { - if ( MapSF.IsBound(itl.Value())) { - TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l); - E1l = TopoDS::Edge(aLocalShape); -// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l)); - Find = Standard_True; - } - } - BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l); - MapSF.Bind(E,OF); - } - } - else { - // ---------------------- - // free border. - // ---------------------- - TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); - TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); -/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); - myInitOffsetEdge.SetRoot(E); // skv: supporting history. - myInitOffsetEdge.Bind (E,EOn1); - } - } - } - - //-------------------------------------------------------- - // Construction of spheres on vertex. - //-------------------------------------------------------- - Done.Clear(); - TopTools_ListIteratorOfListOfShape it; - - for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) { - const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current()); - if (Done.Add(V)) { - const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V); - TopTools_ListOfShape LE; - myAnalyse.Edges(V,OT,LE); - - if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) { - TopTools_ListOfShape LOE; - //-------------------------------------------------------- - // Return connected edges on tubes. - //-------------------------------------------------------- - for (it.Initialize(LE) ; it.More(); it.Next()) { - LOE.Append(MapSF(it.Value()).Generated(V).Reversed()); - } - //---------------------- - // construction sphere. - //----------------------- - const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First()); - const TopoDS_Shape& FF = LLA.First(); - Standard_Real CurOffset = myOffset; - if ( myFaceOffset.IsBound(FF)) - CurOffset = myFaceOffset(FF); - - BRepOffset_Offset OF(V,LOE,CurOffset); - MapSF.Bind(V,OF); - } - //-------------------------------------------------------------- - // Particular processing if V is at least a free border. - //------------------------------------------------------------- - TopTools_ListOfShape LBF; - myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF); - if (!LBF.IsEmpty()) { - Standard_Boolean First = Standard_True; - for (it.Initialize(LE) ; it.More(); it.Next()) { - if (First) { - myInitOffsetEdge.SetRoot(V); // skv: supporting history. - myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V)); - First = Standard_False; - } - else { - myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V)); - } - } - } - } - } - - //------------------------------------------------------------ - // Extension of parallel faces to the context. - // Extended faces are ordered in DS and removed from MapSF. - //------------------------------------------------------------ - if (!myFaces.IsEmpty()) ToContext (MapSF); - - //------------------------------------------------------ - // MAJ SD. - //------------------------------------------------------ - BRepOffset_Type RT = BRepOffset_Concave; - if (myOffset < 0.) RT = BRepOffset_Convex; - BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF); - for ( ; It.More(); It.Next()) { - const TopoDS_Shape& SI = It.Key(); - const BRepOffset_Offset& SF = It.Value(); - if (SF.Status() == BRepOffset_Reversed || - SF.Status() == BRepOffset_Degenerated ) { - //------------------------------------------------ - // Degenerated or returned faces are not stored. - //------------------------------------------------ - continue; - } - - const TopoDS_Face& OF = It.Value().Face(); - myInitOffsetFace.Bind (SI,OF); - myInitOffsetFace.SetRoot (SI); // Initial<-> Offset - myImageOffset.SetRoot (OF); // FaceOffset root of images - - if (SI.ShapeType() == TopAbs_FACE) { - for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp.More(); Exp.Next()) { - //-------------------------------------------------------------------- - // To each face are associatedthe edges that restrict that - // The edges that do not generate tubes or are not tangent - // to two faces are removed. - //-------------------------------------------------------------------- - const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); - const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); - if (!L.IsEmpty() && L.First().Type() != RT) { - TopAbs_Orientation OO = E.Orientation(); - TopoDS_Shape aLocalShape = It.Value().Generated(E); - TopoDS_Edge OE = TopoDS::Edge(aLocalShape); -// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E)); - myAsDes->Add (OF,OE.Oriented(OO)); - } - } - } - else { - for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp.More(); Exp.Next()) { - myAsDes->Add (OF,Exp.Current()); - } - } - } - -#ifdef OCCT_DEBUG - if ( ChronBuild) Clock.Show(); -#endif -} - - - -//======================================================================= -//function : SelfInter -//purpose : -//======================================================================= - void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/) { #ifdef OCCT_DEBUG @@ -2449,12 +1754,10 @@ void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/) #endif } - //======================================================================= //function : ToContext //purpose : //======================================================================= - void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) { TopTools_DataMapOfShapeShape Created; @@ -2598,12 +1901,10 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) } } - //======================================================================= //function : UpdateFaceOffset //purpose : //======================================================================= - void BRepOffset_MakeOffset::UpdateFaceOffset() { TopTools_MapOfShape M; @@ -2643,7 +1944,6 @@ void BRepOffset_MakeOffset::UpdateFaceOffset() //function : CorrectConicalFaces //purpose : //======================================================================= - void BRepOffset_MakeOffset::CorrectConicalFaces() { TopTools_SequenceOfShape Cones; @@ -3078,12 +2378,10 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod #endif } - //======================================================================= //function : MakeLoops //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif) { #ifdef OCCT_DEBUG @@ -3135,7 +2433,6 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif) //purpose : Reconstruction of topologically unchanged faces that // share edges that were reconstructed. //======================================================================= - void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/) { #ifdef OCCT_DEBUG @@ -3162,49 +2459,10 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/) #endif } -//======================================================================= -//function : UpdateInitOffset -//purpose : Update and cleaning of myInitOffset -//======================================================================= - -static void UpdateInitOffset (BRepAlgo_Image& myInitOffset, - BRepAlgo_Image& myImageOffset, - const TopoDS_Shape& myOffsetShape, - const TopAbs_ShapeEnum &theShapeType) // skv -{ - BRepAlgo_Image NIOF; - const TopTools_ListOfShape& Roots = myInitOffset.Roots(); - TopTools_ListIteratorOfListOfShape it(Roots); - for (; it.More(); it.Next()) { - NIOF.SetRoot (it.Value()); - } - for (it.Initialize(Roots); it.More(); it.Next()) { - const TopoDS_Shape& SI = it.Value(); - TopTools_ListOfShape LI; - TopTools_ListOfShape L1; - myInitOffset.LastImage(SI,L1); - TopTools_ListIteratorOfListOfShape itL1(L1); - for (; itL1.More(); itL1.Next()) { - const TopoDS_Shape& O1 = itL1.Value(); - TopTools_ListOfShape L2; - myImageOffset.LastImage(O1,L2); - LI.Append(L2); - } - NIOF.Bind(SI,LI); - } -// Modified by skv - Mon Apr 4 18:17:27 2005 Begin -// Supporting history. -// NIOF.Filter(myOffsetShape,TopAbs_FACE); - NIOF.Filter(myOffsetShape, theShapeType); -// Modified by skv - Mon Apr 4 18:17:27 2005 End - myInitOffset = NIOF; -} - //======================================================================= //function : MakeMissingWalls //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeMissingWalls () { TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary) @@ -3572,71 +2830,6 @@ void BRepOffset_MakeOffset::MakeMissingWalls () } } -//======================================================================= -//function : CheckNormals -//purpose : -//======================================================================= -static Standard_Boolean CheckNormals(const TopoDS_Face& theFIm, - const TopoDS_Face& theFOr) -{ - - Standard_Real aUMin, aUMax, aVMin, aVMax, aU, aV, anAngle; - gp_Pnt aP; - gp_Vec aVecU, aVecV, aVNIm, aVNOr; - Standard_Boolean bIsCollinear; - // - BRepAdaptor_Surface aSFIm(theFIm), aSFOr(theFOr); - // - aUMin = aSFIm.FirstUParameter(); - aUMax = aSFIm.LastUParameter(); - aVMin = aSFIm.FirstVParameter(); - aVMax = aSFIm.LastVParameter(); - // - aU = (aUMin + aUMax) * 0.5; - if (Precision::IsInfinite(aUMin) && - Precision::IsInfinite(aUMax)) { - aU = 0.; - } - else if (Precision::IsInfinite(aUMin) && - !Precision::IsInfinite(aUMax)) { - aU = aUMax; - } - else if (!Precision::IsInfinite(aUMin) && - Precision::IsInfinite(aUMax)) { - aU = aUMin; - } - // - aV = (aVMin + aVMax) * 0.5; - if (Precision::IsInfinite(aVMin) && - Precision::IsInfinite(aVMax)) { - aV = 0.; - } - else if (Precision::IsInfinite(aVMin) && - !Precision::IsInfinite(aVMax)) { - aV = aVMax; - } - else if (!Precision::IsInfinite(aVMin) && - Precision::IsInfinite(aVMax)) { - aV = aVMin; - } - // - aSFIm.D1(aU, aV, aP, aVecU, aVecV); - aVNIm = aVecU.Crossed(aVecV); - if (theFIm.Orientation() == TopAbs_REVERSED) { - aVNIm.Reverse(); - } - // - aSFOr.D1(aU, aV, aP, aVecU, aVecV); - aVNOr = aVecU.Crossed(aVecV); - if (theFOr.Orientation() == TopAbs_REVERSED) { - aVNOr.Reverse(); - } - // - anAngle = aVNIm.Angle(aVNOr); - bIsCollinear = (anAngle < Precision::Confusion()); - return bIsCollinear; -} - //======================================================================= //function : MakeShells //purpose : @@ -3729,7 +2922,7 @@ void BRepOffset_MakeOffset::MakeShells() aBB.Add(aCSF, aF); } // - bDone = (myOffset > 0); + bDone = ((myOffset > 0) || !bFaces); if (bDone) { UpdateOrigins(anOrigins, aGF); // @@ -3785,30 +2978,14 @@ void BRepOffset_MakeOffset::MakeShells() // if (bDone) { for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aFx = aMFS.FindKey(i); const BOPCol_ListOfShape& aLSx = aMFS(i); if (aLSx.Extent() == 1) { - // check orientation - const TopoDS_Face& aF = *(TopoDS_Face*)&aFx; - if (!anOrigins.Contains(aF)) { - aLSF2.Append(aFx); - continue; - } - // - const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx); - aItLS.Initialize(aLFOr); - for (; aItLS.More(); aItLS.Next()) { - const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); - // - if (CheckNormals(aF, aFOr)) { - aLSF2.Append(aFx); - break; - } - } + const TopoDS_Shape& aFx = aMFS.FindKey(i); + aLSF2.Append(aFx); } } // - // make solid containing most outer faces + // make solids from the new list BOPAlgo_MakerVolume aMV2; // aMV2.SetArguments(aLSF2); @@ -3818,6 +2995,43 @@ void BRepOffset_MakeOffset::MakeShells() bDone = (aMV2.ErrorStatus() == 0); if (bDone) { aResult = aMV2.Shape(); + if (aResult.ShapeType() == TopAbs_COMPOUND) { + BOPCol_ListOfShape aLSF3; + // + aExp.Init(aResult, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current(); + // + // check orientation + if (!anOrigins.Contains(aF)) { + aLSF3.Append(aF); + continue; + } + // + const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aF); + aItLS.Initialize(aLFOr); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); + // + if (CheckNormals(aF, aFOr)) { + aLSF3.Append(aF); + break; + } + } + } + // + // make solid containing most outer faces + BOPAlgo_MakerVolume aMV3; + // + aMV3.SetArguments(aLSF3); + aMV3.SetIntersect(Standard_False); + // + aMV3.Perform(); + bDone = (aMV3.ErrorStatus() == 0); + if (bDone) { + aResult = aMV3.Shape(); + } + } } } } @@ -3850,369 +3064,1307 @@ void BRepOffset_MakeOffset::MakeShells() } } } - // - if (!bDone) { - BRepTools_Quilt Glue; - BOPCol_ListIteratorOfListOfShape aItLS; - // - aItLS.Initialize(aLSF); - for (; aItLS.More(); aItLS.Next()) { - const TopoDS_Shape& aF = aItLS.Value(); - Glue.Add(aF); - } - myOffsetShape = Glue.Shells(); - } + // + if (!bDone) { + BRepTools_Quilt Glue; + BOPCol_ListIteratorOfListOfShape aItLS; + // + aItLS.Initialize(aLSF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aF = aItLS.Value(); + Glue.Add(aF); + } + myOffsetShape = Glue.Shells(); + } +} + +//======================================================================= +//function : MakeSolid +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::MakeSolid () +{ + if (myOffsetShape.IsNull()) return; + +// Modified by skv - Mon Apr 4 18:17:27 2005 Begin +// Supporting history. + UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE); + UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE); +// Modified by skv - Mon Apr 4 18:17:27 2005 End + TopExp_Explorer exp; + BRep_Builder B; + Standard_Integer NbShell = 0; + TopoDS_Compound NC; + TopoDS_Shape S1; + B.MakeCompound (NC); + + for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) { + TopoDS_Shell Sh = TopoDS::Shell(exp.Current()); + if (myThickening && myOffset > 0.) + Sh.Reverse(); + NbShell++; + if (Sh.Closed()) { + TopoDS_Solid Sol; + B.MakeSolid (Sol); + B.Add (Sol,Sh); + Sol.Closed(Standard_True); + B.Add (NC,Sol); + if (NbShell == 1) S1 = Sol; + } + else { + B.Add (NC,Sh); + if (NbShell == 1) S1 = Sh; + } + } + if (NbShell == 1) myOffsetShape = S1; + else myOffsetShape = NC; +} + +//======================================================================= +//function : SelectShells +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::SelectShells () +{ + TopTools_MapOfShape FreeEdges; + TopExp_Explorer exp(myShape,TopAbs_EDGE); + //------------------------------------------------------------- + // FreeEdges all edges that can have free border in the + // parallel shell + // 1 - free borders of myShape . + //------------------------------------------------------------- + for ( ; exp.More(); exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E); + if (LA.Extent() < 2) { + if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) { + FreeEdges.Add(E); + } + } + } + // myShape has free borders and there are no caps + // no unwinding 3d. + if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return; + + myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges); +} + +//======================================================================= +//function : OffsetFacesFromShapes +//purpose : +//======================================================================= +const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const +{ + return myInitOffsetFace; +} + +// Modified by skv - Tue Mar 15 16:20:43 2005 Begin + +//======================================================================= +//function : GetJoinType +//purpose : Query offset join type. +//======================================================================= +GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const +{ + return myJoin; +} + +//======================================================================= +//function : OffsetEdgesFromShapes +//purpose : +//======================================================================= +const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const +{ + return myInitOffsetEdge; +} + +// Modified by skv - Tue Mar 15 16:20:43 2005 End + +//======================================================================= +//function : ClosingFaces +//purpose : +//======================================================================= +const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const +{ + return myFaces; +} + +//======================================================================= +//function : EncodeRegularity +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::EncodeRegularity () +{ +#ifdef OCCT_DEBUG + if (ChronBuild) { + cout << " CODING OF REGULARITIES:" << endl; + Clock.Reset(); + Clock.Start(); + } +#endif + + if (myOffsetShape.IsNull()) return; + // find edges G1 in the result + TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE); + + BRep_Builder B; + TopTools_MapOfShape MS; + + for ( ; exp.More(); exp.Next()) { + TopoDS_Edge OE = TopoDS::Edge(exp.Current()); + BRepLib::BuildCurve3d(OE,myTol); + TopoDS_Edge ROE = OE; + + if ( !MS.Add(OE)) continue; + + if ( myImageOffset.IsImage(OE)) + ROE = TopoDS::Edge(myImageOffset.Root(OE)); + + const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE); + + if (LofOF.Extent() != 2) { +#ifdef OCCT_DEBUG_VERB + cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl; +#endif + continue; + } + + const TopoDS_Face& F1 = TopoDS::Face(LofOF.First()); + const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() ); + + if ( F1.IsNull() || F2.IsNull()) + continue; + + const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1); + const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2); + + TopAbs_ShapeEnum Type1 = Root1.ShapeType(); + TopAbs_ShapeEnum Type2 = Root2.ShapeType(); + + if (F1.IsSame(F2)) { + if (BRep_Tool::IsClosed(OE,F1)) { + // Temporary Debug for the Bench. + // Check with YFR. + // In mode intersection, the edges are not coded in myInitOffsetEdge + // so, manage case by case + // Note DUB; for Hidden parts, it is NECESSARY to code CN + // Analytic Surfaces. + if (myJoin == GeomAbs_Intersection) { + BRepAdaptor_Surface BS(F1,Standard_False); + GeomAbs_SurfaceType SType = BS.GetType(); + if (SType == GeomAbs_Cylinder || + SType == GeomAbs_Cone || + SType == GeomAbs_Sphere || + SType == GeomAbs_Torus ) { + B.Continuity(OE,F1,F1,GeomAbs_CN); + } + else { + // See YFR : MaJ of myInitOffsetFace + } + } + else if (myInitOffsetEdge.IsImage(ROE)) { + if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { + const TopoDS_Face& FRoot = TopoDS::Face(Root1); + const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE)); + GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot); + if (Conti == GeomAbs_CN) { + B.Continuity(OE,F1,F1,GeomAbs_CN); + } + else if ( Conti > GeomAbs_C0) { + B.Continuity(OE,F1,F1,GeomAbs_G1); + } + } + } + } + continue; + } + + + // code regularities G1 between : + // - sphere and tube : one root is a vertex, the other is an edge + // and the vertex is included in the edge + // - face and tube : one root is a face, the other an edge + // and the edge is included in the face + // - face and face : if two root faces are tangent in + // the initial shape, they will be tangent in the offset shape + // - tube and tube : if 2 edges generating tubes are + // tangents, the 2 will be tangent either. + if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) { + TopoDS_Vertex V1,V2; + TopExp::Vertices(TopoDS::Edge(Root1), V1, V2); + if ( V1.IsSame(Root2) || V2.IsSame(Root2)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + } + } + else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) { + TopoDS_Vertex V1,V2; + TopExp::Vertices(TopoDS::Edge(Root2), V1, V2); + if ( V1.IsSame(Root1) || V2.IsSame(Root1)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + } + } + else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) { + TopExp_Explorer exp2(Root1,TopAbs_EDGE); + for ( ; exp2.More(); exp2.Next()) { + if ( exp2.Current().IsSame(Root2)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + break; + } + } + } + else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) { + TopExp_Explorer exp2(Root2,TopAbs_EDGE); + for ( ; exp2.More(); exp2.Next()) { + if ( exp2.Current().IsSame(Root1)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + break; + } + } + } + else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { + // if two root faces are tangent in + // the initial shape, they will be tangent in the offset shape + TopTools_ListOfShape LE,LV; + BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1), + TopoDS::Face(Root2), + LE,LV); + if ( LE.Extent() == 1) { + const TopoDS_Edge& Ed = TopoDS::Edge(LE.First()); + if ( myAnalyse.HasAncestor(Ed)) { + const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed); + if (LI.Extent() == 1 && + LI.First().Type() == BRepOffset_Tangent) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + } + } + } + } + else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) { + TopTools_ListOfShape LV; + TopExp_Explorer exp1,exp2; + for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) { + TopExp_Explorer exp2(F2,TopAbs_EDGE); + for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) { + if (exp1.Current().IsSame(exp2.Current())) { + LV.Append(exp1.Current()); + } + } + } + if ( LV.Extent() == 1) { + TopTools_ListOfShape LEdTg; + myAnalyse.TangentEdges(TopoDS::Edge(Root1), + TopoDS::Vertex(LV.First()), + LEdTg); + TopTools_ListIteratorOfListOfShape it(LEdTg); + for (; it.More(); it.Next()) { + if ( it.Value().IsSame(Root2)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + break; + } + } + } + } + } + +#ifdef OCCT_DEBUG + if ( ChronBuild) Clock.Show(); +#endif +} + + +//======================================================================= +// static methods implementation +//======================================================================= + +//======================================================================= +//function : UpDateTolerance +//purpose : +//======================================================================= +void UpdateTolerance (TopoDS_Shape& S, + const TopTools_IndexedMapOfShape& Faces) +{ + BRep_Builder B; + TopTools_MapOfShape View; + TopoDS_Vertex V[2]; + + // The edges of caps are not modified. + Standard_Integer j; + for (j = 1; j <= Faces.Extent(); j++) { + const TopoDS_Shape& F = Faces(j); + TopExp_Explorer Exp; + for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) { + View.Add(Exp.Current()); + } + } + + TopExp_Explorer Exp; + for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) { + TopoDS_Edge E = TopoDS::Edge(Exp.Current()); + if (View.Add(E)) { + Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E); + Standard_Real Tol = EdgeCorrector->Tolerance(); + B.UpdateEdge (E,Tol); + + // Update the vertices. + TopExp::Vertices(E,V[0],V[1]); + + for (Standard_Integer i = 0 ; i <=1 ; i++) { + if (View.Add(V[i])) { + Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape()); + TV->Tolerance(0.); + Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]); + B.UpdateVertex (V[i],VertexCorrector->Tolerance()); + // use the occasion to clean the vertices. + (TV->ChangePoints()).Clear(); + } + B.UpdateVertex(V[i],Tol); + } + } + } +} + +//======================================================================= +//function : FindParameter +//purpose : +//======================================================================= +Standard_Boolean FindParameter(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& U) +{ + // Search the vertex in the edge + + Standard_Boolean rev = Standard_False; + TopoDS_Shape VF; + TopAbs_Orientation orient = TopAbs_INTERNAL; + + TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD)); + + // if the edge has no vertices + // and is degenerated use the vertex orientation + // RLE, june 94 + + if (!itv.More() && BRep_Tool::Degenerated(E)) { + orient = V.Orientation(); + } + + while (itv.More()) { + const TopoDS_Shape& Vcur = itv.Value(); + if (V.IsSame(Vcur)) { + if (VF.IsNull()) { + VF = Vcur; + } + else { + rev = E.Orientation() == TopAbs_REVERSED; + if (Vcur.Orientation() == V.Orientation()) { + VF = Vcur; + } + } + } + itv.Next(); + } + + if (!VF.IsNull()) orient = VF.Orientation(); + + Standard_Real f,l; + + if (orient == TopAbs_FORWARD) { + BRep_Tool::Range(E,f,l); + //return (rev) ? l : f; + U = (rev) ? l : f; + return Standard_True; + } + + else if (orient == TopAbs_REVERSED) { + BRep_Tool::Range(E,f,l); + //return (rev) ? f : l; + U = (rev) ? f : l; + return Standard_True; + } + + else { + TopLoc_Location L; + const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l); + L = L.Predivided(V.Location()); + if (!C.IsNull() || BRep_Tool::Degenerated(E)) { + BRep_ListIteratorOfListOfPointRepresentation itpr + ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); + + while (itpr.More()) { + const Handle(BRep_PointRepresentation)& pr = itpr.Value(); + if (pr->IsPointOnCurve(C,L)) { + Standard_Real p = pr->Parameter(); + Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux + if (!C.IsNull()) { + // Closed curves RLE 16 june 94 + if (Precision::IsNegativeInfinite(f)) + { + //return pr->Parameter();//p; + U = pr->Parameter(); + return Standard_True; + } + if (Precision::IsPositiveInfinite(l)) + { + //return pr->Parameter();//p; + U = pr->Parameter(); + return Standard_True; + } + gp_Pnt Pf = C->Value(f).Transformed(L.Transformation()); + gp_Pnt Pl = C->Value(l).Transformed(L.Transformation()); + Standard_Real tol = BRep_Tool::Tolerance(V); + if (Pf.Distance(Pl) < tol) { + if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) { + if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f; + else res = l;//p = l; + } + } + } + //return res;//p; + U = res; + return Standard_True; + } + itpr.Next(); + } + } + else { + // no 3d curve !! + // let us try with the first pcurve + Handle(Geom2d_Curve) PC; + Handle(Geom_Surface) S; + BRep_Tool::CurveOnSurface(E,PC,S,L,f,l); + L = L.Predivided(V.Location()); + BRep_ListIteratorOfListOfPointRepresentation itpr + ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); + + while (itpr.More()) { + const Handle(BRep_PointRepresentation)& pr = itpr.Value(); + if (pr->IsPointOnCurveOnSurface(PC,S,L)) { + Standard_Real p = pr->Parameter(); + // Closed curves RLE 16 june 94 + if (PC->IsClosed()) { + if ((p == PC->FirstParameter()) || + (p == PC->LastParameter())) { + if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter(); + else p = PC->LastParameter(); + } + } + //return p; + U = p; + return Standard_True; + } + itpr.Next(); + } + } + } + + //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge"); + return Standard_False; +} + +//======================================================================= +//function : GetEdgePoints +//purpose : gets the first, last and middle points of the edge +//======================================================================= +void GetEdgePoints(const TopoDS_Edge& anEdge, + const TopoDS_Face& aFace, + gp_Pnt& fPnt, gp_Pnt& mPnt, + gp_Pnt& lPnt) +{ + Standard_Real f, l; + Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l ); + gp_Pnt2d fPnt2d = theCurve->Value(f); + gp_Pnt2d lPnt2d = theCurve->Value(l); + gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l)); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y()); + lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y()); + mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y()); +} + +//======================================================================= +//function : FillContours +//purpose : fills free boundary contours and faces connected (MapEF) +//======================================================================= +void FillContours(const TopoDS_Shape& aShape, + const BRepOffset_Analyse& Analyser, + TopTools_DataMapOfShapeListOfShape& Contours, + TopTools_DataMapOfShapeShape& MapEF) +{ + TopTools_ListOfShape Edges; + + TopExp_Explorer Explo(aShape, TopAbs_FACE); + BRepTools_WireExplorer Wexp; + + for (; Explo.More(); Explo.Next()) + { + TopoDS_Face aFace = TopoDS::Face(Explo.Current()); + TopoDS_Iterator itf(aFace); + for (; itf.More(); itf.Next()) + { + TopoDS_Wire aWire = TopoDS::Wire(itf.Value()); + for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next()) + { + TopoDS_Edge anEdge = Wexp.Current(); + if (BRep_Tool::Degenerated(anEdge)) + continue; + const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge); + if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary) + { + MapEF.Bind(anEdge, aFace); + Edges.Append(anEdge); + } + } + } + } + + TopTools_ListIteratorOfListOfShape itl; + while (!Edges.IsEmpty()) + { + TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First()); + Edges.RemoveFirst(); + TopoDS_Vertex StartVertex, CurVertex; + TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True); + TopTools_ListOfShape aContour; + aContour.Append(StartEdge); + while (!CurVertex.IsSame(StartVertex)) + for (itl.Initialize(Edges); itl.More(); itl.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex)) + { + aContour.Append(anEdge); + CurVertex = (V1.IsSame(CurVertex))? V2 : V1; + Edges.Remove(itl); + break; + } + } + Contours.Bind(StartVertex, aContour); + } +} + +//======================================================================= +//function : RemoveCorks +//purpose : +//======================================================================= +void RemoveCorks (TopoDS_Shape& S, + TopTools_IndexedMapOfShape& Faces) +{ + TopoDS_Compound SS; + BRep_Builder B; + B.MakeCompound (SS); + //----------------------------------------------------- + // Construction of a shape without caps. + // and Orientation of caps as in shape S. + //----------------------------------------------------- + TopExp_Explorer exp(S,TopAbs_FACE); + for (; exp.More(); exp.Next()) { + const TopoDS_Shape& Cork = exp.Current(); + if (!Faces.Contains(Cork)) { + B.Add(SS,Cork); + } + else { + //Faces.Remove (Cork); + //begin instead of Remove// + TopoDS_Shape LastShape = Faces(Faces.Extent()); + Faces.RemoveLast(); + if (Faces.FindIndex(Cork) != 0) + Faces.Substitute(Faces.FindIndex(Cork), LastShape); + //end instead of Remove // + Faces.Add(Cork); // to reset it with proper orientation. + } + } + S = SS; +#ifdef DRAW + if ( AffichOffC) + DBRep::Set("myInit", SS); +#endif + +} + +//======================================================================= +//function : IsConnectedShell +//purpose : +//======================================================================= +Standard_Boolean IsConnectedShell( const TopoDS_Shape& S ) +{ + BRepTools_Quilt Glue; + Glue.Add( S ); + + TopoDS_Shape SS = Glue.Shells(); + TopExp_Explorer Explo( SS, TopAbs_SHELL ); + Explo.Next(); + if (Explo.More()) + return Standard_False; + + return Standard_True; +} + +//======================================================================= +//function : MakeList +//purpose : +//======================================================================= +void MakeList (TopTools_ListOfShape& OffsetFaces, + const BRepAlgo_Image& myInitOffsetFace, + const TopTools_IndexedMapOfShape& myFaces) +{ + TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots()); + for ( ; itLOF.More(); itLOF.Next()) { + const TopoDS_Shape& Root = itLOF.Value(); + if (myInitOffsetFace.HasImage(Root)) { + if (!myFaces.Contains(Root)) { + OffsetFaces.Append(myInitOffsetFace.Image(Root).First()); + } + } + } } //======================================================================= -//function : MakeSolid +//function : EvalMax //purpose : //======================================================================= - -void BRepOffset_MakeOffset::MakeSolid () +void EvalMax(const TopoDS_Shape& S, + Standard_Real& Tol) { - if (myOffsetShape.IsNull()) return; + TopExp_Explorer exp; + for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { + const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); + Standard_Real TolV = BRep_Tool::Tolerance(V); + if (TolV > Tol) Tol = TolV; + } + //Patch + Tol *= 5.; +} -// Modified by skv - Mon Apr 4 18:17:27 2005 Begin -// Supporting history. - UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE); - UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE); -// Modified by skv - Mon Apr 4 18:17:27 2005 End - TopExp_Explorer exp; - BRep_Builder B; - Standard_Integer NbShell = 0; - TopoDS_Compound NC; - TopoDS_Shape S1; - B.MakeCompound (NC); +//======================================================================= +//function : TrimEdge +//purpose : Trim the edge of the largest of descendants in AsDes2d. +// Order in AsDes two vertices that have trimmed the edge. +//======================================================================= +void TrimEdge(TopoDS_Edge& NE, + const Handle(BRepAlgo_AsDes)& AsDes2d, + Handle(BRepAlgo_AsDes)& AsDes) +{ + Standard_Real aSameParTol = Precision::Confusion(); + + TopoDS_Vertex V1,V2; + Standard_Real U = 0.; + Standard_Real UMin = Precision::Infinite(); + Standard_Real UMax = -UMin; - for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) { - TopoDS_Shell Sh = TopoDS::Shell(exp.Current()); - if (myThickening && myOffset > 0.) - Sh.Reverse(); - NbShell++; - if (Sh.Closed()) { - TopoDS_Solid Sol; - B.MakeSolid (Sol); - B.Add (Sol,Sh); - Sol.Closed(Standard_True); - B.Add (NC,Sol); - if (NbShell == 1) S1 = Sol; + const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE); + // + Standard_Boolean bTrim = Standard_False; + // + if (LE.Extent() > 1) { + TopTools_ListIteratorOfListOfShape it (LE); + for (; it.More(); it.Next()) { + TopoDS_Vertex V = TopoDS::Vertex(it.Value()); + if (NE.Orientation() == TopAbs_REVERSED) + V.Reverse(); + //V.Orientation(TopAbs_INTERNAL); + if (!FindParameter(V, NE, U)) { + Standard_Real f, l; + Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); + gp_Pnt thePoint = BRep_Tool::Pnt(V); + GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); + if (Projector.NbPoints() == 0) + Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); + U = Projector.LowerDistanceParameter(); + } + if (U < UMin) { + UMin = U; V1 = V; + } + if (U > UMax) { + UMax = U; V2 = V; + } } - else { - B.Add (NC,Sh); - if (NbShell == 1) S1 = Sh; + // + if (V1.IsNull() || V2.IsNull()) { + Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge"); + } + if (!V1.IsSame(V2)) { + NE.Free( Standard_True ); + BRep_Builder B; + TopAbs_Orientation Or = NE.Orientation(); + NE.Orientation(TopAbs_FORWARD); + TopoDS_Vertex VF,VL; + TopExp::Vertices (NE,VF,VL); + B.Remove(NE,VF); + B.Remove(NE,VL); + B.Add (NE,V1.Oriented(TopAbs_FORWARD)); + B.Add (NE,V2.Oriented(TopAbs_REVERSED)); + B.Range(NE,UMin,UMax); + NE.Orientation(Or); + AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD)); + AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED)); + BRepLib::SameParameter(NE, aSameParTol, Standard_True); + // + bTrim = Standard_True; + } + } + // + if (!bTrim) { + if (!BRep_Tool::Degenerated(NE)) { + BRepAdaptor_Curve aBAC(NE); + if (!aBAC.IsClosed()) { + if (AsDes->HasAscendant(NE)) { + AsDes->Remove(NE); + } + } } } - if (NbShell == 1) myOffsetShape = S1; - else myOffsetShape = NC; } //======================================================================= -//function : SelectShells +//function : SortFaces //purpose : //======================================================================= - -void BRepOffset_MakeOffset::SelectShells () -{ - TopTools_MapOfShape FreeEdges; - TopExp_Explorer exp(myShape,TopAbs_EDGE); - //------------------------------------------------------------- - // FreeEdges all edges that can have free border in the - // parallel shell - // 1 - free borders of myShape . - //------------------------------------------------------------- - for ( ; exp.More(); exp.Next()) { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E); - if (LA.Extent() < 2) { - if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) { - FreeEdges.Add(E); +void SortFaces(const TopTools_ListOfShape& theLIm, + TopTools_ListOfShape& theLFImages, + const Standard_Boolean bKeepFirst) +{ + Standard_Integer bKeep; // 1 - keep; -1 - remove + Standard_Boolean bFlag; + TopTools_IndexedDataMapOfShapeListOfShape aDMELF; + TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp; + TopTools_MapOfShape aMV; + TopTools_ListIteratorOfListOfShape aItLF; + TopExp_Explorer aExp; + // + aLFLeft = theLIm; + // + bKeep = bKeepFirst ? 1 : -1; + for (;;) { + aLFTmp = aLFLeft; + // + aLFLeft.Clear(); + aLFKeep.Clear(); + aDMELF.Clear(); + // + // map list of images edge - faces + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); + } + // + // find images that have edge attached to only one face + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + aExp.Init(aFIm, TopAbs_EDGE); + for (bFlag = Standard_False; aExp.More(); aExp.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); + const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE); + if (aLEF.Extent() == 1) { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aE, aV1, aV2); + aMV.Add(aV1); + aMV.Add(aV2); + // + bFlag = Standard_True; + } } - } + // + if (bFlag) { + aLFKeep.Append(aFIm); + } + else { + aLFLeft.Append(aFIm); + } + } + // + // map shapes left for processing + aDMELF.Clear(); + aLFTmp = aLFLeft; + aLFLeft.Clear(); + // + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); + } + // + // find outer edges and check if they touch the first part of edges + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + aExp.Init(aFIm, TopAbs_EDGE); + for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); + const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE); + if (aLEF.Extent() == 1) { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aE, aV1, aV2); + // + bFlag = aMV.Contains(aV1) || aMV.Contains(aV2); + } + } + // + if (bFlag) { + aLFKeep.Append(aFIm); + } + else { + aLFLeft.Append(aFIm); + } + } + // + if (bKeep == 1) { + // aLFKeep should be kept + // aLFLeft left for further processing + aItLF.Initialize(aLFKeep); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + theLFImages.Append(aFIm); + } + } + // + if (aLFLeft.IsEmpty()) { + break; + } + // + bKeep *= -1; } - // myShape has free borders and there are no caps - // no unwinding 3d. - if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return; - - myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges); } //======================================================================= -//function : OffsetFacesFromShapes +//function : FindShape //purpose : //======================================================================= - -const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const +Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, + const TopoDS_Shape& theSWhere, + TopoDS_Shape& theRes) { - return myInitOffsetFace; + Standard_Boolean bFound = Standard_False; + TopAbs_ShapeEnum aType = theSWhat.ShapeType(); + TopExp_Explorer aExp(theSWhere, aType); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aS = aExp.Current(); + if (aS.IsSame(theSWhat)) { + theRes = aS; + bFound = Standard_True; + break; + } + } + return bFound; } -// Modified by skv - Tue Mar 15 16:20:43 2005 Begin - //======================================================================= -//function : GetJoinType -//purpose : Query offset join type. +//function : UpdateOrigins +//purpose : //======================================================================= - -GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const +void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + BOPAlgo_Builder& theGF) { - return myJoin; + TopTools_ListOfShape aLSTmp; + TopTools_MapOfShape aMFence; + BOPCol_ListIteratorOfListOfShape aItA; + TopTools_ListIteratorOfListOfShape aIt, aIt1; + // + const BOPCol_ListOfShape& aLSU = theGF.Arguments(); + aItA.Initialize(aLSU); + for (; aItA.More(); aItA.Next()) { + const TopoDS_Shape& aS = aItA.Value(); + // + if (!theOrigins.Contains(aS)) { + continue; + } + // + const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); + if (aLSIm.IsEmpty()) { + continue; + } + // + const TopTools_ListOfShape& aLS = theOrigins.FindFromKey(aS); + // + aIt.Initialize(aLSIm); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSIm = aIt.Value(); + // + if (!theOrigins.Contains(aSIm)) { + theOrigins.Add(aSIm, aLS); + continue; + } + // + aMFence.Clear(); + // + TopTools_ListOfShape& aLS1 = theOrigins.ChangeFromKey(aSIm); + aLSTmp.Assign(aLS1); + // + aLS1.Clear(); + aIt1.Initialize(aLSTmp); + for (; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aS1 = aIt1.Value(); + if (aMFence.Add(aS1)) { + aLS1.Append(aS1); + } + } + // + aIt1.Initialize(aLS); + for (; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aS1 = aIt1.Value(); + if (aMFence.Add(aS1)) { + aLS1.Append(aS1); + } + } + } + } } //======================================================================= -//function : OffsetEdgesFromShapes +//function : IsMicroEdge //purpose : //======================================================================= - -const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const +Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx, + Standard_Real& theFuzz) { - return myInitOffsetEdge; + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(theEdge, aV1, aV2); + Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull(); + if (bNull) { + return Standard_False; + } + // + Standard_Boolean bMicro; + Standard_Real aT1, aT2; + IntTools_ShrunkRange aSR; + // + BRepAdaptor_Curve aBAC(theEdge); + // + aT1 = BRep_Tool::Parameter(aV1, theEdge); + aT2 = BRep_Tool::Parameter(aV2, theEdge); + if (aT2 < aT1) { + Standard_Real aTmp = aT1; + aT1 = aT2; + aT2 = aTmp; + } + // + aSR.SetContext(theCtx); + aSR.SetData(theEdge, aT1, aT2, aV1, aV2); + aSR.Perform(); + bMicro = (aSR.ErrorStatus() != 0); + if (!bMicro) { + Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2; + // + aTolV1 = BRep_Tool::Tolerance(aV1); + aTolV2 = BRep_Tool::Tolerance(aV2); + // + anEps = aBAC.Resolution(aTolV1 + aTolV2); + if (anEps < 1.e-8) { + anEps = 1.e-8; + } + // + aSR.ShrunkRange(aTS1, aTS2); + bMicro = (aTS2 - aTS1) <= anEps; + } + // + if (bMicro) { + Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC); + if (aLen > theFuzz) { + theFuzz = aLen; + } + } + // + return bMicro; } -// Modified by skv - Tue Mar 15 16:20:43 2005 End - //======================================================================= -//function : ClosingFaces +//function : ComputeBiNormal //purpose : //======================================================================= - -const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const +Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF, + const TopoDS_Edge& theE, + gp_Dir& theDB) { - return myFaces; + Standard_Boolean bDone = Standard_False; + Standard_Real aT1, aT2, aTm; + // + const Handle(Geom2d_Curve)& aC2d = + BRep_Tool::CurveOnSurface(theE, theF, aT1, aT2); + if (aC2d.IsNull()) { + return bDone; + } + // + gp_Pnt2d aP2dNear; + gp_Pnt aP, aPNear; + // + const Handle(Geom_Curve)& aC3d = + BRep_Tool::Curve(theE, aT1, aT2); + // + aTm = (aT1 + aT2) * 0.5; + aP = aC3d->Value(aTm); + // + BOPTools_AlgoTools3D::PointNearEdge(theE, theF, aTm, 1.e-5, aP2dNear, aPNear); + // + gp_Vec aVB(aP, aPNear); + theDB = gp_Dir(aVB); + return !bDone; } - - //======================================================================= -//function : EncodeRegularity +//function : CheckBiNormals //purpose : //======================================================================= - -void BRepOffset_MakeOffset::EncodeRegularity () +Standard_Boolean CheckBiNormals + (const TopoDS_Face& aFIm, + const TopoDS_Face& aFOr, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + const TopTools_MapOfShape& theMFence, + Standard_Boolean& bKeep, + Standard_Boolean& bRem) { -#ifdef OCCT_DEBUG - if (ChronBuild) { - cout << " CODING OF REGULARITIES:" << endl; - Clock.Reset(); - Clock.Start(); - } -#endif - - if (myOffsetShape.IsNull()) return; - // find edges G1 in the result - TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE); - - BRep_Builder B; - TopTools_MapOfShape MS; - - for ( ; exp.More(); exp.Next()) { - TopoDS_Edge OE = TopoDS::Edge(exp.Current()); - BRepLib::BuildCurve3d(OE,myTol); - TopoDS_Edge ROE = OE; - - if ( !MS.Add(OE)) continue; - - if ( myImageOffset.IsImage(OE)) - ROE = TopoDS::Edge(myImageOffset.Root(OE)); - - const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE); - - if (LofOF.Extent() != 2) { -#ifdef OCCT_DEBUG_VERB - cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl; -#endif - continue; - } - - const TopoDS_Face& F1 = TopoDS::Face(LofOF.First()); - const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() ); - - if ( F1.IsNull() || F2.IsNull()) - continue; - - const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1); - const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2); - - TopAbs_ShapeEnum Type1 = Root1.ShapeType(); - TopAbs_ShapeEnum Type2 = Root2.ShapeType(); - - if (F1.IsSame(F2)) { - if (BRep_Tool::IsClosed(OE,F1)) { - // Temporary Debug for the Bench. - // Check with YFR. - // In mode intersection, the edges are not coded in myInitOffsetEdge - // so, manage case by case - // Note DUB; for Hidden parts, it is NECESSARY to code CN - // Analytic Surfaces. - if (myJoin == GeomAbs_Intersection) { - BRepAdaptor_Surface BS(F1,Standard_False); - GeomAbs_SurfaceType SType = BS.GetType(); - if (SType == GeomAbs_Cylinder || - SType == GeomAbs_Cone || - SType == GeomAbs_Sphere || - SType == GeomAbs_Torus ) { - B.Continuity(OE,F1,F1,GeomAbs_CN); - } - else { - // See YFR : MaJ of myInitOffsetFace - } - } - else if (myInitOffsetEdge.IsImage(ROE)) { - if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { - const TopoDS_Face& FRoot = TopoDS::Face(Root1); - const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE)); - GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot); - if (Conti == GeomAbs_CN) { - B.Continuity(OE,F1,F1,GeomAbs_CN); - } - else if ( Conti > GeomAbs_C0) { - B.Continuity(OE,F1,F1,GeomAbs_G1); - } - } - } - } + Standard_Boolean bChecked; + Standard_Real anAngle; + // + bKeep = Standard_False; + bRem = Standard_True; + bChecked = Standard_False; + // + const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); + // + TopExp_Explorer aExp(aWIm, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); + // + if (BRep_Tool::Degenerated(aEIm)) { continue; } - - - // code regularities G1 between : - // - sphere and tube : one root is a vertex, the other is an edge - // and the vertex is included in the edge - // - face and tube : one root is a face, the other an edge - // and the edge is included in the face - // - face and face : if two root faces are tangent in - // the initial shape, they will be tangent in the offset shape - // - tube and tube : if 2 edges generating tubes are - // tangents, the 2 will be tangent either. - if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) { - TopoDS_Vertex V1,V2; - TopExp::Vertices(TopoDS::Edge(Root1), V1, V2); - if ( V1.IsSame(Root2) || V2.IsSame(Root2)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - } + // + if (!theOrigins.Contains(aEIm)) { + continue; } - else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) { - TopoDS_Vertex V1,V2; - TopExp::Vertices(TopoDS::Edge(Root2), V1, V2); - if ( V1.IsSame(Root1) || V2.IsSame(Root1)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - } + // + const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm); + const TopoDS_Shape& aSOr = aLEOr.First(); + if (aSOr.ShapeType() != TopAbs_EDGE) { + bRem = Standard_False; + continue; } - else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) { - TopExp_Explorer exp2(Root1,TopAbs_EDGE); - for ( ; exp2.More(); exp2.Next()) { - if ( exp2.Current().IsSame(Root2)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - break; + // + if (aLEOr.Extent() > 1) { + TopTools_MapOfShape aME, aMV; + Standard_Integer aNbE, aNbV; + // + TopTools_ListIteratorOfListOfShape aItLS(aLEOr); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS.Value(); + aME.Add(aEOr); + // + TopExp_Explorer aExpE(aEOr, TopAbs_VERTEX); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Shape& aV = aExpE.Current(); + aMV.Add(aV); } } - } - else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) { - TopExp_Explorer exp2(Root2,TopAbs_EDGE); - for ( ; exp2.More(); exp2.Next()) { - if ( exp2.Current().IsSame(Root1)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - break; - } + // + aNbV = aMV.Extent(); + aNbE = aME.Extent(); + // + if ((aNbE > 1) && (aNbV == 2*aNbE)) { + continue; } } - else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { - // if two root faces are tangent in - // the initial shape, they will be tangent in the offset shape - TopTools_ListOfShape LE,LV; - BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1), - TopoDS::Face(Root2), - LE,LV); - if ( LE.Extent() == 1) { - const TopoDS_Edge& Ed = TopoDS::Edge(LE.First()); - if ( myAnalyse.HasAncestor(Ed)) { - const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed); - if (LI.Extent() == 1 && - LI.First().Type() == BRepOffset_Tangent) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - } - } - } + // + if (theMFence.Contains(aEIm)) { + bChecked = Standard_True; + bKeep = Standard_True; + bRem = Standard_False; + break; + } + // + const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aLEOr.First(); + // + TopoDS_Edge aEOrF; + if (!FindShape(aEOr, aFOr, aEOrF)) { + continue; } - else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) { - TopTools_ListOfShape LV; - TopExp_Explorer exp1,exp2; - for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) { - TopExp_Explorer exp2(F2,TopAbs_EDGE); - for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) { - if (exp1.Current().IsSame(exp2.Current())) { - LV.Append(exp1.Current()); - } - } - } - if ( LV.Extent() == 1) { - TopTools_ListOfShape LEdTg; - myAnalyse.TangentEdges(TopoDS::Edge(Root1), - TopoDS::Vertex(LV.First()), - LEdTg); - TopTools_ListIteratorOfListOfShape it(LEdTg); - for (; it.More(); it.Next()) { - if ( it.Value().IsSame(Root2)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - break; - } - } - } + // + // compute bi-normal for face aFIm on the edge aEIm + gp_Dir aDB1; + if (!ComputeBiNormal(aFIm, aEIm, aDB1)) { + continue; + } + // + // compute bi-normal for face aFOr on the edge aEOrF + gp_Dir aDB2; + if (!ComputeBiNormal(aFOr, aEOrF, aDB2)) { + continue; + } + // + bChecked = Standard_True; + // check coincidence of bi-normals + anAngle = aDB1.Angle(aDB2); + if (Abs(anAngle - M_PI) < Precision::Confusion()) { + bRem = bRem && Standard_True; + } + else { + bRem = Standard_False; + bKeep = Standard_True; + break; } } - -#ifdef OCCT_DEBUG - if ( ChronBuild) Clock.Show(); -#endif + // + return bChecked; } - - //======================================================================= -//function : UpDateTolerance +//function : CheckBiNormals //purpose : //======================================================================= - -static void UpdateTolerance (TopoDS_Shape& S, - const TopTools_IndexedMapOfShape& Faces) +void CheckBiNormals + (TopTools_ListOfShape& theLFImages, + const TopoDS_Face& theF, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + TopTools_ListOfShape& theLFKeep) { - BRep_Builder B; - TopTools_MapOfShape View; - TopoDS_Vertex V[2]; - - // The edges of caps are not modified. - Standard_Integer j; - for (j = 1; j <= Faces.Extent(); j++) { - const TopoDS_Shape& F = Faces(j); - TopExp_Explorer Exp; - for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) { - View.Add(Exp.Current()); + Standard_Boolean bChecked, bKeep, bRem; + Standard_Integer i, aNb; + TopTools_ListOfShape aLFKeep; + TopTools_MapOfShape aMEToKeep; + TopTools_IndexedDataMapOfShapeListOfShape aDMELF; + TopTools_ListIteratorOfListOfShape aItLF; + // + // collect outer edges + aItLF.Initialize(theLFImages); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); + } + // + aNb = aDMELF.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopTools_ListOfShape& aLF = aDMELF(i); + if (aLF.Extent() == 1) { + const TopoDS_Shape& aE = aDMELF.FindKey(i); + aMEToKeep.Add(aE); } } - - TopExp_Explorer Exp; - for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) { - TopoDS_Edge E = TopoDS::Edge(Exp.Current()); - if (View.Add(E)) { - Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E); - Standard_Real Tol = EdgeCorrector->Tolerance(); - B.UpdateEdge (E,Tol); - - // Update the vertices. - TopExp::Vertices(E,V[0],V[1]); - - for (Standard_Integer i = 0 ; i <=1 ; i++) { - if (View.Add(V[i])) { - Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape()); - TV->Tolerance(0.); - Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]); - B.UpdateVertex (V[i],VertexCorrector->Tolerance()); - // use the occasion to clean the vertices. - (TV->ChangePoints()).Clear(); + // + const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(theF).First(); + // + aItLF.Initialize(theLFImages); + for (; aItLF.More(); ) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + // + bChecked = CheckBiNormals(aFIm, aFOr, theOrigins, aMEToKeep, bKeep, bRem); + // + if (bChecked) { + if (bRem) { + theLFImages.Remove(aItLF); + } + else { + if (bKeep) { + theLFKeep.Append(aFIm); } - B.UpdateVertex(V[i],Tol); + aItLF.Next(); } } + else { + aItLF.Next(); + } + } +} + +//======================================================================= +//function : CheckNormals +//purpose : +//======================================================================= +Standard_Boolean CheckNormals(const TopoDS_Face& theFIm, + const TopoDS_Face& theFOr) +{ + + Standard_Real aUMin, aUMax, aVMin, aVMax, aU, aV, anAngle; + gp_Pnt aP; + gp_Vec aVecU, aVecV, aVNIm, aVNOr; + Standard_Boolean bIsCollinear; + // + BRepAdaptor_Surface aSFIm(theFIm), aSFOr(theFOr); + // + aUMin = aSFIm.FirstUParameter(); + aUMax = aSFIm.LastUParameter(); + aVMin = aSFIm.FirstVParameter(); + aVMax = aSFIm.LastVParameter(); + // + aU = (aUMin + aUMax) * 0.5; + if (Precision::IsInfinite(aUMin) && + Precision::IsInfinite(aUMax)) { + aU = 0.; + } + else if (Precision::IsInfinite(aUMin) && + !Precision::IsInfinite(aUMax)) { + aU = aUMax; + } + else if (!Precision::IsInfinite(aUMin) && + Precision::IsInfinite(aUMax)) { + aU = aUMin; + } + // + aV = (aVMin + aVMax) * 0.5; + if (Precision::IsInfinite(aVMin) && + Precision::IsInfinite(aVMax)) { + aV = 0.; + } + else if (Precision::IsInfinite(aVMin) && + !Precision::IsInfinite(aVMax)) { + aV = aVMax; + } + else if (!Precision::IsInfinite(aVMin) && + Precision::IsInfinite(aVMax)) { + aV = aVMin; } + // + aSFIm.D1(aU, aV, aP, aVecU, aVecV); + aVNIm = aVecU.Crossed(aVecV); + if (theFIm.Orientation() == TopAbs_REVERSED) { + aVNIm.Reverse(); + } + // + aSFOr.D1(aU, aV, aP, aVecU, aVecV); + aVNOr = aVecU.Crossed(aVecV); + if (theFOr.Orientation() == TopAbs_REVERSED) { + aVNOr.Reverse(); + } + // + anAngle = aVNIm.Angle(aVNOr); + bIsCollinear = (anAngle < Precision::Confusion()); + return bIsCollinear; } +//======================================================================= +//function : UpdateInitOffset +//purpose : Update and cleaning of myInitOffset +//======================================================================= +void UpdateInitOffset(BRepAlgo_Image& myInitOffset, + BRepAlgo_Image& myImageOffset, + const TopoDS_Shape& myOffsetShape, + const TopAbs_ShapeEnum &theShapeType) // skv +{ + BRepAlgo_Image NIOF; + const TopTools_ListOfShape& Roots = myInitOffset.Roots(); + TopTools_ListIteratorOfListOfShape it(Roots); + for (; it.More(); it.Next()) { + NIOF.SetRoot (it.Value()); + } + for (it.Initialize(Roots); it.More(); it.Next()) { + const TopoDS_Shape& SI = it.Value(); + TopTools_ListOfShape LI; + TopTools_ListOfShape L1; + myInitOffset.LastImage(SI,L1); + TopTools_ListIteratorOfListOfShape itL1(L1); + for (; itL1.More(); itL1.Next()) { + const TopoDS_Shape& O1 = itL1.Value(); + TopTools_ListOfShape L2; + myImageOffset.LastImage(O1,L2); + LI.Append(L2); + } + NIOF.Bind(SI,LI); + } +// Modified by skv - Mon Apr 4 18:17:27 2005 Begin +// Supporting history. +// NIOF.Filter(myOffsetShape,TopAbs_FACE); + NIOF.Filter(myOffsetShape, theShapeType); +// Modified by skv - Mon Apr 4 18:17:27 2005 End + myInitOffset = NIOF; +}