1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-24 13:50:49 +03:00

3D Offset algorithm extension for the cases with the shapes having the faces connected only by the VERTEX.

This commit is contained in:
emv
2015-07-07 14:18:28 +03:00
parent c4362927dc
commit 2102c85e9f
4 changed files with 804 additions and 458 deletions

View File

@@ -18,8 +18,8 @@
class Inter2d from BRepOffset class Inter2d from BRepOffset
---Purpose: Computes the intersections betwwen edges on a face ---Purpose: Computes the intersections betwwen edges on a face
-- stores result is SD as AsDes from BRepOffset. -- stores result is SD as AsDes from BRepOffset.
uses uses
AsDes from BRepAlgo, AsDes from BRepAlgo,
@@ -30,27 +30,28 @@ uses
Real from Standard Real from Standard
is is
Compute(myclass ; AsDes : AsDes from BRepAlgo; Compute(myclass ; AsDes : AsDes from BRepAlgo;
F : Face from TopoDS; F : Face from TopoDS;
NewEdges : IndexedMapOfShape from TopTools; NewEdges : IndexedMapOfShape from TopTools;
Tol : Real from Standard); Tol : Real from Standard);
---Purpose: Computes the intersections between the edges stored ---Purpose: Computes the intersections between the edges stored
-- is AsDes as descendants of <F> . Intersections is computed -- is AsDes as descendants of <F> . Intersections is computed
-- between two edges if one of them is bound in NewEdges. -- between two edges if one of them is bound in NewEdges.
-- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin -- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
-- Add another parameter: offset value. -- Add another parameter: offset value.
ConnexIntByInt(myclass ; ConnexIntByInt(myclass ;
FI : Face from TopoDS; FI : Face from TopoDS;
OFI : in out Offset from BRepOffset; OFI : in out Offset from BRepOffset;
MES : in out DataMapOfShapeShape from TopTools; MES : in out DataMapOfShapeShape from TopTools;
Build : DataMapOfShapeShape from TopTools; Build : DataMapOfShapeShape from TopTools;
AsDes : AsDes from BRepAlgo; AsDes : AsDes from BRepAlgo;
Offset: Real from Standard; AsDes2d : AsDes from BRepAlgo;
Tol : Real from Standard); Offset : Real from Standard;
Tol : Real from Standard);
-- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End -- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End
end Inter2d; end Inter2d;

View File

@@ -805,7 +805,6 @@ static void RefEdgeInter(const TopoDS_Face& F,
} }
} }
//====================================================================== //======================================================================
//function : EvaluateMaxSegment //function : EvaluateMaxSegment
//purpose : return MaxSegment to pass in approximation //purpose : return MaxSegment to pass in approximation
@@ -1465,7 +1464,8 @@ void BRepOffset_Inter2d::ConnexIntByInt
BRepOffset_Offset& OFI, BRepOffset_Offset& OFI,
TopTools_DataMapOfShapeShape& MES, TopTools_DataMapOfShapeShape& MES,
const TopTools_DataMapOfShapeShape& Build, const TopTools_DataMapOfShapeShape& Build,
const Handle(BRepAlgo_AsDes)& AsDes, const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset, const Standard_Real Offset,
const Standard_Real Tol) const Standard_Real Tol)
// Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End // Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
@@ -1503,10 +1503,18 @@ void BRepOffset_Inter2d::ConnexIntByInt
} }
} }
} }
TopoDS_Face FIO = TopoDS::Face(OFI.Face()); TopoDS_Face FIO = TopoDS::Face(OFI.Face());
if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO)); if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
//
TopTools_MapOfShape aME;
const TopTools_ListOfShape& aLE = AsDes->Descendant(FIO);
TopTools_ListIteratorOfListOfShape aItLE(aLE);
for (; aItLE.More(); aItLE.Next()) {
const TopoDS_Shape& aE = aItLE.Value();
aME.Add(aE);
}
//
BRepAdaptor_Surface BAsurf(FIO); BRepAdaptor_Surface BAsurf(FIO);
TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE); TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
@@ -1573,7 +1581,28 @@ void BRepOffset_Inter2d::ConnexIntByInt
for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) { for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()), RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
AsDes,Tol,Standard_True/*Standard_False*/, Pref); AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
}
}
//
if (Build.IsBound(Vref)) {
TopoDS_Shape NE3 = Build(Vref);
//
for (Exp2.Init(NE3,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
const TopoDS_Edge& aE3 = *(TopoDS_Edge*)&Exp2.Current();
if (!aME.Contains(aE3)) {
continue;
}
//
for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
}
//
for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
}
} }
} }
} }
@@ -1581,18 +1610,15 @@ void BRepOffset_Inter2d::ConnexIntByInt
if (MES.IsBound(CEO)) { if (MES.IsBound(CEO)) {
TopoDS_Vertex V = CommonVertex(CEO,NEO); TopoDS_Vertex V = CommonVertex(CEO,NEO);
UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol); UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
AsDes->Add (MES(CEO),V); AsDes2d->Add (MES(CEO),V);
} }
else if (MES.IsBound(NEO)) { else if (MES.IsBound(NEO)) {
TopoDS_Vertex V = CommonVertex(CEO,NEO); TopoDS_Vertex V = CommonVertex(CEO,NEO);
UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol); UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
AsDes->Add (MES(NEO),V); AsDes2d->Add (MES(NEO),V);
} }
} }
CurE = NextE; CurE = NextE;
} }
} }
} }

View File

