1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0029204: BRepOffsetAPI_MakePipeShell produces invalid result and raises exception in Draw

1.The algorithm searching the section in the corner (ChooseSection) is modified to be able to find simple cases with rather big tolerance.

2. The constructor of BRepFill_Section is modified: now it removes locations in the shape of section like it was done in BRepFill_Pipe.

3. Correction of U-edges by Same Parameter has been added to the method BRepFill_Sweep::Build.
This commit is contained in:
jgv
2017-10-18 17:35:58 +03:00
committed by bugmaster
parent d193f101a7
commit 833e75611f
9 changed files with 789 additions and 336 deletions

View File

@@ -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 <FirstShape> and <LastShape>: 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();