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

@@ -48,6 +48,7 @@ is
MES : in out DataMapOfShapeShape from TopTools;
Build : DataMapOfShapeShape from TopTools;
AsDes : AsDes from BRepAlgo;
AsDes2d : AsDes from BRepAlgo;
Offset : Real from Standard;
Tol : Real from Standard);
-- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End

View File

@@ -805,7 +805,6 @@ static void RefEdgeInter(const TopoDS_Face& F,
}
}
//======================================================================
//function : EvaluateMaxSegment
//purpose : return MaxSegment to pass in approximation
@@ -1466,6 +1465,7 @@ void BRepOffset_Inter2d::ConnexIntByInt
TopTools_DataMapOfShapeShape& MES,
const TopTools_DataMapOfShapeShape& Build,
const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset,
const Standard_Real Tol)
// Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
@@ -1506,7 +1506,15 @@ void BRepOffset_Inter2d::ConnexIntByInt
TopoDS_Face FIO = TopoDS::Face(OFI.Face());
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);
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 (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
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)) {
TopoDS_Vertex V = CommonVertex(CEO,NEO);
UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
AsDes->Add (MES(CEO),V);
AsDes2d->Add (MES(CEO),V);
}
else if (MES.IsBound(NEO)) {
TopoDS_Vertex V = CommonVertex(CEO,NEO);
UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
AsDes->Add (MES(NEO),V);
AsDes2d->Add (MES(NEO),V);
}
}
CurE = NextE;
}
}
}

View File