@@ -40,6 +40,7 @@
#include <Extrema_ExtPC.hxx> #include <Extrema_ExtPC.hxx>
#include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfShape.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
@@ -97,110 +98,53 @@ static void ExtentEdge(const TopoDS_Face& /*F*/,
//function : SelectEdge //function : SelectEdge
//purpose : //purpose :
//======================================================================= //=======================================================================
static void SelectEdge (const TopoDS_Shape& theS,
static void SelectEdge (const TopoDS_Face& /*F*/, TopTools_ListOfShape& theLE)
const TopoDS_Face& /*EF*/,
const TopoDS_Edge& E,
TopTools_ListOfShape& LInt)
{ {
//------------------------------------------------------------ Standard_Real aT1, aT2, aDist, aDistMin;
// Proofing on the intersections on periodical faces TopExp_Explorer aExp;
//------------------------------------------------------------ TopTools_ListIteratorOfListOfShape aIt;
TopTools_ListIteratorOfListOfShape it(LInt); GeomAPI_ProjectPointOnCurve aProjPC;
// Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin gp_Pnt aPE1, aPE2;
// Standard_Real dU = 1.0e100; TopoDS_Edge aRE;
Standard_Real dU = RealLast(); //
// Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End aDistMin = RealLast();
TopoDS_Edge GE; //
aIt.Initialize(theLE);
Standard_Real Fst, Lst, tmp; for (; aIt.More(); aIt.Next()) {
BRep_Tool::Range(E, Fst, Lst); const TopoDS_Edge& aE = *(TopoDS_Edge*)&aIt.Value();
BRepAdaptor_Curve Ad1(E); //
const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2);
gp_Pnt PFirst = Ad1.Value( Fst ); //
gp_Pnt PLast = Ad1.Value( Lst ); aProjPC.Init(aC, aT1, aT2);
aPE1 = aC->Value(aT1);
// Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin aPE2 = aC->Value(aT2);
Extrema_ExtPC anExt; //
// Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End aDist = 0.;
//---------------------------------------------------------------------- aExp.Init(theS, TopAbs_VERTEX);
// Selection of edge that coversmost of the domain of the initial edge. for (; aExp.More(); aExp.Next()) {
//---------------------------------------------------------------------- const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExp.Current();
for (; it.More(); it.Next()) { const gp_Pnt aP = BRep_Tool::Pnt(aV);
const TopoDS_Edge& EI = TopoDS::Edge(it.Value()); //
aProjPC.Perform(aP);
BRep_Tool::Range(EI, Fst, Lst); if (aProjPC.NbPoints()) {
BRepAdaptor_Curve Ad2(EI); aDist += aProjPC.LowerDistance();
}
// Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin else {
Standard_Integer i; aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2));
Standard_Real aTol = BRep_Tool::Tolerance(EI);
Standard_Boolean isMinFound = Standard_False;
Standard_Real aSqrDist1 = Precision::Infinite();
Standard_Real aSqrDist2 = Precision::Infinite();
anExt.Initialize(Ad2, Fst, Lst, aTol);
// Seek for the min distance for PFirst:
anExt.Perform(PFirst);
if (anExt.IsDone()) {
for (i = 1; i <= anExt.NbExt(); i++) {
if (anExt.IsMin(i)) {
const gp_Pnt &aPMin = anExt.Point(i).Value();
aSqrDist1 = PFirst.SquareDistance(aPMin);
isMinFound = Standard_True;
break;
}
} }
} }
if (!isMinFound) { //
gp_Pnt aP1 = Ad2.Value(Fst); if (aDist < aDistMin) {
gp_Pnt aP2 = Ad2.Value(Lst); aDistMin = aDist;
aRE = aE;
aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst));
} }
// Seek for the min distance for PLast:
isMinFound = Standard_False;
anExt.Perform(PLast);
if (anExt.IsDone()) {
for (i = 1; i <= anExt.NbExt(); i++) {
if (anExt.IsMin(i)) {
const gp_Pnt &aPMin = anExt.Point(i).Value();
aSqrDist2 = PLast.SquareDistance(aPMin);
isMinFound = Standard_True;
break;
}
}
}
if (!isMinFound) {
gp_Pnt aP1 = Ad2.Value(Fst);
gp_Pnt aP2 = Ad2.Value(Lst);
aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast));
}
tmp = aSqrDist1 + aSqrDist2;
// gp_Pnt P1 = Ad2.Value(Fst);
// gp_Pnt P2 = Ad2.Value(Lst);
// tmp = P1.Distance(PFirst) + P2.Distance(PLast);
if( tmp <= dU ) {
dU = tmp;
GE = EI;
}
// Modified by Sergey KHROMOV - Wed Jun 5 11:24:54 2002 End
} }
LInt.Clear(); //
LInt.Append(GE); theLE.Clear();
theLE.Append(aRE);
} }
//======================================================================= //=======================================================================
//function : CompletInt //function : CompletInt
//purpose : //purpose :
@@ -482,103 +426,213 @@ void BRepOffset_Inter3d::ConnexIntByInt
TopTools_ListOfShape& Failed) TopTools_ListOfShape& Failed)
{ {
//TopExp_Explorer Exp(SI,TopAbs_EDGE); //TopExp_Explorer Exp(SI,TopAbs_EDGE);
TopTools_IndexedMapOfShape Emap; TopTools_IndexedMapOfShape VEmap;
TopExp::MapShapes( SI, TopAbs_EDGE, Emap ); TopTools_IndexedDataMapOfShapeListOfShape aMVF;
TopoDS_Face F1,F2,OF1,OF2,NF1,NF2; TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
TopAbs_State CurSide = mySide; TopAbs_State CurSide = mySide;
BRep_Builder B; BRep_Builder B;
TopTools_ListIteratorOfListOfShape it; Standard_Boolean bEdge;
Standard_Integer i, aNb;
//for (; Exp.More(); Exp.Next()) { TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
for (Standard_Integer i = 1; i <= Emap.Extent(); i++) { //
//const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); TopExp::MapShapes(SI, TopAbs_EDGE , VEmap);
const TopoDS_Edge& E = TopoDS::Edge(Emap(i)); TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
const BRepOffset_ListOfInterval& L = Analyse.Type(E); TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
if (!L.IsEmpty()) { //
aNb = VEmap.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aS = VEmap(i);
//
TopoDS_Edge E;
TopTools_ListOfShape aLF1, aLF2;
//
bEdge = (aS.ShapeType() == TopAbs_EDGE);
if (bEdge) {
// faces connected by the edge
E = *(TopoDS_Edge*)&aS;
//
const BRepOffset_ListOfInterval& L = Analyse.Type(E);
if (L.IsEmpty()) {
continue;
}
//
BRepOffset_Type OT = L.First().Type(); BRepOffset_Type OT = L.First().Type();
if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) { if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
if (OT == BRepOffset_Concave) CurSide = TopAbs_IN; continue;
else CurSide = TopAbs_OUT; }
//----------------------------------------------------------- //
// edge is of the proper type, return adjacent faces. if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
//----------------------------------------------------------- else CurSide = TopAbs_OUT;
const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); //-----------------------------------------------------------
if (Anc.Extent() != 2) continue; // edge is of the proper type, return adjacent faces.
F1 = TopoDS::Face(Anc.First()); //-----------------------------------------------------------
F2 = TopoDS::Face(Anc.Last ()); const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face()); if (Anc.Extent() != 2) {
if (!MES.IsBound(OF1)) { continue;
Standard_Boolean enlargeU = Standard_True; }
Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; //
BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); F1 = TopoDS::Face(Anc.First());
BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); F2 = TopoDS::Face(Anc.Last ());
MES.Bind(OF1,NF1); //
} aLF1.Append(F1);
else { aLF2.Append(F2);
NF1 = TopoDS::Face(MES(OF1));
}
if (!MES.IsBound(OF2)) {
Standard_Boolean enlargeU = Standard_True;
Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
MES.Bind(OF2,NF2);
}
else {
NF2 = TopoDS::Face(MES(OF2));
}
if (!IsDone(NF1,NF2)) {
TopTools_ListOfShape LInt1,LInt2;
BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True);
if (LInt1.Extent() > 1)
{
// intersection is in seceral edges (free sewing)
SelectEdge( NF1, NF2, E, LInt1 );
SelectEdge( NF1, NF2, E, LInt2 );
}
SetDone(NF1,NF2);
if (!LInt1.IsEmpty()) {
Store (NF1,NF2,LInt1,LInt2);
TopoDS_Compound C;
B.MakeCompound(C);
for (it.Initialize(LInt1) ; it.More(); it.Next()) {
B.Add(C,it.Value());
}
Build.Bind(E,C);
}
else {
Failed.Append(E);
}
} else { // IsDone(NF1,NF2)
// Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
if (!aLInt1.IsEmpty()) {
TopoDS_Compound C;
TopTools_ListIteratorOfListOfShape anIt2;
B.MakeCompound(C);
for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
const TopoDS_Shape &anE1 = it.Value();
for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) {
const TopoDS_Shape &anE2 = anIt2.Value();
if (anE1.IsSame(anE2))
B.Add(C, anE1);
}
}
Build.Bind(E,C);
}
else {
Failed.Append(E);
}
}
// Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
}
} }
else {
// faces connected by the vertex
const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS);
if (aLF.Extent() < 2) {
continue;
}
//
Standard_Boolean bVertexOnly = Standard_False;
TopTools_MapOfShape aMFence;
//
it.Initialize(aLF);
for (; it.More(); it.Next()) {
const TopoDS_Face& aFV1 = *(TopoDS_Face*)&it.Value();
if (!aMFence.Add(aFV1)) {
continue;
}
//
TopTools_MapOfShape aME;
TopExp_Explorer aExp(aFV1, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aME.Add(aExp.Current());
}
//
it1.Initialize(aLF);
for (it1.Next(); it1.More(); it1.Next()) {
const TopoDS_Face& aFV2 = *(TopoDS_Face*)&it1.Value();
if (aMFence.Contains(aFV2)) {
continue;
}
//
bVertexOnly = Standard_True;
aExp.Init(aFV2, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aEV2 = aExp.Current();
if (aME.Contains(aEV2)) {
bVertexOnly = Standard_False;
break;
}
}
//
if (bVertexOnly) {
aLF1.Append(aFV1);
aLF2.Append(aFV2);
aMFence.Add(aFV2);
}
}
}
//
if (aLF1.IsEmpty()) {
continue;
}
//
CurSide = mySide;
}
//
itF1.Initialize(aLF1);
itF2.Initialize(aLF2);
for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) {
F1 = TopoDS::Face(itF1.Value());
F2 = TopoDS::Face(itF2.Value());
//
OF1 = TopoDS::Face(MapSF(F1).Face());
OF2 = TopoDS::Face(MapSF(F2).Face());
if (!MES.IsBound(OF1)) {
Standard_Boolean enlargeU = Standard_True;
Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
MES.Bind(OF1,NF1);
}
else {
NF1 = TopoDS::Face(MES(OF1));
}
//
if (!MES.IsBound(OF2)) {
Standard_Boolean enlargeU = Standard_True;
Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
MES.Bind(OF2,NF2);
}
else {
NF2 = TopoDS::Face(MES(OF2));
}
//
if (!IsDone(NF1,NF2)) {
TopTools_ListOfShape LInt1,LInt2;
BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge);
if (LInt1.Extent() > 1) {
// intersection is in seceral edges (free sewing)
SelectEdge(aS, LInt1);
SelectEdge(aS, LInt2);
}
SetDone(NF1,NF2);
if (!LInt1.IsEmpty()) {
Store (NF1,NF2,LInt1,LInt2);
//
TopoDS_Compound C;
B.MakeCompound(C);
//
if (Build.IsBound(aS)) {
const TopoDS_Shape& aSE = Build(aS);
TopExp_Explorer aExp(aSE, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aNE = aExp.Current();
B.Add(C, aNE);
}
}
//
it.Initialize(LInt1);
for (; it.More(); it.Next()) {
const TopoDS_Shape& aNE = it.Value();
B.Add(C, aNE);
}
//
Build.Bind(aS,C);
}
else {
Failed.Append(aS);
}
} else { // IsDone(NF1,NF2)
// Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
if (!aLInt1.IsEmpty()) {
TopoDS_Compound C;
B.MakeCompound(C);
//
if (Build.IsBound(aS)) {
const TopoDS_Shape& aSE = Build(aS);
TopExp_Explorer aExp(aSE, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aNE = aExp.Current();
B.Add(C, aNE);
}
}
//
for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
const TopoDS_Shape &anE1 = it.Value();
//
for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) {
const TopoDS_Shape &anE2 = it1.Value();
if (anE1.IsSame(anE2))
B.Add(C, anE1);
}
}
Build.Bind(aS,C);
}
else {
Failed.Append(aS);
}
}
}
// Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
} }
} }
@@ -603,10 +657,12 @@ void BRepOffset_Inter3d::ContextIntByInt
TopoDS_Edge OE; TopoDS_Edge OE;
TopoDS_Compound C; TopoDS_Compound C;
BRep_Builder B; BRep_Builder B;
TopTools_ListIteratorOfListOfShape it; TopTools_ListIteratorOfListOfShape it, itF;
Standard_Integer i; Standard_Integer i, j, aNb, aNbVE;
Standard_Boolean bEdge;
for (i = 1; i <= ContextFaces.Extent(); i++) {
aNb = ContextFaces.Extent();
for (i = 1; i <= aNb; i++) {
const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
myTouched.Add(CF); myTouched.Add(CF);
if (ExtentContext) { if (ExtentContext) {
@@ -616,89 +672,153 @@ void BRepOffset_Inter3d::ContextIntByInt
} }
TopAbs_State Side = TopAbs_OUT; TopAbs_State Side = TopAbs_OUT;
for (i = 1; i <= ContextFaces.Extent(); i++) { for (i = 1; i <= aNb; i++) {
const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
if (ExtentContext) WCF = TopoDS::Face(MES(CF)); if (ExtentContext) WCF = TopoDS::Face(MES(CF));
else WCF = CF; else WCF = CF;
for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); TopTools_IndexedMapOfShape VEmap;
exp.More(); exp.Next()) { TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
if (!Analyse.HasAncestor(E)) { //
//---------------------------------------------------------------- aNbVE = VEmap.Extent();
// the edges of faces of context that are not in the initial shape for (j = 1; j <= aNbVE; ++j) {
// can appear in the result. const TopoDS_Shape& aS = VEmap(j);
//---------------------------------------------------------------- //
if (!ExtentContext) { bEdge = (aS.ShapeType() == TopAbs_EDGE);
myAsDes->Add(CF,E); //
myNewEdges.Add(E); TopoDS_Edge E;
} TopTools_ListOfShape Anc;
else { //
if (!MES.IsBound(E)) { if (bEdge) {
TopoDS_Edge NE; // faces connected by the edge
Standard_Real f,l,Tol; //
BRep_Tool::Range(E,f,l); E = *(TopoDS_Edge*)&aS;
Tol = BRep_Tool::Tolerance(E); if (!Analyse.HasAncestor(E)) {
ExtentEdge(CF,E,NE); //----------------------------------------------------------------
TopoDS_Vertex V1,V2; // the edges of faces of context that are not in the initial shape
TopExp::Vertices(E,V1,V2); // can appear in the result.
NE.Orientation(TopAbs_FORWARD); //----------------------------------------------------------------
myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); if (!ExtentContext) {
myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); myAsDes->Add(CF,E);
TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); myNewEdges.Add(E);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); }
aLocalShape = V2.Oriented(TopAbs_INTERNAL); else {
B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); if (!MES.IsBound(E)) {
TopoDS_Edge NE;
Standard_Real f,l,Tol;
BRep_Tool::Range(E,f,l);
Tol = BRep_Tool::Tolerance(E);
ExtentEdge(CF,E,NE);
TopoDS_Vertex V1,V2;
TopExp::Vertices(E,V1,V2);
NE.Orientation(TopAbs_FORWARD);
myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
aLocalShape = V2.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
NE.Orientation(E.Orientation()); NE.Orientation(E.Orientation());
myAsDes->Add(CF,NE); myAsDes->Add(CF,NE);
myNewEdges.Add(NE); myNewEdges.Add(NE);
MES.Bind(E,NE); MES.Bind(E,NE);
} }
else { else {
TopoDS_Shape NE = MES(E); TopoDS_Shape NE = MES(E);
TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation()); TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
myAsDes->Add(CF,aLocalShape); myAsDes->Add(CF,aLocalShape);
// myAsDes->Add(CF,NE.Oriented(E.Orientation())); // myAsDes->Add(CF,NE.Oriented(E.Orientation()));
}
} }
} continue;
continue; }
} Anc = Analyse.Ancestors(E);
const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
const TopoDS_Face& F = TopoDS::Face(Anc.First());
OF = TopoDS::Face(MapSF(F).Face());
TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
OE = TopoDS::Edge(aLocalShape);
// OE = TopoDS::Edge(MapSF(F).Generated(E));
if (!MES.IsBound(OF)) {
BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
MES.Bind(OF,NF);
} }
else { else {
NF = TopoDS::Face(MES(OF)); // faces connected by the vertex
} //
if (!IsDone(NF,CF)) { if (!Analyse.HasAncestor(aS)) {
TopTools_ListOfShape LInt1,LInt2; continue;
TopTools_ListOfShape LOE; }
LOE.Append(OE); //
BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True); const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS);
SetDone(NF,CF); it.Initialize(aLE);
if (!LInt1.IsEmpty()) { for (; it.More(); it.Next()) {
Store (CF,NF,LInt1,LInt2); const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value();
if (LInt1.Extent() == 1) { //
Build.Bind(E,LInt1.First()); if (BRep_Tool::Degenerated(aE)) {
continue;
} }
else { //
B.MakeCompound(C); if (VEmap.Contains(aE)) {
for (it.Initialize(LInt1) ; it.More(); it.Next()) { continue;
B.Add(C,it.Value()); }
//
const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE);
itF.Initialize(aLF);
for (; itF.More(); itF.Next()) {
const TopoDS_Shape& aF = itF.Value();
Standard_Boolean bAdd = Standard_True;
exp.Init(aF, TopAbs_EDGE);
for (; exp.More() && bAdd; exp.Next()) {
const TopoDS_Shape& aEF = exp.Current();
bAdd = !VEmap.Contains(aEF);
}
if (bAdd) {
Anc.Append(aF);
} }
Build.Bind(E,C);
} }
} }
}
//
itF.Initialize(Anc);
for (; itF.More(); itF.Next()) {
const TopoDS_Face& F = TopoDS::Face(itF.Value());
OF = TopoDS::Face(MapSF(F).Face());
TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
OE = TopoDS::Edge(aLocalShape);
// OE = TopoDS::Edge(MapSF(F).Generated(E));
if (!MES.IsBound(OF)) {
BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
MES.Bind(OF,NF);
}
else { else {
Failed.Append(E); NF = TopoDS::Face(MES(OF));
}
if (!IsDone(NF,CF)) {
TopTools_ListOfShape LInt1,LInt2;
TopTools_ListOfShape LOE;
LOE.Append(OE);
BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge);
SetDone(NF,CF);
if (!LInt1.IsEmpty()) {
Store (CF,NF,LInt1,LInt2);
if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) {
Build.Bind(aS,LInt1.First());
}
else {
B.MakeCompound(C);
if (Build.IsBound(aS)) {
const TopoDS_Shape& aSE = Build(aS);
exp.Init(aSE, TopAbs_EDGE);
for (; exp.More(); exp.Next()) {
const TopoDS_Shape& aNE = exp.Current();
B.Add(C, aNE);
}
}
//
for (it.Initialize(LInt1) ; it.More(); it.Next()) {
B.Add(C,it.Value());
}
Build.Bind(aS,C);
}
}
else {
Failed.Append(aS);
}
} }
} }
} }

