1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +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

@ -102,40 +102,6 @@ static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
return !found; 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, static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace,
TopoDS_Edge& anEdge) TopoDS_Edge& anEdge)
{ {
@ -739,9 +705,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
result = MkSw.Shape(); result = MkSw.Shape();
UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap); UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
myErrorOnSurf = MkSw.ErrorOnSurface(); myErrorOnSurf = MkSw.ErrorOnSurface();
//Correct <myFirst> and <myLast>
ReverseModifiedEdges(myFirst, myReversedEdges);
ReverseModifiedEdges(myLast, myReversedEdges);
// Labeling of elements // Labeling of elements
if (mySections.IsNull()) { if (mySections.IsNull()) {

View File

@ -583,28 +583,15 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
//======================================================================= //=======================================================================
void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape& Profile) void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape& Profile)
{ {
Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
Standard_Boolean Trouve=Standard_False; Standard_Boolean Trouve=Standard_False;
Standard_Integer ii; Standard_Integer ii;
for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) { for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) {
Standard_Boolean found = Standard_False; const TopoDS_Shape& aSection = mySeq.Value(ii).OriginalShape();
const TopoDS_Wire& aWire = mySeq.Value(ii).Wire(); if (Profile.IsSame(aSection))
if (isVertex) {
{ Trouve = Standard_True;
TopExp_Explorer Explo(aWire, TopAbs_VERTEX); mySeq.Remove(ii);
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);
}
} }
if (Trouve) mySection.Nullify(); if (Trouve) mySection.Nullify();
@ -914,13 +901,9 @@ const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
//function : Generated //function : Generated
//purpose : //purpose :
//======================================================================= //=======================================================================
// void BRepFill_PipeShell::Generated(const TopoDS_Shape& ,
// TopTools_ListOfShape& )
void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape, void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape,
TopTools_ListOfShape& theList) TopTools_ListOfShape& theList)
{ {
// throw Standard_NotImplemented("Generated:Pas Fait");
theList.Clear(); theList.Clear();
if(myGenMap.IsBound(theShape)) { if(myGenMap.IsBound(theShape)) {
@ -1197,9 +1180,6 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
Sec.WithCorrection()); Sec.WithCorrection());
TopoDS_Wire TmpWire = Sec.Wire(); TopoDS_Wire TmpWire = Sec.Wire();
aTrsf = Place.Transformation(); aTrsf = Place.Transformation();
//TopLoc_Location Loc2(Place.Transformation()), Loc1;
//Loc1 = TmpWire.Location();
//W.Location(Loc2.Multiplied(Loc1));
//Transform the copy //Transform the copy
W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True));
//////////////////////////////////// ////////////////////////////////////
@ -1240,37 +1220,40 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
TopoDS_Iterator itw; TopoDS_Iterator itw;
for (indw = 1; indw <= mySeq.Length(); indw++) 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(); Standard_Boolean IsPunctual = mySeq(indw).IsPunctual();
if (IsPunctual) if (IsPunctual)
{ {
//for punctual sections (first or last) //for punctual sections (first or last)
//we take all the wires generated along the path //we take all the wires generated along the path
TopExp_Explorer Explo(aSection, TopAbs_VERTEX);
const TopoDS_Shape& VerSection = Explo.Current();
TopTools_ListOfShape Elist; TopTools_ListOfShape Elist;
for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++) for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++)
for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++) for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++)
Elist.Append(anUEdges->Value(i,j)); Elist.Append(anUEdges->Value(i,j));
myGenMap.Bind(VerSection, Elist); myGenMap.Bind(Section, Elist);
continue; continue;
} }
else
aSection = TopoDS::Wire(Section);
//Take the real index of section on the path //Take the real index of section on the path
Standard_Integer IndOfW = myIndOfSec(indw); Standard_Integer IndOfW = myIndOfSec(indw);
const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW)); const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW));
BRepTools_WireExplorer wexp_sec(aSection); BRepTools_WireExplorer wexp_sec(aSection);
for (inde = 1; wexp_sec.More(); wexp_sec.Next()) 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)) if (BRep_Tool::Degenerated(anEdge))
continue; continue;
TopoDS_Shell aShell; TopoDS_Shell aShell;
BB.MakeShell(aShell); BB.MakeShell(aShell);
TopoDS_Vertex aVertex [2]; TopoDS_Vertex aVertex [2];
TopExp::Vertices(anEdge, aVertex[0], aVertex[1]); TopExp::Vertices(anOriginalEdge, aVertex[0], aVertex[1]);
Standard_Integer SignOfAnEdge = Standard_Integer SignOfAnEdge =
(anEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; (anOriginalEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
//For each non-degenerated inde-th edge of <aSection> //For each non-degenerated inde-th edge of <aSection>
//we find inde-th edge in <theWire> //we find inde-th edge in <theWire>
@ -1422,7 +1405,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
TopTools_ListOfShape ListShell; TopTools_ListOfShape ListShell;
ListShell.Append(aShell); ListShell.Append(aShell);
myGenMap.Bind(anEdge, ListShell); myGenMap.Bind(anOriginalEdge, ListShell);
//////////////////////// ////////////////////////
inde++; inde++;

View File

@ -22,6 +22,9 @@
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx> #include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx> #include <TopoDS_Wire.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx>
#include <ShapeUpgrade_RemoveLocations.hxx>
BRepFill_Section::BRepFill_Section() :islaw(0), BRepFill_Section::BRepFill_Section() :islaw(0),
ispunctual(0), ispunctual(0),
@ -41,12 +44,19 @@ BRepFill_Section::BRepFill_Section(const TopoDS_Shape& Profile,
contact(WithContact), contact(WithContact),
correction(WithCorrection) correction(WithCorrection)
{ {
if (Profile.ShapeType() == TopAbs_WIRE) myOriginalShape = Profile;
wire = TopoDS::Wire(Profile);
else if (Profile.ShapeType() == TopAbs_VERTEX) 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; ispunctual = Standard_True;
TopoDS_Vertex aVertex = TopoDS::Vertex(Profile); TopoDS_Vertex aVertex = TopoDS::Vertex(aProfile);
BRep_Builder BB; BRep_Builder BB;
TopoDS_Edge DegEdge; TopoDS_Edge DegEdge;
@ -67,3 +77,58 @@ void BRepFill_Section::Set(const Standard_Boolean IsLaw)
{ {
islaw = 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;
}

View File

@ -43,10 +43,14 @@ public:
Standard_EXPORT void Set (const Standard_Boolean IsLaw); Standard_EXPORT void Set (const Standard_Boolean IsLaw);
const TopoDS_Shape& OriginalShape() const;
const TopoDS_Wire& Wire() const; const TopoDS_Wire& Wire() const;
const TopoDS_Vertex& Vertex() const; const TopoDS_Vertex& Vertex() const;
Standard_EXPORT TopoDS_Shape ModifiedShape(const TopoDS_Shape& theShape) const;
Standard_Boolean IsLaw() const; Standard_Boolean IsLaw() const;
Standard_Boolean IsPunctual() const; Standard_Boolean IsPunctual() const;
@ -68,6 +72,7 @@ private:
TopoDS_Shape myOriginalShape;
TopoDS_Wire wire; TopoDS_Wire wire;
TopoDS_Vertex vertex; TopoDS_Vertex vertex;
Standard_Boolean islaw; Standard_Boolean islaw;

View File

@ -14,6 +14,11 @@
// Alternatively, this file may be used under the terms of Open CASCADE // Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. // commercial license or contractual agreement.
inline const TopoDS_Shape& BRepFill_Section::OriginalShape() const
{
return myOriginalShape;
}
inline const TopoDS_Wire& BRepFill_Section::Wire() const inline const TopoDS_Wire& BRepFill_Section::Wire() const
{ {
return wire; return wire;

View File

@ -366,6 +366,56 @@ static Standard_Boolean SameParameter(TopoDS_Edge& E,
return Standard_True; 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 //Objet : Orientate an edge of natural restriction
// : General // : General
@ -1661,6 +1711,60 @@ static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S,
return B; 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 //function : Constructeur
//purpose : //purpose :
@ -2064,6 +2168,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
Standard_Boolean exuv, singu, singv; Standard_Boolean exuv, singu, singv;
Handle(Geom_Surface) S; Handle(Geom_Surface) S;
//Correct <FirstShape> and <LastShape>: reverse modified edges
ReverseModifiedEdges(FirstShape, ReversedEdges);
ReverseModifiedEdges(LastShape, ReversedEdges);
// (2.0) return preexisting Edges and vertices // (2.0) return preexisting Edges and vertices
TopoDS_Edge E; TopoDS_Edge E;
TColStd_Array1OfBoolean IsBuilt(1, NbLaw); TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
@ -2293,7 +2401,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
// ---------- Creation of Vertex and edge ------------ // ---------- Creation of Vertex and edge ------------
ReversedEdges.Clear();
for (ipath=1, IPath=IFirst; ipath<=NbPath; for (ipath=1, IPath=IFirst; ipath<=NbPath;
ipath++, IPath++) { ipath++, IPath++) {
for (isec=1; isec <=NbLaw; isec++) { for (isec=1; isec <=NbLaw; isec++) {
@ -2496,7 +2603,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
TopoDS::Edge(VEdge(isec, ipath)), TopoDS::Edge(VEdge(isec, ipath)),
ReversedEdges); ReversedEdges);
if (ReversedEdges.Contains(VEdge(isec, ipath))) if (ReversedEdges.Contains(VEdge(isec, ipath)))
{
ReverseEdgeInFirstOrLastWire(FirstShape, VEdge(isec, ipath));
StartEdges(isec).Reverse(); StartEdges(isec).Reverse();
}
} }
} }
@ -2536,6 +2646,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
RebuildTopOrBottomEdge(aNewLastEdge, RebuildTopOrBottomEdge(aNewLastEdge,
TopoDS::Edge(VEdge(isec, ipath+1)), TopoDS::Edge(VEdge(isec, ipath+1)),
ReversedEdges); 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 (ii = 1; ii <= NbLaw; ii++)
for (jj = 1; jj <= NbPath; jj++) 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.AddBounds(Bounds);
aTrim.AddUEdges(aUEdges); aTrim.AddUEdges(aUEdges);
aTrim.Perform(); aTrim.Perform();

View File

@ -25,6 +25,7 @@
#include <BRepFill_TrimShellCorner.hxx> #include <BRepFill_TrimShellCorner.hxx>
#include <BRepLib_MakeEdge.hxx> #include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeWire.hxx> #include <BRepLib_MakeWire.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepTools_ReShape.hxx> #include <BRepTools_ReShape.hxx>
#include <gce_MakeLin.hxx> #include <gce_MakeLin.hxx>
#include <GCPnts_UniformAbscissa.hxx> #include <GCPnts_UniformAbscissa.hxx>
@ -63,6 +64,23 @@
#include <TopTools_ListOfShape.hxx> #include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx> #include <TopTools_SequenceOfShape.hxx>
#include <BRepExtrema_ExtCC.hxx>
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, static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
const Standard_Integer theEIndex1, const Standard_Integer theEIndex1,
@ -71,24 +89,6 @@ static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
Standard_Real& theParamOnE1, Standard_Real& theParamOnE1,
Standard_Real& theParamOnE2); 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, static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
const BOPDS_PDS& theDS, const BOPDS_PDS& theDS,
TopTools_DataMapOfShapeListOfShape& theHistMap); TopTools_DataMapOfShapeListOfShape& theHistMap);
@ -186,55 +186,27 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir
gp_Pln& thePlane, gp_Pln& thePlane,
Standard_Boolean& IsSingular); Standard_Boolean& IsSingular);
static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, static void UpdateSectionEdge(TopoDS_Edge& theEdge,
const gp_Ax2& bis, const TopoDS_Vertex& theConstVertex,
TopoDS_Shape& resWire, TopoDS_Vertex& theVertex,
gp_Pln& resPlane, const Standard_Real theParam);
Standard_Boolean& IsSingular);
// =========================================================================================== // ===========================================================================================
// function: Constructor // function: Constructor
// purpose: // purpose:
// =========================================================================================== // ===========================================================================================
BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
const gp_Ax2& theAxeOfBisPlane, const BRepFill_TransitionStyle theTransition,
const TopoDS_Face& theSecPlane) : const gp_Ax2& theAxeOfBisPlane) :
myAxeOfBisPlane(theAxeOfBisPlane), myTransition(theTransition),
myDone(Standard_False), myAxeOfBisPlane(theAxeOfBisPlane),
myHasSection(Standard_False) myDone(Standard_False),
myHasSection(Standard_False)
{ {
myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(),
theFaces->LowerCol(), theFaces->UpperCol()); theFaces->LowerCol(), theFaces->UpperCol());
myFaces->ChangeArray2() = theFaces->Array2(); 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(!bhassec) {
if(!MakeFacesNonSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, myHistMap)) { if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) {
myHistMap.Clear(); myHistMap.Clear();
return; return;
} }
} }
else { else {
if(!MakeFacesSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) {
i, myAxeOfBisPlane, myHistMap)) {
myHistMap.Clear(); myHistMap.Clear();
return; return;
} }
@ -403,23 +374,21 @@ void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape,
} }
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
// static function: MakeFacesNonSec // function: MakeFacesNonSec
// purpose: // purpose: Updates <myHistMap> by new faces in the case when old faces do not intersect
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, Standard_Boolean
const Handle(TopTools_HArray2OfShape)& theUEdges, BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer theIndex,
const Handle(TopTools_HArray2OfShape)& theBounds, const BOPDS_PDS& theDS,
const BOPDS_PDS& theDS, const Standard_Integer theFaceIndex1,
const Standard_Integer theFaceIndex1, const Standard_Integer theFaceIndex2)
const Standard_Integer theFaceIndex2,
TopTools_DataMapOfShapeListOfShape& theHistMap)
{ {
Standard_Boolean bHasNewEdge = Standard_False; Standard_Boolean bHasNewEdge = Standard_False;
TopoDS_Edge aNewEdge; TopoDS_Edge aNewEdge;
BRep_Builder aBB; BRep_Builder aBB;
const TopoDS_Shape& aE1 = theBounds->Value(theIndex, 1); const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
const TopoDS_Shape& aE2 = theBounds->Value(theIndex, 2); const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
// search common vertex between bounds. begin // search common vertex between bounds. begin
TopoDS_Vertex aCommonVertex; TopoDS_Vertex aCommonVertex;
@ -439,20 +408,20 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI
Standard_Integer ueit = 0, eindex = 0; Standard_Integer ueit = 0, eindex = 0;
for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) { for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
const TopoDS_Shape& aShape1 = theUEdges->Value(eindex, theUEdges->LowerCol()); const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
const TopoDS_Shape& aShape2 = theUEdges->Value(eindex, theUEdges->UpperCol()); const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
TopoDS_Edge aUE1 = TopoDS::Edge(aShape1); TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
TopoDS_Edge aUE2 = TopoDS::Edge(aShape2); TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
if(theHistMap.IsBound(aShape1)) { if (myHistMap.IsBound(aShape1)) {
const TopTools_ListOfShape& lst = theHistMap.Find(aShape1); const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
if(!lst.IsEmpty()) if(!lst.IsEmpty())
aUE1 = TopoDS::Edge(lst.First()); aUE1 = TopoDS::Edge(lst.First());
} }
if(theHistMap.IsBound(aShape2)) { if (myHistMap.IsBound(aShape2)) {
const TopTools_ListOfShape& lst = theHistMap.Find(aShape2); const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
if(!lst.IsEmpty()) if(!lst.IsEmpty())
aUE2 = TopoDS::Edge(lst.First()); aUE2 = TopoDS::Edge(lst.First());
@ -499,11 +468,11 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI
aBB.MakeCompound(aComp); aBB.MakeCompound(aComp);
for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) { 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; TopoDS_Shape aUE = aShape;
if(theHistMap.IsBound(aShape)) { if(myHistMap.IsBound(aShape)) {
const TopTools_ListOfShape& lst = theHistMap.Find(aShape); const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
if(!lst.IsEmpty()) if(!lst.IsEmpty())
aUE = TopoDS::Edge(lst.First()); aUE = TopoDS::Edge(lst.First());
@ -638,7 +607,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI
aNewFace.Orientation(aFaceOri); aNewFace.Orientation(aFaceOri);
TopTools_ListOfShape atmpList; TopTools_ListOfShape atmpList;
atmpList.Append(aNewFace); atmpList.Append(aNewFace);
theHistMap.Bind(aFace, atmpList); myHistMap.Bind(aFace, atmpList);
anExpE.Init(aFace, TopAbs_EDGE); anExpE.Init(aFace, TopAbs_EDGE);
@ -648,7 +617,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI
if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current())) if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
continue; continue;
if(theHistMap.IsBound(anExpE.Current())) if (myHistMap.IsBound(anExpE.Current()))
continue; continue;
TopTools_ListOfShape aListOfNewEdge; TopTools_ListOfShape aListOfNewEdge;
TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE); TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
@ -656,7 +625,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI
for(; anExpE2.More(); anExpE2.Next()) { for(; anExpE2.More(); anExpE2.Next()) {
aListOfNewEdge.Append(anExpE2.Current()); 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 // function: MakeFacesSec
// purpose: // purpose: Updates <myHistMap> by new faces in the case when old faces intersect each other
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, Standard_Boolean
const Handle(TopTools_HArray2OfShape)& theUEdges, BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer theIndex,
const Handle(TopTools_HArray2OfShape)& theBounds, const BOPDS_PDS& theDS,
const BOPDS_PDS& theDS, const Standard_Integer theFaceIndex1,
const Standard_Integer theFaceIndex1, const Standard_Integer theFaceIndex2,
const Standard_Integer theFaceIndex2, const Standard_Integer theSSInterfIndex)
const Standard_Integer theSSInterfIndex,
const gp_Ax2& AxeOfBisPlane,
TopTools_DataMapOfShapeListOfShape& theHistMap)
{ {
const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF(); const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex); const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
@ -687,10 +653,30 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde
if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges)) if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
return Standard_False; 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; TopoDS_Shape SecWire;
gp_Pln SecPlane; gp_Pln SecPlane;
Standard_Boolean IsSingular; Standard_Boolean IsSingular;
Standard_Boolean WireFound = ChooseSection( aSecEdges, AxeOfBisPlane, SecWire, SecPlane, IsSingular ); Standard_Boolean WireFound = ChooseSection(aSecEdges,
FirstVertex, LastVertex,
SecWire, SecPlane, IsSingular );
if(WireFound) { if(WireFound) {
//aSecEdges = SecWire; //aSecEdges = SecWire;
@ -715,19 +701,19 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde
TopAbs_Orientation aFaceOri = aFace.Orientation(); TopAbs_Orientation aFaceOri = aFace.Orientation();
TopoDS_Face aFaceF = aFace; TopoDS_Face aFaceF = aFace;
aFaceF.Orientation(TopAbs_FORWARD); 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); Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
TopoDS_Edge aUE1; TopoDS_Edge aUE1;
TopoDS_Edge aUE2; TopoDS_Edge aUE2;
if(!GetUEdges(theIndex, fit, theUEdges, aBoundEdge, aFaceF, aUE1, aUE2)) if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
return Standard_False; return Standard_False;
TopoDS_Edge aUE1old = aUE1; TopoDS_Edge aUE1old = aUE1;
TopoDS_Edge aUE2old = aUE2; TopoDS_Edge aUE2old = aUE2;
if(theHistMap.IsBound(aUE1)) { if (myHistMap.IsBound(aUE1)) {
const TopTools_ListOfShape& lst = theHistMap.Find(aUE1); const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
if(!lst.IsEmpty()) { if(!lst.IsEmpty()) {
const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation()); const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
@ -738,8 +724,8 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde
} }
} }
if(theHistMap.IsBound(aUE2)) { if (myHistMap.IsBound(aUE2)) {
const TopTools_ListOfShape& lst = theHistMap.Find(aUE2); const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
if(!lst.IsEmpty()) { if(!lst.IsEmpty()) {
const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation()); 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; Standard_Boolean isPave1OnUEdge = Standard_True;
if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex, 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; TopTools_ListOfShape aSecondListOfEdges;
Standard_Boolean bisSectionFound = Standard_False; Standard_Boolean bisSectionFound = Standard_False;
if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge, if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge,
aBoundEdgeIndex, theDS, theHistMap, aSecondListOfEdges, bisSectionFound)) { aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) {
return Standard_False; return Standard_False;
} }
@ -792,7 +778,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde
aNewFace.Orientation(aFaceOri); aNewFace.Orientation(aFaceOri);
TopTools_ListOfShape atmpList; TopTools_ListOfShape atmpList;
atmpList.Append(aNewFace); atmpList.Append(aNewFace);
theHistMap.Bind(aFace, atmpList); myHistMap.Bind(aFace, atmpList);
TopExp_Explorer anExpE(aFace, TopAbs_EDGE); TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
@ -802,7 +788,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde
if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current())) if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
continue; continue;
if(theHistMap.IsBound(anExpE.Current())) if (myHistMap.IsBound(anExpE.Current()))
continue; continue;
TopTools_ListOfShape aListOfNewEdge; TopTools_ListOfShape aListOfNewEdge;
TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE); TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
@ -810,12 +796,240 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde
for(; anExpE2.More(); anExpE2.Next()) { for(; anExpE2.More(); anExpE2.Next()) {
aListOfNewEdge.Append(anExpE2.Current()); aListOfNewEdge.Append(anExpE2.Current());
} }
theHistMap.Bind(anExpE.Current(), aListOfNewEdge); myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
} }
} }
return Standard_True; 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 <FirstEdge> and <LastEdge> 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 <OldComp> 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 // static function: SplitUEdges
@ -966,13 +1180,15 @@ Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
continue; continue;
IntTools_CommonPrt aCP = aEE.CommonPart(); IntTools_CommonPrt aCP = aEE.CommonPart();
if(aCP.Type() == TopAbs_VERTEX) { if(aCP.Type() == TopAbs_VERTEX)
{
theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew()); theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
if (theEIndex1 == aEE.Index1()) {
if (theEIndex1 == aEE.Index1())
IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2); IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
} else { else
IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1); IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
}
// //
bvertexfound = Standard_True; bvertexfound = Standard_True;
break; break;
@ -2004,147 +2220,182 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir
return MaxDeviation; return MaxDeviation;
} }
//=======================================================================
//function : ChooseSection static void UpdateSectionEdge(TopoDS_Edge& theEdge,
//purpose : const TopoDS_Vertex& theConstVertex,
//======================================================================= TopoDS_Vertex& theVertex,
static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, const Standard_Real theParam)
const gp_Ax2& bis,
TopoDS_Shape& resWire,
gp_Pln& resPlane,
Standard_Boolean& IsSingular)
{ {
IsSingular = Standard_False; TopoDS_Edge F_Edge = theEdge;
Standard_Real TolDeviation = 0.01; //, TolConf = 1.e-4, TolAng = 1.e-5; 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; BRep_Builder BB;
Standard_Integer ind, i, j; 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 F_Edge.Free(Standard_True);
TopoDS_Compound OldComp; BB.Remove(F_Edge, AnotherVertex);
BRep_Builder B; theVertex.Orientation(OrOfVertex);
B.MakeCompound( OldComp ); BB.Add(F_Edge, theVertex);
TopoDS_Iterator iter( Comp ); }
for (; iter.More(); iter.Next())
B.Add( OldComp, iter.Value() ); //Finds the edge connected to <theVertex> in the compound <theComp>
//that is closest to bisector plane angularly.
Standard_Boolean anError = Standard_False; //Removes found edge from <theComp>
//TopoDS_Wire NewWire [2]; //<theAxis> is the axis of bisector plane
TopTools_SequenceOfShape Wseq; static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
for (;;) TopoDS_Compound& theComp,
{ const gp_Ax1& theAxis)
TopExp_Explorer explo( OldComp, TopAbs_EDGE ); {
if (!explo.More()) TopTools_IndexedDataMapOfShapeListOfShape VEmap;
break; TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge ); TopoDS_Edge MinEdge;
B.Remove( OldComp, FirstEdge ); if (!VEmap.Contains(theVertex))
if (NewWire.Closed()) return MinEdge;
{
Wseq.Append(NewWire); BRep_Builder BB;
continue;
} const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
if (Edges.Extent() == 1)
for (;;) MinEdge = TopoDS::Edge(Edges.First());
{ else
TopoDS_Vertex Extremity [2]; {
TopExp::Vertices( NewWire, Extremity[0], Extremity[1] ); TopTools_ListIteratorOfListOfShape itl(Edges);
if (Extremity[0].IsNull() || Extremity[1].IsNull()) Standard_Real MinAngle = RealLast();
{ for (; itl.More(); itl.Next())
anError = Standard_True; {
break; const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
} TopoDS_Wire aWire;
TopTools_IndexedDataMapOfShapeListOfShape VEmap; BB.MakeWire(aWire);
TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); BB.Add(aWire, anEdge);
TopTools_ListOfShape Vedges [2]; gp_Pln aPln;
for (j = 0; j < 2; j++) Standard_Boolean issing;
if (VEmap.Contains( Extremity[j] )) ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
Vedges[j] = VEmap.FindFromKey( Extremity[j] ); Standard_Real anAngle;
if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty()) if (issing) //edge is a segment of line
//no more edges in OldComp to continue NewWire {
break; //<anAngle> is angle between <anEdge> and its projection on bisector plane
Standard_Boolean Modified = Standard_False; BRepAdaptor_Curve BAcurve(anEdge);
for (j = 0; j < 2; j++) gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
{ gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter());
if (Vedges[j].Extent() == 1) gp_Vec EdgeVec(FirstPnt, LastPnt);
{ gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() ); anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
NewWire = BRepLib_MakeWire( NewWire, anEdge ); if (anAngle > M_PI/2)
B.Remove( OldComp, anEdge ); anAngle = M_PI - anAngle;
Modified = Standard_True; anAngle = M_PI/2 - anAngle;
} }
} else
if (!Modified) //only multiple connections {
{ anAngle = aPln.Axis().Angle( theAxis );
ind = (Vedges[0].IsEmpty())? 1 : 0; if (anAngle > M_PI/2)
TopTools_SequenceOfShape Edges; anAngle = M_PI - anAngle;
TopTools_ListIteratorOfListOfShape itl( Vedges[ind] ); }
for (; itl.More(); itl.Next())
Edges.Append( itl.Value() ); if (anAngle < MinAngle)
Standard_Integer theind=0; {
Standard_Real MinDeviation = RealLast(); MinAngle = anAngle;
for (j = 1; j <= Edges.Length(); j++) MinEdge = anEdge;
{ }
TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) ); }
gp_Pln aPlane; } //else (more than one edge)
Standard_Boolean issing;
Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing ); BB.Remove(theComp, MinEdge);
if (Deviation < MinDeviation) return MinEdge;
{ }
MinDeviation = Deviation;
theind = j; static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
} const TopoDS_Vertex& theVertex2,
} const gp_Ax1& theAxis,
NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) ); TopoDS_Compound& theComp,
B.Remove( OldComp, Edges(theind) ); TopTools_ListOfShape& theElist)
} {
if (NewWire.Closed()) TopTools_IndexedDataMapOfShapeListOfShape VEmap;
break; TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
} if (VEmap.IsEmpty())
Wseq.Append(NewWire); return Standard_False;
if (anError)
break; if (!VEmap.Contains(theVertex1) ||
} !VEmap.Contains(theVertex2))
return Standard_False;
Standard_Real Deviation=0.;
Standard_Real MinAngle = RealLast(); TopoDS_Vertex CurVertex = theVertex1;
TopExp_Explorer Explo( OldComp, TopAbs_EDGE ); for (;;)
if (!anError && !Explo.More()) {
{ TopoDS_Edge CurEdge;
if (Wseq.Length() == 1)
{ CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
resWire = Wseq.First(); if (CurEdge.IsNull())
Deviation = ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular ); return Standard_False;
return Standard_True;
} TopoDS_Vertex V1, V2;
else TopExp::Vertices(CurEdge, V1, V2);
{ CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
for (i = 1; i <= Wseq.Length(); i++)
{ theElist.Append(CurEdge);
TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) ); if (CurVertex.IsSame(theVertex2))
gp_Pln aPln; return Standard_True;
Standard_Boolean issing; }
Standard_Real aDeviation = }
ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
if (issing) static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
continue; const TopoDS_Edge& theLastEdge,
const TopoDS_Vertex& theFirstVertex,
Standard_Real Angle = aPln.Axis().Angle( bis.Axis() ); const TopoDS_Vertex& theLastVertex,
if (Angle > M_PI/2) TopoDS_Vertex& theCommonVertex)
Angle = M_PI - Angle; {
if (!theFirstVertex.IsSame(theLastVertex))
if (Angle < MinAngle) {
{ Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge,
MinAngle = Angle; theLastEdge,
resWire = aWire; theCommonVertex);
resPlane = aPln; return CommonVertexExists;
Deviation = aDeviation; }
}
} TopoDS_Vertex V1, V2, V3, V4;
if (Deviation <= TolDeviation) TopExp::Vertices(theFirstEdge, V1, V2);
return Standard_True; TopExp::Vertices(theLastEdge, V3, V4);
}
} if (V1.IsSame(theFirstVertex))
return Standard_False; {
//end of simplest case 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;
} }