@@ -40,6 +40,7 @@
#include <Extrema_ExtPC.hxx>
#include <TopTools_MapOfShape.hxx>
#include <Precision.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
@@ -97,109 +98,52 @@ static void ExtentEdge(const TopoDS_Face& /*F*/,
//function : SelectEdge
//purpose :
//=======================================================================
static void SelectEdge (const TopoDS_Face& /*F*/,
const TopoDS_Face& /*EF*/,
const TopoDS_Edge& E,
TopTools_ListOfShape& LInt)
static void SelectEdge (const TopoDS_Shape& theS,
TopTools_ListOfShape& theLE)
{
//------------------------------------------------------------
// Proofing on the intersections on periodical faces
//------------------------------------------------------------
TopTools_ListIteratorOfListOfShape it(LInt);
// Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin
// Standard_Real dU = 1.0e100;
Standard_Real dU = RealLast();
// Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End
TopoDS_Edge GE;
Standard_Real Fst, Lst, tmp;
BRep_Tool::Range(E, Fst, Lst);
BRepAdaptor_Curve Ad1(E);
gp_Pnt PFirst = Ad1.Value( Fst );
gp_Pnt PLast = Ad1.Value( Lst );
// Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin
Extrema_ExtPC anExt;
// Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End
//----------------------------------------------------------------------
// Selection of edge that coversmost of the domain of the initial edge.
//----------------------------------------------------------------------
for (; it.More(); it.Next()) {
const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
BRep_Tool::Range(EI, Fst, Lst);
BRepAdaptor_Curve Ad2(EI);
// Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin
Standard_Integer i;
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;
Standard_Real aT1, aT2, aDist, aDistMin;
TopExp_Explorer aExp;
TopTools_ListIteratorOfListOfShape aIt;
GeomAPI_ProjectPointOnCurve aProjPC;
gp_Pnt aPE1, aPE2;
TopoDS_Edge aRE;
//
aDistMin = RealLast();
//
aIt.Initialize(theLE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Edge& aE = *(TopoDS_Edge*)&aIt.Value();
//
const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2);
//
aProjPC.Init(aC, aT1, aT2);
aPE1 = aC->Value(aT1);
aPE2 = aC->Value(aT2);
//
aDist = 0.;
aExp.Init(theS, TopAbs_VERTEX);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExp.Current();
const gp_Pnt aP = BRep_Tool::Pnt(aV);
//
aProjPC.Perform(aP);
if (aProjPC.NbPoints()) {
aDist += aProjPC.LowerDistance();
}
else {
aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2));
}
}
}
if (!isMinFound) {
gp_Pnt aP1 = Ad2.Value(Fst);
gp_Pnt aP2 = Ad2.Value(Lst);
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 (aDist < aDistMin) {
aDistMin = aDist;
aRE = aE;
}
}
//
theLE.Clear();
theLE.Append(aRE);
}
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);
}
//=======================================================================
//function : CompletInt
@@ -482,31 +426,120 @@ void BRepOffset_Inter3d::ConnexIntByInt
TopTools_ListOfShape& Failed)
{
//TopExp_Explorer Exp(SI,TopAbs_EDGE);
TopTools_IndexedMapOfShape Emap;
TopExp::MapShapes( SI, TopAbs_EDGE, Emap );
TopTools_IndexedMapOfShape VEmap;
TopTools_IndexedDataMapOfShapeListOfShape aMVF;
TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
TopAbs_State CurSide = mySide;
BRep_Builder B;
TopTools_ListIteratorOfListOfShape it;
//for (; Exp.More(); Exp.Next()) {
for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
//const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
const TopoDS_Edge& E = TopoDS::Edge(Emap(i));
Standard_Boolean bEdge;
Standard_Integer i, aNb;
TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
//
TopExp::MapShapes(SI, TopAbs_EDGE , VEmap);
TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
//
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()) {
if (L.IsEmpty()) {
continue;
}
//
BRepOffset_Type OT = L.First().Type();
if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) {
if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
continue;
}
//
if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
else CurSide = TopAbs_OUT;
//-----------------------------------------------------------
// edge is of the proper type, return adjacent faces.
//-----------------------------------------------------------
const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
if (Anc.Extent() != 2) continue;
if (Anc.Extent() != 2) {
continue;
}
//
F1 = TopoDS::Face(Anc.First());
F2 = TopoDS::Face(Anc.Last ());
OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face());
//
aLF1.Append(F1);
aLF2.Append(F2);
}
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;
@@ -517,6 +550,7 @@ void BRepOffset_Inter3d::ConnexIntByInt
else {
NF1 = TopoDS::Face(MES(OF1));
}
//
if (!MES.IsBound(OF2)) {
Standard_Boolean enlargeU = Standard_True;
Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
@@ -527,27 +561,41 @@ void BRepOffset_Inter3d::ConnexIntByInt
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)
{
BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge);
if (LInt1.Extent() > 1) {
// intersection is in seceral edges (free sewing)
SelectEdge( NF1, NF2, E, LInt1 );
SelectEdge( NF1, NF2, E, LInt2 );
SelectEdge(aS, LInt1);
SelectEdge(aS, 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());
//
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);
}
Build.Bind(E,C);
}
//
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(E);
Failed.Append(aS);
}
} else { // IsDone(NF1,NF2)
// Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
@@ -556,31 +604,37 @@ void BRepOffset_Inter3d::ConnexIntByInt
if (!aLInt1.IsEmpty()) {
TopoDS_Compound C;
TopTools_ListIteratorOfListOfShape anIt2;
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 (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) {
const TopoDS_Shape &anE2 = anIt2.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(E,C);
Build.Bind(aS,C);
}
else {
Failed.Append(E);
Failed.Append(aS);
}
}
}
// Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
}
}
}
}
//=======================================================================
//function : ContextIntByInt
@@ -603,10 +657,12 @@ void BRepOffset_Inter3d::ContextIntByInt
TopoDS_Edge OE;
TopoDS_Compound C;
BRep_Builder B;
TopTools_ListIteratorOfListOfShape it;
Standard_Integer i;
TopTools_ListIteratorOfListOfShape it, itF;
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));
myTouched.Add(CF);
if (ExtentContext) {
@@ -616,14 +672,28 @@ void BRepOffset_Inter3d::ContextIntByInt
}
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));
if (ExtentContext) WCF = TopoDS::Face(MES(CF));
else WCF = CF;
for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
exp.More(); exp.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
TopTools_IndexedMapOfShape VEmap;
TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
//
aNbVE = VEmap.Extent();
for (j = 1; j <= aNbVE; ++j) {
const TopoDS_Shape& aS = VEmap(j);
//
bEdge = (aS.ShapeType() == TopAbs_EDGE);
//
TopoDS_Edge E;
TopTools_ListOfShape Anc;
//
if (bEdge) {
// faces connected by the edge
//
E = *(TopoDS_Edge*)&aS;
if (!Analyse.HasAncestor(E)) {
//----------------------------------------------------------------
// the edges of faces of context that are not in the initial shape
@@ -665,8 +735,48 @@ void BRepOffset_Inter3d::ContextIntByInt
}
continue;
}
const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
const TopoDS_Face& F = TopoDS::Face(Anc.First());
Anc = Analyse.Ancestors(E);
}
else {
// faces connected by the vertex
//
if (!Analyse.HasAncestor(aS)) {
continue;
}
//
const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS);
it.Initialize(aLE);
for (; it.More(); it.Next()) {
const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value();
//
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
if (VEmap.Contains(aE)) {
continue;
}
//
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);
}
}
}
}
//
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);
@@ -682,23 +792,33 @@ void BRepOffset_Inter3d::ContextIntByInt
TopTools_ListOfShape LInt1,LInt2;
TopTools_ListOfShape LOE;
LOE.Append(OE);
BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True);
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.Bind(E,LInt1.First());
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(E,C);
Build.Bind(aS,C);
}
}
else {
Failed.Append(E);
Failed.Append(aS);
}
}
}
}