View File

@@ -901,7 +901,9 @@ static void TrimEdge (TopoDS_Edge& NE,
Standard_Real UMax = -UMin; Standard_Real UMax = -UMin;
const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE); const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
//
Standard_Boolean bTrim = Standard_False;
//
if (LE.Extent() > 1) { if (LE.Extent() > 1) {
TopTools_ListIteratorOfListOfShape it (LE); TopTools_ListIteratorOfListOfShape it (LE);
for (; it.More(); it.Next()) { for (; it.More(); it.Next()) {
@@ -909,16 +911,15 @@ static void TrimEdge (TopoDS_Edge& NE,
if (NE.Orientation() == TopAbs_REVERSED) if (NE.Orientation() == TopAbs_REVERSED)
V.Reverse(); V.Reverse();
//V.Orientation(TopAbs_INTERNAL); //V.Orientation(TopAbs_INTERNAL);
if (!FindParameter(V, NE, U)) if (!FindParameter(V, NE, U)) {
{ Standard_Real f, l;
Standard_Real f, l; Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); gp_Pnt thePoint = BRep_Tool::Pnt(V);
gp_Pnt thePoint = BRep_Tool::Pnt(V); GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); if (Projector.NbPoints() == 0)
if (Projector.NbPoints() == 0) Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); U = Projector.LowerDistanceParameter();
U = Projector.LowerDistanceParameter(); }
}
if (U < UMin) { if (U < UMin) {
UMin = U; V1 = V; UMin = U; V1 = V;
} }
@@ -926,6 +927,7 @@ static void TrimEdge (TopoDS_Edge& NE,
UMax = U; V2 = V; UMax = U; V2 = V;
} }
} }
//
if (V1.IsNull() || V2.IsNull()) { if (V1.IsNull() || V2.IsNull()) {
Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge"); Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
} }
@@ -945,6 +947,19 @@ static void TrimEdge (TopoDS_Edge& NE,
AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD)); AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED)); AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
BRepLib::SameParameter(NE, aSameParTol, Standard_True); BRepLib::SameParameter(NE, aSameParTol, Standard_True);
//
bTrim = Standard_True;
}
}
//
if (!bTrim) {
if (!BRep_Tool::Degenerated(NE)) {
BRepAdaptor_Curve aBAC(NE);
if (!aBAC.IsClosed()) {
if (AsDes->HasAscendant(NE)) {
AsDes->Remove(NE);
}
}
} }
} }
} }
@@ -961,6 +976,10 @@ static void TrimEdge (TopoDS_Edge& NE,
#include <BOPDS_VectorOfInterfVE.hxx> #include <BOPDS_VectorOfInterfVE.hxx>
#include <BOPCol_DataMapOfShapeShape.hxx> #include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPTools_AlgoTools3D.hxx> #include <BOPTools_AlgoTools3D.hxx>
#include <IntTools_Context.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <CPnts_AbscissaPoint.hxx>
#include <IntTools_ShrunkRange.hxx>
//======================================================================= //=======================================================================
//function : SortFaces //function : SortFaces
@@ -1032,7 +1051,7 @@ static void SortFaces(const TopTools_ListOfShape& theLIm,
TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
} }
// //
// find outer edges and check if they touche the first part of edges // find outer edges and check if they touch the first part of edges
aItLF.Initialize(aLFTmp); aItLF.Initialize(aLFTmp);
for (; aItLF.More(); aItLF.Next()) { for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
@@ -1044,8 +1063,7 @@ static void SortFaces(const TopTools_ListOfShape& theLIm,
TopoDS_Vertex aV1, aV2; TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aE, aV1, aV2); TopExp::Vertices(aE, aV1, aV2);
// //
bFlag = aMV.Contains(aV1) || bFlag = aMV.Contains(aV1) || aMV.Contains(aV2);
aMV.Contains(aV2);
} }
} }
// //
@@ -1192,6 +1210,64 @@ static void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
} }
} }
//=======================================================================
//function : IsMicroEdge
//purpose :
//=======================================================================
static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge,
const Handle(IntTools_Context)& theCtx,
Standard_Real& theFuzz)
{
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(theEdge, aV1, aV2);
Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull();
if (bNull) {
return Standard_False;
}
//
Standard_Boolean bMicro;
Standard_Real aT1, aT2;
IntTools_ShrunkRange aSR;
//
BRepAdaptor_Curve aBAC(theEdge);
//
aT1 = BRep_Tool::Parameter(aV1, theEdge);
aT2 = BRep_Tool::Parameter(aV2, theEdge);
if (aT2 < aT1) {
Standard_Real aTmp = aT1;
aT1 = aT2;
aT2 = aTmp;
}
//
aSR.SetContext(theCtx);
aSR.SetData(theEdge, aT1, aT2, aV1, aV2);
aSR.Perform();
bMicro = (aSR.ErrorStatus() != 0);
if (!bMicro) {
Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2;
//
aTolV1 = BRep_Tool::Tolerance(aV1);
aTolV2 = BRep_Tool::Tolerance(aV2);
//
anEps = aBAC.Resolution(aTolV1 + aTolV2);
if (anEps < 1.e-8) {
anEps = 1.e-8;
}
//
aSR.ShrunkRange(aTS1, aTS2);
bMicro = (aTS2 - aTS1) <= anEps;
}
//
if (bMicro) {
Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC);
if (aLen > theFuzz) {
theFuzz = aLen;
}
}
//
return bMicro;
}
//======================================================================= //=======================================================================
//function : BuildSplitsOfFaces //function : BuildSplitsOfFaces
//purpose : //purpose :
@@ -1208,8 +1284,15 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
BOPCol_ListIteratorOfListOfShape aIt; BOPCol_ListIteratorOfListOfShape aIt;
TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1; TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1;
TopTools_DataMapOfShapeListOfShape anEImages; TopTools_DataMapOfShapeListOfShape anEImages;
BRep_Builder aBB;
TopoDS_Compound aFaces;
//
aBB.MakeCompound(aFaces);
// //
// firstly it is necessary to fuse all the edges // firstly it is necessary to fuse all the edges
Standard_Real aFuzz = 0.;
Handle(IntTools_Context) aCtx = new IntTools_Context();
//
aItLF.Initialize(theLF); aItLF.Initialize(theLF);
for (; aItLF.More(); aItLF.Next()) { for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aF = aItLF.Value(); const TopoDS_Shape& aF = aItLF.Value();
@@ -1221,41 +1304,41 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
if (BRep_Tool::Degenerated(aE)) { if (BRep_Tool::Degenerated(aE)) {
continue; continue;
} }
//
if (IsMicroEdge(aE, aCtx, aFuzz)) {
continue;
}
//
aLS.Append(aE); aLS.Append(aE);
} }
} }
// //
if (aLS.Extent() > 1) { if (aLS.Extent() > 1) {
BOPAlgo_PaveFiller aPF; BOPAlgo_Builder aGFE;
// //
aPF.SetArguments(aLS); aGFE.SetArguments(aLS);
aPF.Perform(); aGFE.SetFuzzyValue(aFuzz);
if (aPF.ErrorStatus() == 0) { aGFE.Perform();
BOPAlgo_Builder aGFE; if (aGFE.ErrorStatus() == 0) {
// // fill map with edges images
aGFE.SetArguments(aLS); aIt.Initialize(aLS);
aGFE.PerformWithFiller(aPF); for (; aIt.More(); aIt.Next()) {
if (aGFE.ErrorStatus() == 0) { const TopoDS_Shape& aE = aIt.Value();
// fill map with edges images
aIt.Initialize(aLS);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE = aIt.Value();
//
const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE);
if (aLEIm.Extent()) {
anEImages.Bind(aE, aLEIm);
}
}
// //
UpdateOrigins(theOrigins, aGFE); const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE);
if (aLEIm.Extent()) {
anEImages.Bind(aE, aLEIm);
}
} }
//
UpdateOrigins(theOrigins, aGFE);
} }
} }
// //
// now we can split the faces // now we can split the faces
aItLF.Initialize(theLF); aItLF.Initialize(theLF);
for (; aItLF.More(); aItLF.Next()) { for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aF = aItLF.Value(); const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value();
// //
// the offset face // the offset face
aLS.Clear(); aLS.Clear();
@@ -1279,6 +1362,7 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
} }
} }
// //
aFuzz = 0.;
// the edges by which the offset face should be split // the edges by which the offset face should be split
const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF);
aItLE.Initialize(aLE); aItLE.Initialize(aLE);
@@ -1292,7 +1376,12 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
const TopTools_ListOfShape& aLEIm = anEImages.Find(aE); const TopTools_ListOfShape& aLEIm = anEImages.Find(aE);
aItLE1.Initialize(aLEIm); aItLE1.Initialize(aLEIm);
for (; aItLE1.More(); aItLE1.Next()) { for (; aItLE1.More(); aItLE1.Next()) {
const TopoDS_Shape& aEIm = aItLE1.Value(); const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aItLE1.Value();
// check for micro edge
if (IsMicroEdge(aEIm, aCtx, aFuzz)) {
continue;
}
//
aLS.Append(aEIm); aLS.Append(aEIm);
if (!aMFE.Contains(aEIm)) { if (!aMFE.Contains(aEIm)) {
++iCountE; ++iCountE;
@@ -1300,6 +1389,9 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
} }
} }
else { else {
if (IsMicroEdge(aE, aCtx, aFuzz)) {
continue;
}
aLS.Append(aE); aLS.Append(aE);
if (!aMFE.Contains(aE)) { if (!aMFE.Contains(aE)) {
++iCountE; ++iCountE;
@@ -1313,12 +1405,14 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
if (!iCountE) { if (!iCountE) {
aLFImages.Append(aF); aLFImages.Append(aF);
theImage.Bind(aF, aLFImages); theImage.Bind(aF, aLFImages);
aBB.Add(aFaces, aF);
continue; continue;
} }
// //
BOPAlgo_Builder aGF; BOPAlgo_Builder aGF;
// //
aGF.SetArguments(aLS); aGF.SetArguments(aLS);
aGF.SetFuzzyValue(aFuzz);
aGF.Perform(); aGF.Perform();
if (aGF.ErrorStatus()) { if (aGF.ErrorStatus()) {
theLFailed.Append(aF); theLFailed.Append(aF);
@@ -1397,6 +1491,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
aExp.Init(aFIm, TopAbs_EDGE); aExp.Init(aFIm, TopAbs_EDGE);
for (bKeep = Standard_True; aExp.More() && bKeep; aExp.Next()) { for (bKeep = Standard_True; aExp.More() && bKeep; aExp.Next()) {
const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
//
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
bKeep = aME.Contains(aE); bKeep = aME.Contains(aE);
} }
// //
@@ -1431,11 +1530,20 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
for (; aExp.More(); aExp.Next()) { for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
// //
if (BRep_Tool::Degenerated(aEIm)) {
continue;
}
//
if (!theOrigins.Contains(aEIm)) { if (!theOrigins.Contains(aEIm)) {
continue; continue;
} }
// //
const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm); const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
const TopoDS_Shape& aSOr = aLEOr.First();
if (aSOr.ShapeType() != TopAbs_EDGE) {
bRem = Standard_False;
break;
}
// //
if (aLEOr.Extent() > 1) { if (aLEOr.Extent() > 1) {
TopTools_MapOfShape aME, aMV; TopTools_MapOfShape aME, aMV;
@@ -1494,11 +1602,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
} }
} }
// //
if (bRem) { if (bRem && !bKeep) {
aLFImages.Remove(aItLE); aLFImages.Remove(aItLE);
} }
else { else {
if (bKeep) { if (!bRem && bKeep) {
aLFKeep.Append(aFIm); aLFKeep.Append(aFIm);
} }
aItLE.Next(); aItLE.Next();
@@ -1531,20 +1639,41 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
theImage.Bind(aF, aLFImages); theImage.Bind(aF, aLFImages);
} }
else { else {
theLFailed.Append(aF); BRepAdaptor_Surface aBAS(aF, Standard_False);
if (aBAS.GetType() != GeomAbs_Plane) {
theLFailed.Append(aF);
}
}
//
aItLE.Initialize(aLFImages);
for (; aItLE.More(); aItLE.Next()) {
const TopoDS_Shape& aFIm = aItLE.Value();
aBB.Add(aFaces, aFIm);
} }
} }
// //
// fill history for edges // fill history for edges
TopTools_IndexedMapOfShape aMFE;
TopExp::MapShapes(aFaces, TopAbs_EDGE, aMFE);
//
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages); TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages);
for (; aItEIm.More(); aItEIm.Next()) { for (; aItEIm.More(); aItEIm.Next()) {
const TopoDS_Shape& aE = aItEIm.Key(); const TopoDS_Shape& aE = aItEIm.Key();
const TopTools_ListOfShape& aLEIm = aItEIm.Value(); const TopTools_ListOfShape& aLEIm = aItEIm.Value();
if (theImage.HasImage(aE)) { //
theImage.Add(aE, aLEIm); Standard_Boolean bHasImage = theImage.HasImage(aE);
} aItLE.Initialize(aLEIm);
else { for (; aItLE.More(); aItLE.Next()) {
theImage.Bind(aE, aLEIm); const TopoDS_Shape& aEIm = aItLE.Value();
if (aMFE.Contains(aEIm)) {
if (bHasImage) {
theImage.Add(aE, aEIm);
}
else {
theImage.Bind(aE, aEIm);
bHasImage = Standard_True;
}
}
} }
} }
} }
@@ -1645,7 +1774,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol); // BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myOffset, myTol); BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes,AsDes2d,myOffset, myTol);
// Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End // Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
} }
//----------------------------------------------------------- //-----------------------------------------------------------
@@ -1661,78 +1790,95 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
NF = MapSF(FI).Face(); NF = MapSF(FI).Face();
if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));} if (MES.IsBound(NF)) {
NF = TopoDS::Face(MES(NF));
}
//
TopTools_MapOfShape View; TopTools_MapOfShape View;
for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) { TopTools_IndexedMapOfShape VEmap;
const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current()); Standard_Integer i, aNb;
if (View.Add(EI)) { //
if (Build.IsBound(EI)) { TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
NE = Build(EI); TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
if (NE.ShapeType() == TopAbs_EDGE) { //
if (anOrigins.Contains(NE)) { aNb = VEmap.Extent();
anOrigins.ChangeFromKey(NE).Append(EI); for (i = 1; i <= aNb; ++i) {
} const TopoDS_Shape& aS = VEmap(i);
else { if (!View.Add(aS)) {
TopTools_ListOfShape aLSx; continue;
aLSx.Append(EI); }
anOrigins.Add(NE, aLSx); //
} if (Build.IsBound(aS)) {
// NE = Build(aS);
if (NewEdges.Add(NE)) { if (NE.ShapeType() == TopAbs_EDGE) {
TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes); if (anOrigins.Contains(NE)) {
} anOrigins.ChangeFromKey(NE).Append(aS);
} }
else { else {
//------------------------------------------------------------ TopTools_ListOfShape aLSx;
// The Intersections are on several edges. aLSx.Append(aS);
// The pieces without intersections with neighbors anOrigins.Add(NE, aLSx);
// are removed from AsDes. }
//------------------------------------------------------------ //
for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { if (NewEdges.Add(NE)) {
TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);
if (NewEdges.Add(NEC)) { }
NEC.Free(Standard_True); }
if (anOrigins.Contains(NEC)) { else {
anOrigins.ChangeFromKey(NEC).Append(EI); //------------------------------------------------------------
} // The Intersections are on several edges.
else { // The pieces without intersections with neighbors
TopTools_ListOfShape aLSx; // are removed from AsDes.
aLSx.Append(EI); //------------------------------------------------------------
anOrigins.Add(NEC, aLSx); for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
} TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
// if (NewEdges.Add(NEC)) {
if (!AsDes2d->Descendant(NEC).IsEmpty()) { NEC.Free(Standard_True);
TrimEdge (NEC,AsDes2d,AsDes); if (anOrigins.Contains(NEC)) {
} anOrigins.ChangeFromKey(NEC).Append(aS);
else { }
else {
TopTools_ListOfShape aLSx;
aLSx.Append(aS);
anOrigins.Add(NEC, aLSx);
}
//
if (!AsDes2d->Descendant(NEC).IsEmpty()) {
TrimEdge (NEC,AsDes2d,AsDes);
}
else {
if (AsDes->HasAscendant(NEC)) {
AsDes->Remove(NEC); AsDes->Remove(NEC);
} }
} }
} }
} }
} }
else {
NE = MapSF(FI).Generated(EI);
//// modified by jgv, 19.12.03 for OCC4455 ////
NE.Orientation( EI.Orientation() );
if (anOrigins.Contains(NE)) {
anOrigins.ChangeFromKey(NE).Append(EI);
}
else {
TopTools_ListOfShape aLSx;
aLSx.Append(EI);
anOrigins.Add(NE, aLSx);
}
///////////////////////////////////////////////
if (MES.IsBound(NE)) {
NE = MES(NE);
NE.Orientation(EI.Orientation());
if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
}
AsDes->Add(NF,NE);
}
} }
else {
if (aS.ShapeType() != TopAbs_EDGE) {
continue;
}
//
NE = MapSF(FI).Generated(aS);
//// modified by jgv, 19.12.03 for OCC4455 ////
NE.Orientation(aS.Orientation());
if (anOrigins.Contains(NE)) {
anOrigins.ChangeFromKey(NE).Append(aS);
}
else {
TopTools_ListOfShape aLSx;
aLSx.Append(aS);
anOrigins.Add(NE, aLSx);
}
//
if (MES.IsBound(NE)) {
NE = MES(NE);
NE.Orientation(aS.Orientation());
if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
}
AsDes->Add(NF,NE);
}
} }
} }
@@ -3558,96 +3704,149 @@ void BRepOffset_MakeOffset::MakeShells()
} }
}*/ }*/
// //
Standard_Boolean bFaces = !myFaces.IsEmpty();
//
if ((myJoin == GeomAbs_Intersection) && myInter) { if ((myJoin == GeomAbs_Intersection) && myInter) {
Standard_Integer i, aNb; Standard_Integer i, aNb;
TopTools_ListIteratorOfListOfShape aItLS, aItLS1; TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
BRep_Builder aBB;
//
TopoDS_Compound aCSF;
aBB.MakeCompound(aCSF);
// //
BOPAlgo_Builder aGF; BOPAlgo_Builder aGF;
// //
aGF.SetArguments(aLSF); aGF.SetArguments(aLSF);
aGF.Perform(); aGF.Perform();
if (aGF.ErrorStatus() == 0) { bDone = (aGF.ErrorStatus() == 0);
if (bDone) {
const TopoDS_Shape& aR = aGF.Shape(); const TopoDS_Shape& aR = aGF.Shape();
TopExp_Explorer aExp(aR, TopAbs_FACE); TopExp_Explorer aExp(aR, TopAbs_FACE);
aLSF.Clear(); aLSF.Clear();
for (; aExp.More(); aExp.Next()) { for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aF = aExp.Current(); const TopoDS_Shape& aF = aExp.Current();
aLSF.Append(aF); aLSF.Append(aF);
aBB.Add(aCSF, aF);
} }
// //
UpdateOrigins(anOrigins, aGF); bDone = (myOffset > 0);
}
//
if (myFaces.IsEmpty()) {
BOPAlgo_MakerVolume aMV1;
//
aMV1.SetArguments(aLSF);
aMV1.SetIntersect(Standard_False);
//
aMV1.Perform();
bDone = (aMV1.ErrorStatus() == 0);
if (bDone) { if (bDone) {
TopoDS_Compound aShells; UpdateOrigins(anOrigins, aGF);
BRep_Builder aBB;
// //
aBB.MakeCompound(aShells); BOPAlgo_MakerVolume aMV1;
// //
TopoDS_Shape aResult = aMV1.Shape(); aMV1.AddArgument(aCSF);
if (aResult.ShapeType() == TopAbs_COMPOUND) { aMV1.SetIntersect(Standard_False);
// collect faces attached to only one solid //
BOPCol_IndexedDataMapOfShapeListOfShape aMFS; if (bFaces) {
BOPCol_ListOfShape aLSF2; aNb = myFaces.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aFEx = myFaces(i);
aMV1.AddArgument(aFEx);
}
aMV1.SetIntersect(Standard_True);
}
//
aMV1.Perform();
bDone = (aMV1.ErrorStatus() == 0);
if (bDone) {
TopoDS_Compound aShells;
// //
BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS); aBB.MakeCompound(aShells);
aNb = aMFS.Extent();
bDone = (aNb > 0);
// //
if (bDone) { TopoDS_Shape aResult = aMV1.Shape();
for (i = 1; i <= aNb; ++i) { //
const TopoDS_Shape& aFx = aMFS.FindKey(i); // collect images of the faces
const BOPCol_ListOfShape& aLSx = aMFS(i); TopTools_MapOfShape aMFaces;
if (aLSx.Extent() == 1) { aNb = myFaces.Extent();
// check orientation for (i = 1; i <= aNb; ++i) {
const TopoDS_Face& aF = *(TopoDS_Face*)&aFx; const TopoDS_Shape& aFEx = myFaces(i);
if (!anOrigins.Contains(aF)) { const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx);
aLSF2.Append(aFx); if (!aLFEx.IsEmpty()) {
continue; aItLS.Initialize(aLFEx);
} for (; aItLS.More(); aItLS.Next()) {
// const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value();
const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx); aMFaces.Add(aFExIm);
aItLS.Initialize(aLFOr); }
for (; aItLS.More(); aItLS.Next()) { }
const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); else {
// aMFaces.Add(aFEx);
if (CheckNormals(aF, aFOr)) { }
}
//
if (aResult.ShapeType() == TopAbs_COMPOUND) {
// collect faces attached to only one solid
BOPCol_IndexedDataMapOfShapeListOfShape aMFS;
BOPCol_ListOfShape aLSF2;
//
BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS);
aNb = aMFS.Extent();
bDone = (aNb > 0);
//
if (bDone) {
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aFx = aMFS.FindKey(i);
const BOPCol_ListOfShape& aLSx = aMFS(i);
if (aLSx.Extent() == 1) {
// check orientation
const TopoDS_Face& aF = *(TopoDS_Face*)&aFx;
if (!anOrigins.Contains(aF)) {
aLSF2.Append(aFx); aLSF2.Append(aFx);
break; continue;
}
//
const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx);
aItLS.Initialize(aLFOr);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
//
if (CheckNormals(aF, aFOr)) {
aLSF2.Append(aFx);
break;
}
} }
} }
} }
} //
// // make solid containing most outer faces
// make solid containing most outer faces BOPAlgo_MakerVolume aMV2;
BOPAlgo_MakerVolume aMV2; //
// aMV2.SetArguments(aLSF2);
aMV2.SetArguments(aLSF2); aMV2.SetIntersect(Standard_False);
aMV2.SetIntersect(Standard_False); //
// aMV2.Perform();
aMV2.Perform(); bDone = (aMV2.ErrorStatus() == 0);
bDone = (aMV2.ErrorStatus() == 0); if (bDone) {
if (bDone) { aResult = aMV2.Shape();
aResult = aMV2.Shape(); }
} }
} }
//
TopExp_Explorer aExp(aResult, TopAbs_SHELL);
bDone = aExp.More();
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shell& aSh = *(TopoDS_Shell*)&aExp.Current();
//
TopoDS_Shell aShellNew;
if (bFaces) {
aBB.MakeShell(aShellNew);
//
TopExp_Explorer aExp(aSh, TopAbs_FACE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Face& aFSh = *(TopoDS_Face*)&aExp.Current();
if (!aMFaces.Contains(aFSh)) {
aBB.Add(aShellNew, aFSh);
}
}
}
else {
aShellNew = aSh;
}
//
aBB.Add(aShells, aShellNew);
}
myOffsetShape = aShells;
} }
//
TopExp_Explorer aExp(aResult, TopAbs_SHELL);
bDone = aExp.More();
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aSh = aExp.Current();
aBB.Add(aShells, aSh);
}
myOffsetShape = aShells;
} }
} }
} }