View File

@ -20,6 +20,7 @@
#include <Standard_DefineAlloc.hxx> #include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx> #include <Standard_Handle.hxx>
#include <BRepFill_TransitionStyle.hxx>
#include <gp_Ax2.hxx> #include <gp_Ax2.hxx>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopoDS_Wire.hxx> #include <TopoDS_Wire.hxx>
@ -28,13 +29,14 @@
#include <Standard_Boolean.hxx> #include <Standard_Boolean.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx> #include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_ListOfShape.hxx> #include <TopTools_ListOfShape.hxx>
#include <BOPDS_PDS.hxx>
class gp_Ax2; class gp_Ax2;
class TopoDS_Face; class TopoDS_Face;
class TopoDS_Wire; class TopoDS_Wire;
class TopoDS_Shape; class TopoDS_Shape;
//! Trims sets of faces in the corner to make proper parts of pipe
class BRepFill_TrimShellCorner class BRepFill_TrimShellCorner
{ {
public: public:
@ -42,12 +44,13 @@ public:
DEFINE_STANDARD_ALLOC DEFINE_STANDARD_ALLOC
Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Face& theSecPlane); //! Constructor: takes faces to intersect,
//! type of transition (it can be RightCorner or RoundCorner)
Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Wire& theSpine, const TopoDS_Face& theSecPlane); //! and axis of bisector plane
Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
Standard_EXPORT void SetSpine (const TopoDS_Wire& theSpine); const BRepFill_TransitionStyle theTransition,
const gp_Ax2& theAxeOfBisPlane);
Standard_EXPORT void AddBounds (const Handle(TopTools_HArray2OfShape)& Bounds); Standard_EXPORT void AddBounds (const Handle(TopTools_HArray2OfShape)& Bounds);
Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges); Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges);
@ -71,13 +74,29 @@ protected:
private: 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; gp_Ax2 myAxeOfBisPlane;
TopoDS_Shape myShape1; TopoDS_Shape myShape1;
TopoDS_Shape myShape2; TopoDS_Shape myShape2;
TopoDS_Wire mySpine;
TopoDS_Face mySecPln;
Handle(TopTools_HArray2OfShape) myBounds; Handle(TopTools_HArray2OfShape) myBounds;
Handle(TopTools_HArray2OfShape) myUEdges; Handle(TopTools_HArray2OfShape) myUEdges;
Handle(TopTools_HArray2OfShape) myFaces; Handle(TopTools_HArray2OfShape) myFaces;

View File

@ -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