View File

@@ -901,7 +901,9 @@ static void TrimEdge (TopoDS_Edge& NE,
Standard_Real UMax = -UMin;
const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
//
Standard_Boolean bTrim = Standard_False;
//
if (LE.Extent() > 1) {
TopTools_ListIteratorOfListOfShape it (LE);
for (; it.More(); it.Next()) {
@@ -909,8 +911,7 @@ static void TrimEdge (TopoDS_Edge& NE,
if (NE.Orientation() == TopAbs_REVERSED)
V.Reverse();
//V.Orientation(TopAbs_INTERNAL);
if (!FindParameter(V, NE, U))
{
if (!FindParameter(V, NE, U)) {
Standard_Real f, l;
Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
gp_Pnt thePoint = BRep_Tool::Pnt(V);
@@ -926,6 +927,7 @@ static void TrimEdge (TopoDS_Edge& NE,
UMax = U; V2 = V;
}
}
//
if (V1.IsNull() || V2.IsNull()) {
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,V2.Oriented(TopAbs_REVERSED));
BRepLib::SameParameter(NE, aSameParTol, Standard_True);
//
bTrim = Standard_True;
}
}
//
if (!bTrim) {
if (!BRep_Tool::Degenerated(NE)) {
BRepAdaptor_Curve aBAC(NE);
if (!aBAC.IsClosed()) {
if (AsDes->HasAscendant(NE)) {
AsDes->Remove(NE);
}
}
}
}
}
@@ -961,6 +976,10 @@ static void TrimEdge (TopoDS_Edge& NE,
#include <BOPDS_VectorOfInterfVE.hxx>
#include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPTools_AlgoTools3D.hxx>
#include <IntTools_Context.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <CPnts_AbscissaPoint.hxx>
#include <IntTools_ShrunkRange.hxx>
//=======================================================================
//function : SortFaces
@@ -1032,7 +1051,7 @@ static void SortFaces(const TopTools_ListOfShape& theLIm,
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);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
@@ -1044,8 +1063,7 @@ static void SortFaces(const TopTools_ListOfShape& theLIm,
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aE, aV1, aV2);
//
bFlag = aMV.Contains(aV1) ||
aMV.Contains(aV2);
bFlag = aMV.Contains(aV1) || 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
//purpose :
@@ -1208,8 +1284,15 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
BOPCol_ListIteratorOfListOfShape aIt;
TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1;
TopTools_DataMapOfShapeListOfShape anEImages;
BRep_Builder aBB;
TopoDS_Compound aFaces;
//
aBB.MakeCompound(aFaces);
//
// firstly it is necessary to fuse all the edges
Standard_Real aFuzz = 0.;
Handle(IntTools_Context) aCtx = new IntTools_Context();
//
aItLF.Initialize(theLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aF = aItLF.Value();
@@ -1221,20 +1304,21 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
if (IsMicroEdge(aE, aCtx, aFuzz)) {
continue;
}
//
aLS.Append(aE);
}
}
//
if (aLS.Extent() > 1) {
BOPAlgo_PaveFiller aPF;
//
aPF.SetArguments(aLS);
aPF.Perform();
if (aPF.ErrorStatus() == 0) {
BOPAlgo_Builder aGFE;
//
aGFE.SetArguments(aLS);
aGFE.PerformWithFiller(aPF);
aGFE.SetFuzzyValue(aFuzz);
aGFE.Perform();
if (aGFE.ErrorStatus() == 0) {
// fill map with edges images
aIt.Initialize(aLS);
@@ -1250,12 +1334,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
UpdateOrigins(theOrigins, aGFE);
}
}
}
//
// now we can split the faces
aItLF.Initialize(theLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aF = aItLF.Value();
const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value();
//
// the offset face
aLS.Clear();
@@ -1279,6 +1362,7 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
}
}
//
aFuzz = 0.;
// the edges by which the offset face should be split
const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF);
aItLE.Initialize(aLE);
@@ -1292,7 +1376,12 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
const TopTools_ListOfShape& aLEIm = anEImages.Find(aE);
aItLE1.Initialize(aLEIm);
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);
if (!aMFE.Contains(aEIm)) {
++iCountE;
@@ -1300,6 +1389,9 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
}
}
else {
if (IsMicroEdge(aE, aCtx, aFuzz)) {
continue;
}
aLS.Append(aE);
if (!aMFE.Contains(aE)) {
++iCountE;
@@ -1313,12 +1405,14 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
if (!iCountE) {
aLFImages.Append(aF);
theImage.Bind(aF, aLFImages);
aBB.Add(aFaces, aF);
continue;
}
//
BOPAlgo_Builder aGF;
//
aGF.SetArguments(aLS);
aGF.SetFuzzyValue(aFuzz);
aGF.Perform();
if (aGF.ErrorStatus()) {
theLFailed.Append(aF);
@@ -1397,6 +1491,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
aExp.Init(aFIm, TopAbs_EDGE);
for (bKeep = Standard_True; aExp.More() && bKeep; aExp.Next()) {
const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
//
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
bKeep = aME.Contains(aE);
}
//
@@ -1431,11 +1530,20 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
//
if (BRep_Tool::Degenerated(aEIm)) {
continue;
}
//
if (!theOrigins.Contains(aEIm)) {
continue;
}
//
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) {
TopTools_MapOfShape aME, aMV;
@@ -1494,11 +1602,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
}
}
//
if (bRem) {
if (bRem && !bKeep) {
aLFImages.Remove(aItLE);
}
else {
if (bKeep) {
if (!bRem && bKeep) {
aLFKeep.Append(aFIm);
}
aItLE.Next();
@@ -1531,20 +1639,41 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
theImage.Bind(aF, aLFImages);
}
else {
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
TopTools_IndexedMapOfShape aMFE;
TopExp::MapShapes(aFaces, TopAbs_EDGE, aMFE);
//
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages);
for (; aItEIm.More(); aItEIm.Next()) {
const TopoDS_Shape& aE = aItEIm.Key();
const TopTools_ListOfShape& aLEIm = aItEIm.Value();
if (theImage.HasImage(aE)) {
theImage.Add(aE, aLEIm);
//
Standard_Boolean bHasImage = theImage.HasImage(aE);
aItLE.Initialize(aLEIm);
for (; aItLE.More(); aItLE.Next()) {
const TopoDS_Shape& aEIm = aItLE.Value();
if (aMFE.Contains(aEIm)) {
if (bHasImage) {
theImage.Add(aE, aEIm);
}
else {
theImage.Bind(aE, aLEIm);
theImage.Bind(aE, aEIm);
bHasImage = Standard_True;
}
}
}
}
}
@@ -1645,7 +1774,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,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
}
//-----------------------------------------------------------
@@ -1661,20 +1790,33 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
NF = MapSF(FI).Face();
if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));}
if (MES.IsBound(NF)) {
NF = TopoDS::Face(MES(NF));
}
//
TopTools_MapOfShape View;
for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current());
if (View.Add(EI)) {
if (Build.IsBound(EI)) {
NE = Build(EI);
TopTools_IndexedMapOfShape VEmap;
Standard_Integer i, aNb;
//
TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
//
aNb = VEmap.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aS = VEmap(i);
if (!View.Add(aS)) {
continue;
}
//
if (Build.IsBound(aS)) {
NE = Build(aS);
if (NE.ShapeType() == TopAbs_EDGE) {
if (anOrigins.Contains(NE)) {
anOrigins.ChangeFromKey(NE).Append(EI);
anOrigins.ChangeFromKey(NE).Append(aS);
}
else {
TopTools_ListOfShape aLSx;
aLSx.Append(EI);
aLSx.Append(aS);
anOrigins.Add(NE, aLSx);
}
//
@@ -1693,11 +1835,11 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
if (NewEdges.Add(NEC)) {
NEC.Free(Standard_True);
if (anOrigins.Contains(NEC)) {
anOrigins.ChangeFromKey(NEC).Append(EI);
anOrigins.ChangeFromKey(NEC).Append(aS);
}
else {
TopTools_ListOfShape aLSx;
aLSx.Append(EI);
aLSx.Append(aS);
anOrigins.Add(NEC, aLSx);
}
//
@@ -1705,36 +1847,40 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
TrimEdge (NEC,AsDes2d,AsDes);
}
else {
if (AsDes->HasAscendant(NEC)) {
AsDes->Remove(NEC);
}
}
}
}
}
}
else {
NE = MapSF(FI).Generated(EI);
if (aS.ShapeType() != TopAbs_EDGE) {
continue;
}
//
NE = MapSF(FI).Generated(aS);
//// modified by jgv, 19.12.03 for OCC4455 ////
NE.Orientation( EI.Orientation() );
NE.Orientation(aS.Orientation());
if (anOrigins.Contains(NE)) {
anOrigins.ChangeFromKey(NE).Append(EI);
anOrigins.ChangeFromKey(NE).Append(aS);
}
else {
TopTools_ListOfShape aLSx;
aLSx.Append(EI);
aLSx.Append(aS);
anOrigins.Add(NE, aLSx);
}
///////////////////////////////////////////////
//
if (MES.IsBound(NE)) {
NE = MES(NE);
NE.Orientation(EI.Orientation());
NE.Orientation(aS.Orientation());
if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
}
AsDes->Add(NF,NE);
}
}
}
}
//---------------------------------
// Intersection 2D on //
@@ -3558,41 +3704,76 @@ void BRepOffset_MakeOffset::MakeShells()
}
}*/
//
Standard_Boolean bFaces = !myFaces.IsEmpty();
//
if ((myJoin == GeomAbs_Intersection) && myInter) {
Standard_Integer i, aNb;
TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
BRep_Builder aBB;
//
TopoDS_Compound aCSF;
aBB.MakeCompound(aCSF);
//
BOPAlgo_Builder aGF;
//
aGF.SetArguments(aLSF);
aGF.Perform();
if (aGF.ErrorStatus() == 0) {
bDone = (aGF.ErrorStatus() == 0);
if (bDone) {
const TopoDS_Shape& aR = aGF.Shape();
TopExp_Explorer aExp(aR, TopAbs_FACE);
aLSF.Clear();
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aF = aExp.Current();
aLSF.Append(aF);
aBB.Add(aCSF, aF);
}
//
bDone = (myOffset > 0);
if (bDone) {
UpdateOrigins(anOrigins, aGF);
}
//
if (myFaces.IsEmpty()) {
BOPAlgo_MakerVolume aMV1;
//
aMV1.SetArguments(aLSF);
aMV1.AddArgument(aCSF);
aMV1.SetIntersect(Standard_False);
//
if (bFaces) {
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;
BRep_Builder aBB;
//
aBB.MakeCompound(aShells);
//
TopoDS_Shape aResult = aMV1.Shape();
//
// collect images of the faces
TopTools_MapOfShape aMFaces;
aNb = myFaces.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aFEx = myFaces(i);
const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx);
if (!aLFEx.IsEmpty()) {
aItLS.Initialize(aLFEx);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value();
aMFaces.Add(aFExIm);
}
}
else {
aMFaces.Add(aFEx);
}
}
//
if (aResult.ShapeType() == TopAbs_COMPOUND) {
// collect faces attached to only one solid
BOPCol_IndexedDataMapOfShapeListOfShape aMFS;
@@ -3644,13 +3825,31 @@ void BRepOffset_MakeOffset::MakeShells()
TopExp_Explorer aExp(aResult, TopAbs_SHELL);
bDone = aExp.More();
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aSh = aExp.Current();
aBB.Add(aShells, aSh);
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;
}
}
}
}
//
if (!bDone) {
BRepTools_Quilt Glue;