diff --git a/src/BRepFill/BRepFill_Pipe.cxx b/src/BRepFill/BRepFill_Pipe.cxx index c514052544..db46764d7a 100644 --- a/src/BRepFill/BRepFill_Pipe.cxx +++ b/src/BRepFill/BRepFill_Pipe.cxx @@ -102,40 +102,6 @@ static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey, return !found; } -static void ReverseModifiedEdges(TopoDS_Shape& aShape, - TopTools_MapOfShape& Emap) -{ - TopExp_Explorer Explo(aShape, TopAbs_FACE); - BRep_Builder BB; - - for (; Explo.More(); Explo.Next()) - { - TopoDS_Shape aFace = Explo.Current(); - TopoDS_Iterator itf(aFace); - for (; itf.More(); itf.Next()) - { - TopoDS_Shape aWire = itf.Value(); - TopTools_ListOfShape Ledges; - TopoDS_Iterator itw(aWire); - for (; itw.More(); itw.Next()) - Ledges.Append(itw.Value()); - - aWire.Free(Standard_True); - TopTools_ListIteratorOfListOfShape itl(Ledges); - for (; itl.More(); itl.Next()) - BB.Remove(aWire, itl.Value()); - - for (itl.Initialize(Ledges); itl.More(); itl.Next()) - { - TopoDS_Shape anEdge = itl.Value(); - if (Emap.Contains(anEdge)) - anEdge.Reverse(); - BB.Add(aWire, anEdge); - } - } - } -} - static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace, TopoDS_Edge& anEdge) { @@ -739,9 +705,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, result = MkSw.Shape(); UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap); myErrorOnSurf = MkSw.ErrorOnSurface(); - //Correct and - ReverseModifiedEdges(myFirst, myReversedEdges); - ReverseModifiedEdges(myLast, myReversedEdges); // Labeling of elements if (mySections.IsNull()) { diff --git a/src/BRepFill/BRepFill_PipeShell.cxx b/src/BRepFill/BRepFill_PipeShell.cxx index 519c6b5d0b..65ff2b28a0 100644 --- a/src/BRepFill/BRepFill_PipeShell.cxx +++ b/src/BRepFill/BRepFill_PipeShell.cxx @@ -583,28 +583,15 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) //======================================================================= void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape& Profile) { - Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX); - Standard_Boolean Trouve=Standard_False; Standard_Integer ii; for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) { - Standard_Boolean found = Standard_False; - const TopoDS_Wire& aWire = mySeq.Value(ii).Wire(); - if (isVertex) - { - TopExp_Explorer Explo(aWire, TopAbs_VERTEX); - for (; Explo.More(); Explo.Next()) - if (Profile.IsSame(Explo.Current())) - found = Standard_True; - } - else if (Profile.IsSame(aWire)) - found = Standard_True; - - if (found) - { - Trouve = Standard_True; - mySeq.Remove(ii); - } + const TopoDS_Shape& aSection = mySeq.Value(ii).OriginalShape(); + if (Profile.IsSame(aSection)) + { + Trouve = Standard_True; + mySeq.Remove(ii); + } } if (Trouve) mySection.Nullify(); @@ -914,13 +901,9 @@ const TopoDS_Shape& BRepFill_PipeShell::LastShape() const //function : Generated //purpose : //======================================================================= -// void BRepFill_PipeShell::Generated(const TopoDS_Shape& , -// TopTools_ListOfShape& ) void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape, TopTools_ListOfShape& theList) { - // throw Standard_NotImplemented("Generated:Pas Fait"); - theList.Clear(); if(myGenMap.IsBound(theShape)) { @@ -1197,9 +1180,6 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, Sec.WithCorrection()); TopoDS_Wire TmpWire = Sec.Wire(); aTrsf = Place.Transformation(); - //TopLoc_Location Loc2(Place.Transformation()), Loc1; - //Loc1 = TmpWire.Location(); - //W.Location(Loc2.Multiplied(Loc1)); //Transform the copy W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); //////////////////////////////////// @@ -1240,37 +1220,40 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) TopoDS_Iterator itw; for (indw = 1; indw <= mySeq.Length(); indw++) { - const TopoDS_Wire& aSection = mySeq(indw).Wire(); + const TopoDS_Shape& Section = mySeq(indw).OriginalShape(); + TopoDS_Wire aSection; Standard_Boolean IsPunctual = mySeq(indw).IsPunctual(); if (IsPunctual) { //for punctual sections (first or last) //we take all the wires generated along the path - TopExp_Explorer Explo(aSection, TopAbs_VERTEX); - const TopoDS_Shape& VerSection = Explo.Current(); + TopTools_ListOfShape Elist; for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++) for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++) Elist.Append(anUEdges->Value(i,j)); - myGenMap.Bind(VerSection, Elist); + myGenMap.Bind(Section, Elist); continue; } + else + aSection = TopoDS::Wire(Section); //Take the real index of section on the path Standard_Integer IndOfW = myIndOfSec(indw); const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW)); BRepTools_WireExplorer wexp_sec(aSection); for (inde = 1; wexp_sec.More(); wexp_sec.Next()) { - const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current()); + const TopoDS_Edge& anOriginalEdge = TopoDS::Edge(wexp_sec.Current()); + TopoDS_Edge anEdge = TopoDS::Edge(mySeq(indw).ModifiedShape(anOriginalEdge)); if (BRep_Tool::Degenerated(anEdge)) continue; TopoDS_Shell aShell; BB.MakeShell(aShell); TopoDS_Vertex aVertex [2]; - TopExp::Vertices(anEdge, aVertex[0], aVertex[1]); + TopExp::Vertices(anOriginalEdge, aVertex[0], aVertex[1]); Standard_Integer SignOfAnEdge = - (anEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; + (anOriginalEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; //For each non-degenerated inde-th edge of //we find inde-th edge in @@ -1422,7 +1405,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) TopTools_ListOfShape ListShell; ListShell.Append(aShell); - myGenMap.Bind(anEdge, ListShell); + myGenMap.Bind(anOriginalEdge, ListShell); //////////////////////// inde++; diff --git a/src/BRepFill/BRepFill_Section.cxx b/src/BRepFill/BRepFill_Section.cxx index b65b5f85c1..09e5d6f8a7 100644 --- a/src/BRepFill/BRepFill_Section.cxx +++ b/src/BRepFill/BRepFill_Section.cxx @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include BRepFill_Section::BRepFill_Section() :islaw(0), ispunctual(0), @@ -41,12 +44,19 @@ BRepFill_Section::BRepFill_Section(const TopoDS_Shape& Profile, contact(WithContact), correction(WithCorrection) { - if (Profile.ShapeType() == TopAbs_WIRE) - wire = TopoDS::Wire(Profile); - else if (Profile.ShapeType() == TopAbs_VERTEX) + myOriginalShape = Profile; + + ShapeUpgrade_RemoveLocations RemLoc; + RemLoc.SetRemoveLevel(TopAbs_COMPOUND); + RemLoc.Remove(Profile); + TopoDS_Shape aProfile = RemLoc.GetResult(); + + if (aProfile.ShapeType() == TopAbs_WIRE) + wire = TopoDS::Wire(aProfile); + else if (aProfile.ShapeType() == TopAbs_VERTEX) { ispunctual = Standard_True; - TopoDS_Vertex aVertex = TopoDS::Vertex(Profile); + TopoDS_Vertex aVertex = TopoDS::Vertex(aProfile); BRep_Builder BB; TopoDS_Edge DegEdge; @@ -67,3 +77,58 @@ void BRepFill_Section::Set(const Standard_Boolean IsLaw) { islaw = IsLaw; } + +TopoDS_Shape BRepFill_Section::ModifiedShape(const TopoDS_Shape& theShape) const +{ + TopoDS_Shape aModifiedShape; + + switch (theShape.ShapeType()) + { + case TopAbs_WIRE: + if (theShape.IsSame(myOriginalShape)) + aModifiedShape = wire; + break; + case TopAbs_EDGE: + { + TopoDS_Iterator itor(myOriginalShape); + TopoDS_Iterator itw(wire); + for (; itor.More(); itor.Next(),itw.Next()) + { + const TopoDS_Shape& anOriginalEdge = itor.Value(); + const TopoDS_Shape& anEdge = itw.Value(); + if (anOriginalEdge.IsSame(theShape)) + { + aModifiedShape = anEdge; + break; + } + } + } + break; + case TopAbs_VERTEX: + if (theShape.IsSame(myOriginalShape)) + { + TopExp_Explorer Explo(wire, TopAbs_VERTEX); + aModifiedShape = Explo.Current(); + } + else + { + TopExp_Explorer ExpOrig(myOriginalShape, TopAbs_VERTEX); + TopExp_Explorer ExpWire(wire, TopAbs_VERTEX); + for (; ExpOrig.More(); ExpOrig.Next(),ExpWire.Next()) + { + const TopoDS_Shape& anOriginalVertex = ExpOrig.Current(); + const TopoDS_Shape& aVertex = ExpWire.Current(); + if (anOriginalVertex.IsSame(theShape)) + { + aModifiedShape = aVertex; + break; + } + } + } + break; + default: + break; + } + + return aModifiedShape; +} diff --git a/src/BRepFill/BRepFill_Section.hxx b/src/BRepFill/BRepFill_Section.hxx index ede9091f05..10acf1decc 100644 --- a/src/BRepFill/BRepFill_Section.hxx +++ b/src/BRepFill/BRepFill_Section.hxx @@ -43,10 +43,14 @@ public: Standard_EXPORT void Set (const Standard_Boolean IsLaw); + const TopoDS_Shape& OriginalShape() const; + const TopoDS_Wire& Wire() const; const TopoDS_Vertex& Vertex() const; + Standard_EXPORT TopoDS_Shape ModifiedShape(const TopoDS_Shape& theShape) const; + Standard_Boolean IsLaw() const; Standard_Boolean IsPunctual() const; @@ -68,6 +72,7 @@ private: + TopoDS_Shape myOriginalShape; TopoDS_Wire wire; TopoDS_Vertex vertex; Standard_Boolean islaw; diff --git a/src/BRepFill/BRepFill_Section.lxx b/src/BRepFill/BRepFill_Section.lxx index 5b80bc996e..c96eaec01f 100644 --- a/src/BRepFill/BRepFill_Section.lxx +++ b/src/BRepFill/BRepFill_Section.lxx @@ -14,6 +14,11 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +inline const TopoDS_Shape& BRepFill_Section::OriginalShape() const +{ + return myOriginalShape; +} + inline const TopoDS_Wire& BRepFill_Section::Wire() const { return wire; diff --git a/src/BRepFill/BRepFill_Sweep.cxx b/src/BRepFill/BRepFill_Sweep.cxx index 9e35334bbb..8b628e1518 100644 --- a/src/BRepFill/BRepFill_Sweep.cxx +++ b/src/BRepFill/BRepFill_Sweep.cxx @@ -366,6 +366,56 @@ static Standard_Boolean SameParameter(TopoDS_Edge& E, return Standard_True; } +static void CorrectSameParameter(TopoDS_Edge& theEdge, + const TopoDS_Face& theFace1, + const TopoDS_Face& theFace2) +{ + if (BRep_Tool::Degenerated(theEdge)) + return; + + Standard_Real fpar, lpar; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar); + + Standard_Boolean PCurveExists [2] = {Standard_False, Standard_False}; + BRepAdaptor_Curve BAcurve [2]; + + if (!theFace1.IsNull()) + { + PCurveExists[0] = Standard_True; + BAcurve[0].Initialize(theEdge, theFace1); + } + if (!theFace1.IsNull() && + theFace1.IsSame(theFace2)) + theEdge.Reverse(); + if (!theFace2.IsNull()) + { + PCurveExists[1] = Standard_True; + BAcurve[1].Initialize(theEdge, theFace2); + } + + Standard_Real MaxSqDist = 0.; + const Standard_Integer NCONTROL = 23; + Standard_Real delta = (lpar - fpar)/NCONTROL; + + for (Standard_Integer i = 0; i <= NCONTROL; i++) + { + Standard_Real aParam = fpar + i*delta; + gp_Pnt aPnt = aCurve->Value(aParam); + for (Standard_Integer j = 0; j < 2; j++) + if (PCurveExists[j]) + { + gp_Pnt aPntFromFace = BAcurve[j].Value(aParam); + Standard_Real aSqDist = aPnt.SquareDistance(aPntFromFace); + if (aSqDist > MaxSqDist) + MaxSqDist = aSqDist; + } + } + + Standard_Real aTol = sqrt(MaxSqDist); + BRep_Builder BB; + BB.UpdateEdge(theEdge, aTol); +} + //======================================================================= //Objet : Orientate an edge of natural restriction // : General @@ -1661,6 +1711,60 @@ static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S, return B; } +static void ReverseEdgeInFirstOrLastWire(TopoDS_Shape& theWire, + const TopoDS_Shape& theEdge) +{ + TopoDS_Shape EdgeToReverse; + TopoDS_Iterator itw(theWire); + + for (; itw.More(); itw.Next()) + { + const TopoDS_Shape& anEdge = itw.Value(); + if (anEdge.IsSame(theEdge)) + { + EdgeToReverse = anEdge; + break; + } + } + + if (!EdgeToReverse.IsNull()) + { + BRep_Builder BB; + theWire.Free(Standard_True); + BB.Remove(theWire, EdgeToReverse); + EdgeToReverse.Reverse(); + BB.Add(theWire, EdgeToReverse); + } +} + +static void ReverseModifiedEdges(TopoDS_Wire& theWire, + const TopTools_MapOfShape& theEmap) +{ + if (theEmap.IsEmpty()) + return; + + TopoDS_Iterator itw(theWire); + BRep_Builder BB; + + TopTools_ListOfShape Ledges; + for (; itw.More(); itw.Next()) + Ledges.Append(itw.Value()); + + theWire.Free(Standard_True); + TopTools_ListIteratorOfListOfShape itl(Ledges); + for (; itl.More(); itl.Next()) + BB.Remove(theWire, itl.Value()); + + for (itl.Initialize(Ledges); itl.More(); itl.Next()) + { + TopoDS_Shape anEdge = itl.Value(); + if (theEmap.Contains(anEdge)) + anEdge.Reverse(); + BB.Add(theWire, anEdge); + } +} + + //======================================================================= //function : Constructeur //purpose : @@ -2064,6 +2168,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Standard_Boolean exuv, singu, singv; Handle(Geom_Surface) S; + //Correct and : reverse modified edges + ReverseModifiedEdges(FirstShape, ReversedEdges); + ReverseModifiedEdges(LastShape, ReversedEdges); + // (2.0) return preexisting Edges and vertices TopoDS_Edge E; TColStd_Array1OfBoolean IsBuilt(1, NbLaw); @@ -2293,7 +2401,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, // ---------- Creation of Vertex and edge ------------ - ReversedEdges.Clear(); for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) { for (isec=1; isec <=NbLaw; isec++) { @@ -2496,7 +2603,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, TopoDS::Edge(VEdge(isec, ipath)), ReversedEdges); if (ReversedEdges.Contains(VEdge(isec, ipath))) + { + ReverseEdgeInFirstOrLastWire(FirstShape, VEdge(isec, ipath)); StartEdges(isec).Reverse(); + } } } @@ -2536,6 +2646,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, RebuildTopOrBottomEdge(aNewLastEdge, TopoDS::Edge(VEdge(isec, ipath+1)), ReversedEdges); + if (ReversedEdges.Contains(VEdge(isec, ipath+1))) + ReverseEdgeInFirstOrLastWire(LastShape, VEdge(isec, ipath+1)); } } } @@ -2877,6 +2989,30 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges, } } + //Ensure Same Parameter on U-edges + for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) + { + if (mySec->IsUClosed() && ii == myUEdges->UpperRow()) + continue; + for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) + { + TopoDS_Edge anEdge = TopoDS::Edge(myUEdges->Value(ii, jj)); + if (anEdge.IsNull()) + continue; + TopoDS_Face Face1, Face2; + Standard_Integer i1 = ii-1, i2 = ii; + if (i1 == 0 && mySec->IsUClosed()) + i1 = myFaces->UpperRow(); + if (i2 > myFaces->UpperRow()) + i2 = 0; + if (i1 != 0) + Face1 = TopoDS::Face(myFaces->Value(i1, jj)); + if (i2 != 0) + Face2 = TopoDS::Face(myFaces->Value(i2, jj)); + CorrectSameParameter(anEdge, Face1, Face2); + } + } + for (ii = 1; ii <= NbLaw; ii++) for (jj = 1; jj <= NbPath; jj++) { @@ -3083,7 +3219,7 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const } } - BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF); + BRepFill_TrimShellCorner aTrim(aFaces, Transition, AxeOfBisPlane); aTrim.AddBounds(Bounds); aTrim.AddUEdges(aUEdges); aTrim.Perform(); diff --git a/src/BRepFill/BRepFill_TrimShellCorner.cxx b/src/BRepFill/BRepFill_TrimShellCorner.cxx index 9d3e925ca6..0083bf8e23 100644 --- a/src/BRepFill/BRepFill_TrimShellCorner.cxx +++ b/src/BRepFill/BRepFill_TrimShellCorner.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,23 @@ #include #include #include +#include + +static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex, + TopoDS_Compound& theComp, + const gp_Ax1& theAxis); + +static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1, + const TopoDS_Vertex& theVertex2, + const gp_Ax1& theAxis, + TopoDS_Compound& theComp, + TopTools_ListOfShape& theElist); + +static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge, + const TopoDS_Edge& theLastEdge, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Vertex& theCommonVertex); static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS, const Standard_Integer theEIndex1, @@ -71,24 +89,6 @@ static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS, Standard_Real& theParamOnE1, Standard_Real& theParamOnE2); -static Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - TopTools_DataMapOfShapeListOfShape& theHistMap); - -static Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - const Standard_Integer theSSInterfIndex, - const gp_Ax2& AxeOfBisPlane, - TopTools_DataMapOfShapeListOfShape& theHistMap); - static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges, const BOPDS_PDS& theDS, TopTools_DataMapOfShapeListOfShape& theHistMap); @@ -186,55 +186,27 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir gp_Pln& thePlane, Standard_Boolean& IsSingular); -static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, - const gp_Ax2& bis, - TopoDS_Shape& resWire, - gp_Pln& resPlane, - Standard_Boolean& IsSingular); +static void UpdateSectionEdge(TopoDS_Edge& theEdge, + const TopoDS_Vertex& theConstVertex, + TopoDS_Vertex& theVertex, + const Standard_Real theParam); + // =========================================================================================== // function: Constructor // purpose: // =========================================================================================== BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, - const gp_Ax2& theAxeOfBisPlane, - const TopoDS_Face& theSecPlane) : -myAxeOfBisPlane(theAxeOfBisPlane), -myDone(Standard_False), -myHasSection(Standard_False) + const BRepFill_TransitionStyle theTransition, + const gp_Ax2& theAxeOfBisPlane) : + myTransition(theTransition), + myAxeOfBisPlane(theAxeOfBisPlane), + myDone(Standard_False), + myHasSection(Standard_False) { myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), theFaces->LowerCol(), theFaces->UpperCol()); myFaces->ChangeArray2() = theFaces->Array2(); - mySecPln = theSecPlane; -} - -// =========================================================================================== -// function: Constructor -// purpose: -// =========================================================================================== -BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, - const gp_Ax2& theAxeOfBisPlane, - const TopoDS_Wire& theSpine, - const TopoDS_Face& theSecPlane): -myAxeOfBisPlane(theAxeOfBisPlane), -myDone(Standard_False), -myHasSection(Standard_False) -{ - myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), - theFaces->LowerCol(), theFaces->UpperCol()); - myFaces->ChangeArray2() = theFaces->Array2(); - mySpine = theSpine; - mySecPln = theSecPlane; -} - -// =========================================================================================== -// function: SetSpine -// purpose: -// =========================================================================================== -void BRepFill_TrimShellCorner::SetSpine(const TopoDS_Wire& theSpine) -{ - mySpine = theSpine; } // =========================================================================================== @@ -351,14 +323,13 @@ void BRepFill_TrimShellCorner::Perform() } if(!bhassec) { - if(!MakeFacesNonSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, myHistMap)) { + if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) { myHistMap.Clear(); return; } } else { - if(!MakeFacesSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, - i, myAxeOfBisPlane, myHistMap)) { + if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) { myHistMap.Clear(); return; } @@ -403,23 +374,21 @@ void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape, } // ---------------------------------------------------------------------------------------------------- -// static function: MakeFacesNonSec -// purpose: +// function: MakeFacesNonSec +// purpose: Updates by new faces in the case when old faces do not intersect // ---------------------------------------------------------------------------------------------------- -Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - TopTools_DataMapOfShapeListOfShape& theHistMap) +Standard_Boolean +BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2) { Standard_Boolean bHasNewEdge = Standard_False; TopoDS_Edge aNewEdge; BRep_Builder aBB; - const TopoDS_Shape& aE1 = theBounds->Value(theIndex, 1); - const TopoDS_Shape& aE2 = theBounds->Value(theIndex, 2); + const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1); + const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2); // search common vertex between bounds. begin TopoDS_Vertex aCommonVertex; @@ -439,20 +408,20 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI Standard_Integer ueit = 0, eindex = 0; for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) { - const TopoDS_Shape& aShape1 = theUEdges->Value(eindex, theUEdges->LowerCol()); - const TopoDS_Shape& aShape2 = theUEdges->Value(eindex, theUEdges->UpperCol()); + const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol()); + const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol()); TopoDS_Edge aUE1 = TopoDS::Edge(aShape1); TopoDS_Edge aUE2 = TopoDS::Edge(aShape2); - if(theHistMap.IsBound(aShape1)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aShape1); + if (myHistMap.IsBound(aShape1)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aShape1); if(!lst.IsEmpty()) aUE1 = TopoDS::Edge(lst.First()); } - if(theHistMap.IsBound(aShape2)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aShape2); + if (myHistMap.IsBound(aShape2)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aShape2); if(!lst.IsEmpty()) aUE2 = TopoDS::Edge(lst.First()); @@ -499,11 +468,11 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI aBB.MakeCompound(aComp); for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) { - const TopoDS_Shape& aShape = theUEdges->Value(eindex, theUEdges->LowerCol() + fit - 1); + const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1); TopoDS_Shape aUE = aShape; - if(theHistMap.IsBound(aShape)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aShape); + if(myHistMap.IsBound(aShape)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aShape); if(!lst.IsEmpty()) aUE = TopoDS::Edge(lst.First()); @@ -638,7 +607,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI aNewFace.Orientation(aFaceOri); TopTools_ListOfShape atmpList; atmpList.Append(aNewFace); - theHistMap.Bind(aFace, atmpList); + myHistMap.Bind(aFace, atmpList); anExpE.Init(aFace, TopAbs_EDGE); @@ -648,7 +617,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current())) continue; - if(theHistMap.IsBound(anExpE.Current())) + if (myHistMap.IsBound(anExpE.Current())) continue; TopTools_ListOfShape aListOfNewEdge; TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE); @@ -656,7 +625,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI for(; anExpE2.More(); anExpE2.Next()) { aListOfNewEdge.Append(anExpE2.Current()); } - theHistMap.Bind(anExpE.Current(), aListOfNewEdge); + myHistMap.Bind(anExpE.Current(), aListOfNewEdge); } } @@ -664,18 +633,15 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI } // ---------------------------------------------------------------------------------------------------- -// static function: MakeFacesSec -// purpose: +// function: MakeFacesSec +// purpose: Updates by new faces in the case when old faces intersect each other // ---------------------------------------------------------------------------------------------------- -Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - const Standard_Integer theSSInterfIndex, - const gp_Ax2& AxeOfBisPlane, - TopTools_DataMapOfShapeListOfShape& theHistMap) +Standard_Boolean +BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2, + const Standard_Integer theSSInterfIndex) { const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF(); const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex); @@ -687,10 +653,30 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges)) return Standard_False; + //Extract vertices on the intersection of correspondent U-edges + const TopoDS_Shape& LeftE1 = myUEdges->Value(theIndex, 1); + const TopoDS_Shape& LeftE2 = myUEdges->Value(theIndex, 2); + const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1); + const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2); + + Standard_Integer IndexOfLeftE1 = theDS->Index(LeftE1); + Standard_Integer IndexOfLeftE2 = theDS->Index(LeftE2); + Standard_Integer IndexOfRightE1 = theDS->Index(RightE1); + Standard_Integer IndexOfRightE2 = theDS->Index(RightE2); + + TopoDS_Vertex FirstVertex, LastVertex; + Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2; + FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2, + FirstVertex, ParamOnLeftE1, ParamOnLeftE2); + FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2, + LastVertex, ParamOnRightE1, ParamOnRightE2); + TopoDS_Shape SecWire; gp_Pln SecPlane; Standard_Boolean IsSingular; - Standard_Boolean WireFound = ChooseSection( aSecEdges, AxeOfBisPlane, SecWire, SecPlane, IsSingular ); + Standard_Boolean WireFound = ChooseSection(aSecEdges, + FirstVertex, LastVertex, + SecWire, SecPlane, IsSingular ); if(WireFound) { //aSecEdges = SecWire; @@ -715,19 +701,19 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde TopAbs_Orientation aFaceOri = aFace.Orientation(); TopoDS_Face aFaceF = aFace; aFaceF.Orientation(TopAbs_FORWARD); - TopoDS_Edge aBoundEdge = TopoDS::Edge(theBounds->Value(theIndex, theBounds->LowerCol() +fit)); + TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit)); Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge); TopoDS_Edge aUE1; TopoDS_Edge aUE2; - if(!GetUEdges(theIndex, fit, theUEdges, aBoundEdge, aFaceF, aUE1, aUE2)) + if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2)) return Standard_False; TopoDS_Edge aUE1old = aUE1; TopoDS_Edge aUE2old = aUE2; - if(theHistMap.IsBound(aUE1)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aUE1); + if (myHistMap.IsBound(aUE1)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aUE1); if(!lst.IsEmpty()) { const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation()); @@ -738,8 +724,8 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde } } - if(theHistMap.IsBound(aUE2)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aUE2); + if (myHistMap.IsBound(aUE2)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aUE2); if(!lst.IsEmpty()) { const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation()); @@ -757,12 +743,12 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde Standard_Boolean isPave1OnUEdge = Standard_True; if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex, - theDS, theHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) { + theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) { TopTools_ListOfShape aSecondListOfEdges; Standard_Boolean bisSectionFound = Standard_False; if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge, - aBoundEdgeIndex, theDS, theHistMap, aSecondListOfEdges, bisSectionFound)) { + aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) { return Standard_False; } @@ -792,7 +778,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde aNewFace.Orientation(aFaceOri); TopTools_ListOfShape atmpList; atmpList.Append(aNewFace); - theHistMap.Bind(aFace, atmpList); + myHistMap.Bind(aFace, atmpList); TopExp_Explorer anExpE(aFace, TopAbs_EDGE); @@ -802,7 +788,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current())) continue; - if(theHistMap.IsBound(anExpE.Current())) + if (myHistMap.IsBound(anExpE.Current())) continue; TopTools_ListOfShape aListOfNewEdge; TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE); @@ -810,12 +796,240 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde for(; anExpE2.More(); anExpE2.Next()) { aListOfNewEdge.Append(anExpE2.Current()); } - theHistMap.Bind(anExpE.Current(), aListOfNewEdge); + myHistMap.Bind(anExpE.Current(), aListOfNewEdge); } } return Standard_True; } +//======================================================================= +//function : ChooseSection +//purpose : +//======================================================================= +Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Shape& resWire, + gp_Pln& resPlane, + Standard_Boolean& IsSingular) +{ + IsSingular = Standard_False; + + Standard_Integer ind, i, j; + BRep_Builder BB; + + if (myTransition == BRepFill_Right && + !theFirstVertex.IsNull() && + !theLastVertex.IsNull()) //the case where section wire goes from + //its known first vertex to its known last vertex + { + TopoDS_Wire NewWire; + BB.MakeWire(NewWire); + + TopoDS_Compound OldComp; + BB.MakeCompound( OldComp ); + TopoDS_Iterator iter( Comp ); + for (; iter.More(); iter.Next()) + BB.Add( OldComp, iter.Value() ); + + TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex, + OldComp, + myAxeOfBisPlane.Axis()); + iter.Initialize(OldComp); + if (!iter.More()) + { + iter.Initialize(Comp); + BB.Add( OldComp, iter.Value() ); + } + TopoDS_Edge LastEdge = FindEdgeCloseToBisectorPlane(theLastVertex, + OldComp, + myAxeOfBisPlane.Axis()); + + BB.Add(NewWire, FirstEdge); + + if (!FirstEdge.IsSame(LastEdge)) + { + TopoDS_Vertex aCommonVertex; + Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge, + theFirstVertex, theLastVertex, + aCommonVertex); + if (CommonVertexExists) + BB.Add(NewWire, LastEdge); + else + { + TopoDS_Vertex Vertex1, Vertex2, V1, V2; + TopExp::Vertices(FirstEdge, V1, V2); + Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1; + TopExp::Vertices(LastEdge, V1, V2); + Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1; + + TopTools_ListOfShape MiddleEdges; + if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges)) + { + TopTools_ListIteratorOfListOfShape itl(MiddleEdges); + for (; itl.More(); itl.Next()) + BB.Add(NewWire, itl.Value()); + BB.Add(NewWire, LastEdge); + } + else + { + //trim and in the points of extrema + //these points become new vertex with centre between them + BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge); + if (Extrema.IsDone() && Extrema.NbExt() > 0) + { + Standard_Integer imin = 1; + for (i = 2; i <= Extrema.NbExt(); i++) + if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin)) + imin = i; + + Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin)); + Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin); + Standard_Real ParamOnLastEdge = Extrema.ParameterOnE2(imin); + gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin); + gp_Pnt PointOnLastEdge = Extrema.PointOnE2(imin); + gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2); + aCommonVertex = BRepLib_MakeVertex(MidPnt); + BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2); + + UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge); + UpdateSectionEdge(LastEdge, theLastVertex, aCommonVertex, ParamOnLastEdge); + + BB.Add(NewWire, LastEdge); + } + } + } + } + + resWire = NewWire; + resPlane = gp_Pln(myAxeOfBisPlane); + return Standard_True; + } + + //General case: try to find continuous section closest to bisector plane + TopoDS_Compound OldComp; + BRep_Builder B; + B.MakeCompound( OldComp ); + TopoDS_Iterator iter( Comp ); + for (; iter.More(); iter.Next()) + B.Add( OldComp, iter.Value() ); + + Standard_Boolean anError = Standard_False; + //TopoDS_Wire NewWire [2]; + TopTools_SequenceOfShape Wseq; + for (;;) + { + TopExp_Explorer explo( OldComp, TopAbs_EDGE ); + if (!explo.More()) + break; + TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() ); + TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge ); + B.Remove( OldComp, FirstEdge ); + if (NewWire.Closed()) + { + Wseq.Append(NewWire); + continue; + } + + for (;;) + { + TopoDS_Vertex Extremity [2]; + TopExp::Vertices( NewWire, Extremity[0], Extremity[1] ); + if (Extremity[0].IsNull() || Extremity[1].IsNull()) + { + anError = Standard_True; + break; + } + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); + TopTools_ListOfShape Vedges [2]; + for (j = 0; j < 2; j++) + if (VEmap.Contains( Extremity[j] )) + Vedges[j] = VEmap.FindFromKey( Extremity[j] ); + if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty()) + //no more edges in OldComp to continue NewWire + break; + Standard_Boolean Modified = Standard_False; + for (j = 0; j < 2; j++) + { + if (Vedges[j].Extent() == 1) + { + const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() ); + NewWire = BRepLib_MakeWire( NewWire, anEdge ); + B.Remove( OldComp, anEdge ); + Modified = Standard_True; + } + } + if (!Modified) //only multiple connections + { + ind = (Vedges[0].IsEmpty())? 1 : 0; + TopTools_SequenceOfShape Edges; + TopTools_ListIteratorOfListOfShape itl( Vedges[ind] ); + for (; itl.More(); itl.Next()) + Edges.Append( itl.Value() ); + Standard_Integer theind=0; + Standard_Real MinDeviation = RealLast(); + for (j = 1; j <= Edges.Length(); j++) + { + TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) ); + gp_Pln aPlane; + Standard_Boolean issing; + Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing ); + if (Deviation < MinDeviation) + { + MinDeviation = Deviation; + theind = j; + } + } + NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) ); + B.Remove( OldComp, Edges(theind) ); + } + if (NewWire.Closed()) + break; + } + Wseq.Append(NewWire); + if (anError) + break; + } + + Standard_Real MinAngle = RealLast(); + TopExp_Explorer Explo( OldComp, TopAbs_EDGE ); + if (!anError && !Explo.More()) //wires are built successfully and compound is empty + { + if (Wseq.Length() == 1) //only one wire => it becomes result + { + resWire = Wseq.First(); + ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular ); + return Standard_True; + } + else //we must choose the wire which average plane is closest to bisector plane + { //(check angle between axes) + for (i = 1; i <= Wseq.Length(); i++) + { + TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) ); + gp_Pln aPln; + Standard_Boolean issing; + ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing ); + if (issing) + continue; + + Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() ); + if (Angle > M_PI/2) + Angle = M_PI - Angle; + + if (Angle < MinAngle) + { + MinAngle = Angle; + resWire = aWire; + resPlane = aPln; + } + } + return Standard_True; + } + } + return Standard_False; +} + // ------------------------------------------------------------------------------------------ // static function: SplitUEdges @@ -966,13 +1180,15 @@ Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS, continue; IntTools_CommonPrt aCP = aEE.CommonPart(); - if(aCP.Type() == TopAbs_VERTEX) { + if(aCP.Type() == TopAbs_VERTEX) + { theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew()); - if (theEIndex1 == aEE.Index1()) { + + if (theEIndex1 == aEE.Index1()) IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2); - } else { + else IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1); - } + // bvertexfound = Standard_True; break; @@ -2004,147 +2220,182 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir return MaxDeviation; } -//======================================================================= -//function : ChooseSection -//purpose : -//======================================================================= -static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, - const gp_Ax2& bis, - TopoDS_Shape& resWire, - gp_Pln& resPlane, - Standard_Boolean& IsSingular) + +static void UpdateSectionEdge(TopoDS_Edge& theEdge, + const TopoDS_Vertex& theConstVertex, + TopoDS_Vertex& theVertex, + const Standard_Real theParam) { - IsSingular = Standard_False; - Standard_Real TolDeviation = 0.01; //, TolConf = 1.e-4, TolAng = 1.e-5; + TopoDS_Edge F_Edge = theEdge; + F_Edge.Orientation(TopAbs_FORWARD); + + TopAbs_Orientation OrOfVertex; + TopoDS_Vertex V1, V2, AnotherVertex; + TopExp::Vertices(F_Edge, V1, V2); + if (theConstVertex.IsSame(V1)) + { + //OrOfConst = TopAbs_FORWARD; + OrOfVertex = TopAbs_REVERSED; + AnotherVertex = V2; + } + else + { + //OrOfConst = TopAbs_REVERSED; + OrOfVertex = TopAbs_FORWARD; + AnotherVertex = V1; + } -// Standard_Integer N = 100; - Standard_Integer ind, i, j; + BRep_Builder BB; + Standard_Real fpar, lpar; + BRep_Tool::Range(F_Edge, fpar, lpar); + if (OrOfVertex == TopAbs_FORWARD) + fpar = theParam; + else + lpar = theParam; + BB.Range(F_Edge, fpar, lpar); - //Simplest case - TopoDS_Compound OldComp; - BRep_Builder B; - B.MakeCompound( OldComp ); - TopoDS_Iterator iter( Comp ); - for (; iter.More(); iter.Next()) - B.Add( OldComp, iter.Value() ); - - Standard_Boolean anError = Standard_False; - //TopoDS_Wire NewWire [2]; - TopTools_SequenceOfShape Wseq; - for (;;) - { - TopExp_Explorer explo( OldComp, TopAbs_EDGE ); - if (!explo.More()) - break; - TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() ); - TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge ); - B.Remove( OldComp, FirstEdge ); - if (NewWire.Closed()) - { - Wseq.Append(NewWire); - continue; - } - - for (;;) - { - TopoDS_Vertex Extremity [2]; - TopExp::Vertices( NewWire, Extremity[0], Extremity[1] ); - if (Extremity[0].IsNull() || Extremity[1].IsNull()) - { - anError = Standard_True; - break; - } - TopTools_IndexedDataMapOfShapeListOfShape VEmap; - TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); - TopTools_ListOfShape Vedges [2]; - for (j = 0; j < 2; j++) - if (VEmap.Contains( Extremity[j] )) - Vedges[j] = VEmap.FindFromKey( Extremity[j] ); - if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty()) - //no more edges in OldComp to continue NewWire - break; - Standard_Boolean Modified = Standard_False; - for (j = 0; j < 2; j++) - { - if (Vedges[j].Extent() == 1) - { - const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() ); - NewWire = BRepLib_MakeWire( NewWire, anEdge ); - B.Remove( OldComp, anEdge ); - Modified = Standard_True; - } - } - if (!Modified) //only multiple connections - { - ind = (Vedges[0].IsEmpty())? 1 : 0; - TopTools_SequenceOfShape Edges; - TopTools_ListIteratorOfListOfShape itl( Vedges[ind] ); - for (; itl.More(); itl.Next()) - Edges.Append( itl.Value() ); - Standard_Integer theind=0; - Standard_Real MinDeviation = RealLast(); - for (j = 1; j <= Edges.Length(); j++) - { - TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) ); - gp_Pln aPlane; - Standard_Boolean issing; - Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing ); - if (Deviation < MinDeviation) - { - MinDeviation = Deviation; - theind = j; - } - } - NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) ); - B.Remove( OldComp, Edges(theind) ); - } - if (NewWire.Closed()) - break; - } - Wseq.Append(NewWire); - if (anError) - break; - } - - Standard_Real Deviation=0.; - Standard_Real MinAngle = RealLast(); - TopExp_Explorer Explo( OldComp, TopAbs_EDGE ); - if (!anError && !Explo.More()) - { - if (Wseq.Length() == 1) - { - resWire = Wseq.First(); - Deviation = ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular ); - return Standard_True; - } - else - { - for (i = 1; i <= Wseq.Length(); i++) - { - TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) ); - gp_Pln aPln; - Standard_Boolean issing; - Standard_Real aDeviation = - ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing ); - if (issing) - continue; - - Standard_Real Angle = aPln.Axis().Angle( bis.Axis() ); - if (Angle > M_PI/2) - Angle = M_PI - Angle; - - if (Angle < MinAngle) - { - MinAngle = Angle; - resWire = aWire; - resPlane = aPln; - Deviation = aDeviation; - } - } - if (Deviation <= TolDeviation) - return Standard_True; - } - } - return Standard_False; - //end of simplest case + F_Edge.Free(Standard_True); + BB.Remove(F_Edge, AnotherVertex); + theVertex.Orientation(OrOfVertex); + BB.Add(F_Edge, theVertex); +} + +//Finds the edge connected to in the compound +//that is closest to bisector plane angularly. +//Removes found edge from +// is the axis of bisector plane +static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex, + TopoDS_Compound& theComp, + const gp_Ax1& theAxis) +{ + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); + + TopoDS_Edge MinEdge; + if (!VEmap.Contains(theVertex)) + return MinEdge; + + BRep_Builder BB; + + const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex); + if (Edges.Extent() == 1) + MinEdge = TopoDS::Edge(Edges.First()); + else + { + TopTools_ListIteratorOfListOfShape itl(Edges); + Standard_Real MinAngle = RealLast(); + for (; itl.More(); itl.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value()); + TopoDS_Wire aWire; + BB.MakeWire(aWire); + BB.Add(aWire, anEdge); + gp_Pln aPln; + Standard_Boolean issing; + ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing ); + Standard_Real anAngle; + if (issing) //edge is a segment of line + { + // is angle between and its projection on bisector plane + BRepAdaptor_Curve BAcurve(anEdge); + gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter()); + gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter()); + gp_Vec EdgeVec(FirstPnt, LastPnt); + gp_Ax1 EdgeAxis(FirstPnt, EdgeVec); + anAngle = EdgeAxis.Direction().Angle(theAxis.Direction()); + if (anAngle > M_PI/2) + anAngle = M_PI - anAngle; + anAngle = M_PI/2 - anAngle; + } + else + { + anAngle = aPln.Axis().Angle( theAxis ); + if (anAngle > M_PI/2) + anAngle = M_PI - anAngle; + } + + if (anAngle < MinAngle) + { + MinAngle = anAngle; + MinEdge = anEdge; + } + } + } //else (more than one edge) + + BB.Remove(theComp, MinEdge); + return MinEdge; +} + +static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1, + const TopoDS_Vertex& theVertex2, + const gp_Ax1& theAxis, + TopoDS_Compound& theComp, + TopTools_ListOfShape& theElist) +{ + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); + if (VEmap.IsEmpty()) + return Standard_False; + + if (!VEmap.Contains(theVertex1) || + !VEmap.Contains(theVertex2)) + return Standard_False; + + TopoDS_Vertex CurVertex = theVertex1; + for (;;) + { + TopoDS_Edge CurEdge; + + CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis); + if (CurEdge.IsNull()) + return Standard_False; + + TopoDS_Vertex V1, V2; + TopExp::Vertices(CurEdge, V1, V2); + CurVertex = (V1.IsSame(CurVertex))? V2 : V1; + + theElist.Append(CurEdge); + if (CurVertex.IsSame(theVertex2)) + return Standard_True; + } +} + +static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge, + const TopoDS_Edge& theLastEdge, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Vertex& theCommonVertex) +{ + if (!theFirstVertex.IsSame(theLastVertex)) + { + Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge, + theLastEdge, + theCommonVertex); + return CommonVertexExists; + } + + TopoDS_Vertex V1, V2, V3, V4; + TopExp::Vertices(theFirstEdge, V1, V2); + TopExp::Vertices(theLastEdge, V3, V4); + + if (V1.IsSame(theFirstVertex)) + { + if (V2.IsSame(V3) || + V2.IsSame(V4)) + { + theCommonVertex = V2; + return Standard_True; + } + } + else + { + if (V1.IsSame(V3) || + V1.IsSame(V4)) + { + theCommonVertex = V1; + return Standard_True; + } + } + + return Standard_False; } diff --git a/src/BRepFill/BRepFill_TrimShellCorner.hxx b/src/BRepFill/BRepFill_TrimShellCorner.hxx index 2298d7c6b4..a134916e8b 100644 --- a/src/BRepFill/BRepFill_TrimShellCorner.hxx +++ b/src/BRepFill/BRepFill_TrimShellCorner.hxx @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -28,13 +29,14 @@ #include #include #include +#include class gp_Ax2; class TopoDS_Face; class TopoDS_Wire; class TopoDS_Shape; - +//! Trims sets of faces in the corner to make proper parts of pipe class BRepFill_TrimShellCorner { public: @@ -42,12 +44,13 @@ public: DEFINE_STANDARD_ALLOC - Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Face& theSecPlane); - - Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Wire& theSpine, const TopoDS_Face& theSecPlane); - - Standard_EXPORT void SetSpine (const TopoDS_Wire& theSpine); - + //! Constructor: takes faces to intersect, + //! type of transition (it can be RightCorner or RoundCorner) + //! and axis of bisector plane + Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, + const BRepFill_TransitionStyle theTransition, + const gp_Ax2& theAxeOfBisPlane); + Standard_EXPORT void AddBounds (const Handle(TopTools_HArray2OfShape)& Bounds); Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges); @@ -71,13 +74,29 @@ protected: private: + Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2, + const Standard_Integer theSSInterfIndex); + + Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2); + + Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Shape& resWire, + gp_Pln& resPlane, + Standard_Boolean& IsSingular); + BRepFill_TransitionStyle myTransition; gp_Ax2 myAxeOfBisPlane; TopoDS_Shape myShape1; TopoDS_Shape myShape2; - TopoDS_Wire mySpine; - TopoDS_Face mySecPln; Handle(TopTools_HArray2OfShape) myBounds; Handle(TopTools_HArray2OfShape) myUEdges; Handle(TopTools_HArray2OfShape) myFaces; diff --git a/tests/bugs/modalg_7/bug29204 b/tests/bugs/modalg_7/bug29204 new file mode 100644 index 0000000000..8ce39b7bdc --- /dev/null +++ b/tests/bugs/modalg_7/bug29204 @@ -0,0 +1,26 @@ +puts "============" +puts "OCC29204" +puts "============" +puts "" +################################################################################## +# BRepOffsetAPI_MakePipeShell produces invalid result and raises exception in Draw +################################################################################## + +restore [locate_data_file bug29204_sweep_spine.brep] sp +restore [locate_data_file bug29204_sweep_profile.brep] pr + +mksweep sp +addsweep pr +buildsweep result -C -S + +checkshape result + +checknbshapes result -solid 1 -shell 1 -face 28 -wire 28 -edge 64 -vertex 36 -shape 158 + +set tolres [checkmaxtol result] + +if { ${tolres} > 0.001} { + puts "Error: bad tolerance of result" +} + +checkprops result -v 1.16577e+007