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

0031148: Modeling Algorithms - Offset adjacent co-planar faces with different offset values

Extend the Offset operation (Join Type "Intersection", mode "Complete") to allow different offset values on adjacent co-planar faces.
The gap between adjacent faces is closed by creating artificial face perpendicular to the face.

Adding test cases.
This commit is contained in:
emv
2019-10-11 07:23:19 +03:00
committed by bugmaster
parent 34e7ac6817
commit 420b38fde9
63 changed files with 3050 additions and 369 deletions

View File

@@ -309,3 +309,55 @@ void BRepAlgo_Image::Filter(const TopoDS_Shape& S,
}
//=======================================================================
//function : RemoveRoot
//purpose :
//=======================================================================
void BRepAlgo_Image::RemoveRoot (const TopoDS_Shape& Root)
{
Standard_Boolean isRemoved = Standard_False;
for (TopTools_ListOfShape::Iterator it (roots); it.More(); it.Next())
{
if (Root.IsSame (it.Value()))
{
roots.Remove (it);
isRemoved = Standard_True;
break;
}
}
if (!isRemoved)
return;
const TopTools_ListOfShape* pNewS = down.Seek (Root);
if (pNewS)
{
for (TopTools_ListOfShape::Iterator it (*pNewS); it.More(); it.Next())
{
const TopoDS_Shape *pOldS = up.Seek (it.Value());
if (pOldS && pOldS->IsSame (Root))
up.UnBind (it.Value());
}
down.UnBind (Root);
}
}
//=======================================================================
//function : ReplaceRoot
//purpose :
//=======================================================================
void BRepAlgo_Image::ReplaceRoot (const TopoDS_Shape& OldRoot,
const TopoDS_Shape& NewRoot)
{
if (!HasImage (OldRoot))
return;
const TopTools_ListOfShape& aLImage = Image (OldRoot);
if (HasImage (NewRoot))
Add (NewRoot, aLImage);
else
Bind (NewRoot, aLImage);
SetRoot (NewRoot);
RemoveRoot (OldRoot);
}

View File

@@ -60,6 +60,14 @@ public:
//! Remove <S> to set of images.
Standard_EXPORT void Remove (const TopoDS_Shape& S);
//! Removes the root <theRoot> from the list of roots and up and down maps.
Standard_EXPORT void RemoveRoot (const TopoDS_Shape& Root);
//! Replaces the <OldRoot> with the <NewRoot>, so all images
//! of the <OldRoot> become the images of the <NewRoot>.
//! The <OldRoot> is removed.
Standard_EXPORT void ReplaceRoot (const TopoDS_Shape& OldRoot, const TopoDS_Shape& NewRoot);
Standard_EXPORT const TopTools_ListOfShape& Roots() const;
Standard_EXPORT Standard_Boolean IsImage (const TopoDS_Shape& S) const;

View File

@@ -16,6 +16,8 @@
#include <Adaptor3d_Surface.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
@@ -24,6 +26,7 @@
#include <BRepOffset_Interval.hxx>
#include <BRepOffset_ListIteratorOfListOfInterval.hxx>
#include <BRepOffset_Tool.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepTools.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Curve.hxx>
@@ -33,6 +36,7 @@
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <IntTools_Context.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
@@ -60,19 +64,17 @@ static void CorrectOrientationOfTangent(gp_Vec& TangVec,
//=======================================================================
BRepOffset_Analyse::BRepOffset_Analyse()
:myDone(Standard_False)
: myOffset (0.0), myDone (Standard_False)
{
}
//=======================================================================
//function : BRepOffset_Analyse
//purpose :
//=======================================================================
BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S,
const Standard_Real Angle)
:myDone(Standard_False)
const Standard_Real Angle)
: myOffset (0.0), myDone (Standard_False)
{
Perform( S, Angle);
}
@@ -81,7 +83,6 @@ BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S,
//function : EdgeAnlyse
//purpose :
//=======================================================================
static void EdgeAnalyse(const TopoDS_Edge& E,
const TopoDS_Face& F1,
const TopoDS_Face& F2,
@@ -117,7 +118,6 @@ static void EdgeAnalyse(const TopoDS_Edge& E,
//function : BuildAncestors
//purpose :
//=======================================================================
static void BuildAncestors (const TopoDS_Shape& S,
TopTools_IndexedDataMapOfShapeListOfShape& MA)
{
@@ -126,60 +126,58 @@ static void BuildAncestors (const TopoDS_Shape& S,
TopExp::MapShapesAndUniqueAncestors(S,TopAbs_EDGE ,TopAbs_FACE,MA);
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean BRepOffset_Analyse::IsDone() const
{
return myDone;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
const Standard_Real Angle)
const Standard_Real Angle)
{
myShape = S;
myNewFaces .Clear();
myGenerated.Clear();
myReplacement.Clear();
myDescendants.Clear();
angle = Angle;
Standard_Real SinTol = Sin(Angle);
myAngle = Angle;
Standard_Real SinTol = Abs (Sin(Angle));
// Build ancestors.
BuildAncestors (S,ancestors);
BuildAncestors (S,myAncestors);
TopTools_ListOfShape aLETang;
TopExp_Explorer Exp(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
for ( ; Exp.More(); Exp.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
if (!mapEdgeType.IsBound(E)) {
if (!myMapEdgeType.IsBound(E)) {
BRepOffset_ListOfInterval LI;
mapEdgeType.Bind(E,LI);
myMapEdgeType.Bind(E,LI);
const TopTools_ListOfShape& L = Ancestors(E);
if ( L.IsEmpty())
continue;
continue;
if (L.Extent() == 2) {
const TopoDS_Face& F1 = TopoDS::Face(L.First());
const TopoDS_Face& F2 = TopoDS::Face(L.Last ());
EdgeAnalyse(E,F1,F2,SinTol,mapEdgeType(E));
const TopoDS_Face& F1 = TopoDS::Face (L.First());
const TopoDS_Face& F2 = TopoDS::Face (L.Last());
EdgeAnalyse (E, F1, F2, SinTol, myMapEdgeType (E));
// For tangent faces add artificial perpendicular face
// to close the gap between them (if they have different offset values)
if (myMapEdgeType(E).Last().Type() == ChFiDS_Tangential)
aLETang.Append (E);
}
else if (L.Extent() == 1) {
Standard_Real U1,U2;
const TopoDS_Face& F = TopoDS::Face(L.First());
BRep_Tool::Range(E,F,U1,U2);
BRepOffset_Interval Inter(U1,U2,ChFiDS_Other);
if (! BRepTools::IsReallyClosed(E,F)) {
Inter.Type(ChFiDS_FreeBound);
}
mapEdgeType(E).Append(Inter);
Standard_Real U1, U2;
const TopoDS_Face& F = TopoDS::Face (L.First());
BRep_Tool::Range (E, F, U1, U2);
BRepOffset_Interval Inter (U1, U2, ChFiDS_Other);
if (!BRepTools::IsReallyClosed (E, F)) {
Inter.Type (ChFiDS_FreeBound);
}
myMapEdgeType (E).Append (Inter);
}
else {
#ifdef OCCT_DEBUG
@@ -188,47 +186,472 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
}
}
}
TreatTangentFaces (aLETang);
myDone = Standard_True;
}
//=======================================================================
//function : Generated
//purpose :
//=======================================================================
void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
{
if (theLE.IsEmpty() || myFaceOffsetMap.IsEmpty())
{
// Noting to do: either there are no tangent faces in the shape or
// the face offset map has not been provided
return;
}
// Select the edges which connect faces with different offset values
TopoDS_Compound aCETangent;
BRep_Builder().MakeCompound (aCETangent);
// Bind to each tangent edge a max offset value of its faces
TopTools_DataMapOfShapeReal anEdgeOffsetMap;
// Bind vertices of the tangent edges with connected edges
// of the face with smaller offset value
TopTools_DataMapOfShapeShape aDMVEMin;
for (TopTools_ListOfShape::Iterator it (theLE); it.More(); it.Next())
{
const TopoDS_Shape& aE = it.Value();
const TopTools_ListOfShape& aLA = Ancestors (aE);
const TopoDS_Shape& aF1 = aLA.First(), aF2 = aLA.Last();
const Standard_Real *pOffsetVal1 = myFaceOffsetMap.Seek (aF1);
const Standard_Real *pOffsetVal2 = myFaceOffsetMap.Seek (aF2);
const Standard_Real anOffsetVal1 = pOffsetVal1 ? Abs (*pOffsetVal1) : myOffset;
const Standard_Real anOffsetVal2 = pOffsetVal2 ? Abs (*pOffsetVal2) : myOffset;
if (anOffsetVal1 != anOffsetVal2)
{
BRep_Builder().Add (aCETangent, aE);
anEdgeOffsetMap.Bind (aE, Max (anOffsetVal1, anOffsetVal2));
const TopoDS_Shape& aFMin = anOffsetVal1 < anOffsetVal2 ? aF1 : aF2;
for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
{
const TopoDS_Shape& aV = itV.Value();
if (Ancestors (aV).Extent() == 3)
{
for (TopExp_Explorer expE (aFMin, TopAbs_EDGE); expE.More(); expE.Next())
{
const TopoDS_Shape& aEMin = expE.Current();
if (aEMin.IsSame (aE))
continue;
for (TopoDS_Iterator itV1 (aEMin); itV1.More(); itV1.Next())
{
const TopoDS_Shape& aVx = itV1.Value();
if (aV.IsSame (aVx))
aDMVEMin.Bind (aV, aEMin);
}
}
}
}
}
}
if (anEdgeOffsetMap.IsEmpty())
return;
// Create map of Face ancestors for the vertices on tangent edges
TopTools_DataMapOfShapeListOfShape aDMVFAnc;
for (TopTools_ListOfShape::Iterator itE (theLE); itE.More(); itE.Next())
{
const TopoDS_Shape& aE = itE.Value();
if (!anEdgeOffsetMap.IsBound (aE))
continue;
TopTools_MapOfShape aMFence;
{
const TopTools_ListOfShape& aLEA = Ancestors (aE);
for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
aMFence.Add (itLEA.Value());
}
for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
{
const TopoDS_Shape& aV = itV.Value();
TopTools_ListOfShape* pLFA = aDMVFAnc.Bound (aV, TopTools_ListOfShape());
const TopTools_ListOfShape& aLVA = Ancestors (aV);
for (TopTools_ListOfShape::Iterator itLVA (aLVA); itLVA.More(); itLVA.Next())
{
const TopoDS_Edge& aEA = TopoDS::Edge (itLVA.Value());
const BRepOffset_ListOfInterval* pIntervals = myMapEdgeType.Seek (aEA);
if (!pIntervals || pIntervals->IsEmpty())
continue;
if (pIntervals->First().Type() == ChFiDS_Tangential)
continue;
const TopTools_ListOfShape& aLEA = Ancestors (aEA);
for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
{
const TopoDS_Shape& aFA = itLEA.Value();
if (aMFence.Add (aFA))
pLFA->Append (aFA);
}
}
}
}
Handle(IntTools_Context) aCtx = new IntTools_Context();
// Tangency criteria
Standard_Real aSinTol = Abs (Sin (myAngle));
// Make blocks of connected edges
TopTools_ListOfListOfShape aLCB;
TopTools_IndexedDataMapOfShapeListOfShape aMVEMap;
BOPTools_AlgoTools::MakeConnexityBlocks (aCETangent, TopAbs_VERTEX, TopAbs_EDGE, aLCB, aMVEMap);
// Analyze each block to find co-planar edges
for (TopTools_ListOfListOfShape::Iterator itLCB (aLCB); itLCB.More(); itLCB.Next())
{
const TopTools_ListOfShape& aCB = itLCB.Value();
TopTools_MapOfShape aMFence;
for (TopTools_ListOfShape::Iterator itCB1 (aCB); itCB1.More(); itCB1.Next())
{
const TopoDS_Edge& aE1 = TopoDS::Edge (itCB1.Value());
if (!aMFence.Add (aE1))
continue;
TopoDS_Compound aBlock;
BRep_Builder().MakeCompound (aBlock);
BRep_Builder().Add (aBlock, aE1.Oriented (TopAbs_FORWARD));
Standard_Real anOffset = anEdgeOffsetMap.Find (aE1);
const TopTools_ListOfShape& aLF1 = Ancestors (aE1);
gp_Dir aDN1;
BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE1, TopoDS::Face (aLF1.First()), aDN1);
TopTools_ListOfShape::Iterator itCB2 = itCB1;
for (itCB2.Next(); itCB2.More(); itCB2.Next())
{
const TopoDS_Edge& aE2 = TopoDS::Edge (itCB2.Value());
if (aMFence.Contains (aE2))
continue;
const TopTools_ListOfShape& aLF2 = Ancestors (aE2);
gp_Dir aDN2;
BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE2, TopoDS::Face (aLF2.First()), aDN2);
if (aDN1.XYZ().Crossed (aDN2.XYZ()).Modulus() < aSinTol)
{
BRep_Builder().Add (aBlock, aE2.Oriented (TopAbs_FORWARD));
aMFence.Add (aE2);
anOffset = Max (anOffset, anEdgeOffsetMap.Find (aE2));
}
}
// Make the prism
BRepPrimAPI_MakePrism aMP (aBlock, gp_Vec (aDN1.XYZ()) * anOffset);
if (!aMP.IsDone())
continue;
TopTools_IndexedDataMapOfShapeListOfShape aPrismAncestors;
TopExp::MapShapesAndAncestors (aMP.Shape(), TopAbs_EDGE, TopAbs_FACE, aPrismAncestors);
TopExp::MapShapesAndAncestors (aMP.Shape(), TopAbs_VERTEX, TopAbs_EDGE, aPrismAncestors);
for (TopoDS_Iterator itE (aBlock); itE.More(); itE.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge (itE.Value());
const TopTools_ListOfShape& aLG = aMP.Generated (aE);
TopoDS_Face aFNew = TopoDS::Face (aLG.First());
TopTools_ListOfShape& aLA = myAncestors.ChangeFromKey (aE);
TopoDS_Shape aF1 = aLA.First();
TopoDS_Shape aF2 = aLA.Last();
const Standard_Real *pOffsetVal1 = myFaceOffsetMap.Seek (aF1);
const Standard_Real *pOffsetVal2 = myFaceOffsetMap.Seek (aF2);
const Standard_Real anOffsetVal1 = pOffsetVal1 ? Abs (*pOffsetVal1) : myOffset;
const Standard_Real anOffsetVal2 = pOffsetVal2 ? Abs (*pOffsetVal2) : myOffset;
const TopoDS_Shape& aFToRemove = anOffsetVal1 > anOffsetVal2 ? aF1 : aF2;
const TopoDS_Shape& aFOpposite = anOffsetVal1 > anOffsetVal2 ? aF2 : aF1;
// Orient the face so its normal is directed to smaller offset face
{
// get normal of the new face
gp_Dir aDN;
BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aFNew, aDN);
// get bi-normal for the aFOpposite
TopoDS_Edge aEInF;
for (TopExp_Explorer aExpE (aFOpposite, TopAbs_EDGE); aExpE.More(); aExpE.Next())
{
if (aE.IsSame (aExpE.Current()))
{
aEInF = TopoDS::Edge (aExpE.Current());
break;
}
}
gp_Pnt2d aP2d;
gp_Pnt aPInF;
Standard_Real f, l;
const Handle(Geom_Curve)& aC3D = BRep_Tool::Curve (aEInF, f, l);
gp_Pnt aPOnE = aC3D->Value ((f + l) / 2.);
BOPTools_AlgoTools3D::PointNearEdge (aEInF, TopoDS::Face (aFOpposite), (f + l) / 2., 1.e-5, aP2d, aPInF);
gp_Vec aBN (aPOnE, aPInF);
if (aBN.Dot (aDN) < 0)
aFNew.Reverse();
}
// Remove the face with bigger offset value from edge ancestors
for (TopTools_ListOfShape::Iterator itA (aLA); itA.More();itA.Next())
{
if (itA.Value().IsSame (aFToRemove))
{
aLA.Remove (itA);
break;
}
}
aLA.Append (aFNew);
myMapEdgeType (aE).Clear();
// Analyze edge again
EdgeAnalyse (aE, TopoDS::Face (aFOpposite), aFNew, aSinTol, myMapEdgeType (aE));
// Analyze vertices
TopTools_MapOfShape aFNewEdgeMap;
aFNewEdgeMap.Add (aE);
for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
{
const TopoDS_Shape& aV = itV.Value();
// Add Side edge to map of Ancestors with the correct orientation
TopoDS_Edge aEG = TopoDS::Edge (aMP.Generated (aV).First());
myGenerated.Bind (aV, aEG);
{
for (TopExp_Explorer anExpEg (aFNew, TopAbs_EDGE); anExpEg.More(); anExpEg.Next())
{
if (anExpEg.Current().IsSame (aEG))
{
aEG = TopoDS::Edge (anExpEg.Current());
break;
}
}
}
if (aDMVEMin.IsBound (aV))
{
const TopTools_ListOfShape* pSA = aDMVFAnc.Seek (aV);
if (pSA && pSA->Extent() == 1)
{
// Adjust orientation of generated edge to its new ancestor
TopoDS_Edge aEMin = TopoDS::Edge (aDMVEMin.Find (aV));
for (TopExp_Explorer expEx (pSA->First(), TopAbs_EDGE); expEx.More(); expEx.Next())
{
if (expEx.Current().IsSame (aEMin))
{
aEMin = TopoDS::Edge (expEx.Current());
break;
}
}
TopAbs_Orientation anOriInEMin (TopAbs_FORWARD), anOriInEG (TopAbs_FORWARD);
for (TopoDS_Iterator itx (aEMin); itx.More(); itx.Next())
{
if (itx.Value().IsSame (aV))
{
anOriInEMin = itx.Value().Orientation();
break;
}
}
for (TopoDS_Iterator itx (aEG); itx.More(); itx.Next())
{
if (itx.Value().IsSame (aV))
{
anOriInEG = itx.Value().Orientation();
break;
}
}
if (anOriInEG == anOriInEMin)
aEG.Reverse();
}
}
TopTools_ListOfShape& aLVA = myAncestors.ChangeFromKey (aV);
if (!aLVA.Contains (aEG))
aLVA.Append (aEG);
aFNewEdgeMap.Add (aEG);
TopTools_ListOfShape& aLEGA =
myAncestors (myAncestors.Add (aEG, aPrismAncestors.FindFromKey (aEG)));
{
// Add ancestors from the shape
const TopTools_ListOfShape* pSA = aDMVFAnc.Seek (aV);
if (pSA && !pSA->IsEmpty())
{
TopTools_ListOfShape aLSA = *pSA;
aLEGA.Append (aLSA);
}
}
myMapEdgeType.Bind (aEG, BRepOffset_ListOfInterval());
if (aLEGA.Extent() == 2)
{
EdgeAnalyse (aEG, TopoDS::Face (aLEGA.First()), TopoDS::Face (aLEGA.Last()),
aSinTol, myMapEdgeType (aEG));
}
}
// Find an edge opposite to tangential one and add ancestors for it
TopoDS_Edge aEOpposite;
for (TopExp_Explorer anExpE (aFNew, TopAbs_EDGE); anExpE.More(); anExpE.Next())
{
if (!aFNewEdgeMap.Contains (anExpE.Current()))
{
aEOpposite = TopoDS::Edge (anExpE.Current());
break;
}
}
{
// Find it in aFOpposite
for (TopExp_Explorer anExpE (aFToRemove, TopAbs_EDGE); anExpE.More(); anExpE.Next())
{
const TopoDS_Shape& aEInFToRem = anExpE.Current();
if (aE.IsSame (aEInFToRem))
{
if (BOPTools_AlgoTools::IsSplitToReverse (aEOpposite, aEInFToRem, aCtx))
aEOpposite.Reverse();
break;
}
}
}
TopTools_ListOfShape aLFOpposite;
aLFOpposite.Append (aFNew);
aLFOpposite.Append (aFToRemove);
myAncestors.Add (aEOpposite, aLFOpposite);
myMapEdgeType.Bind (aEOpposite, BRepOffset_ListOfInterval());
EdgeAnalyse (aEOpposite, aFNew, TopoDS::Face (aFToRemove), aSinTol, myMapEdgeType (aEOpposite));
TopTools_DataMapOfShapeShape* pEEMap = myReplacement.ChangeSeek (aFToRemove);
if (!pEEMap)
pEEMap = myReplacement.Bound (aFToRemove, TopTools_DataMapOfShapeShape());
pEEMap->Bind (aE, aEOpposite);
// Add ancestors for the vertices
for (TopoDS_Iterator itV (aEOpposite); itV.More(); itV.Next())
{
const TopoDS_Shape& aV = itV.Value();
const TopTools_ListOfShape& aLVA = aPrismAncestors.FindFromKey (aV);
myAncestors.Add (aV, aLVA);
}
myNewFaces.Append (aFNew);
myGenerated.Bind (aE, aFNew);
}
}
}
}
//=======================================================================
//function : EdgeReplacement
//purpose :
//=======================================================================
const TopoDS_Edge& BRepOffset_Analyse::EdgeReplacement (const TopoDS_Face& theF,
const TopoDS_Edge& theE) const
{
const TopTools_DataMapOfShapeShape* pEE = myReplacement.Seek (theF);
if (!pEE)
return theE;
const TopoDS_Shape* pE = pEE->Seek (theE);
if (!pE)
return theE;
return TopoDS::Edge (*pE);
}
//=======================================================================
//function : Generated
//purpose :
//=======================================================================
TopoDS_Shape BRepOffset_Analyse::Generated (const TopoDS_Shape& theS) const
{
static TopoDS_Shape aNullShape;
const TopoDS_Shape* pGenS = myGenerated.Seek (theS);
return pGenS ? *pGenS : aNullShape;
}
//=======================================================================
//function : Descendants
//purpose :
//=======================================================================
const TopTools_ListOfShape* BRepOffset_Analyse::Descendants (const TopoDS_Shape& theS,
const Standard_Boolean theUpdate) const
{
if (myDescendants.IsEmpty() || theUpdate)
{
myDescendants.Clear();
const Standard_Integer aNbA = myAncestors.Extent();
for (Standard_Integer i = 1; i <= aNbA; ++i)
{
const TopoDS_Shape& aSS = myAncestors.FindKey (i);
const TopTools_ListOfShape& aLA = myAncestors (i);
for (TopTools_ListOfShape::Iterator it (aLA); it.More(); it.Next())
{
const TopoDS_Shape& aSA = it.Value();
TopTools_ListOfShape* pLD = myDescendants.ChangeSeek (aSA);
if (!pLD)
pLD = myDescendants.Bound (aSA, TopTools_ListOfShape());
if (!pLD->Contains (aSS))
pLD->Append (aSS);
}
}
}
return myDescendants.Seek (theS);
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void BRepOffset_Analyse::Clear()
{
myDone = Standard_False;
myShape .Nullify();
mapEdgeType.Clear();
ancestors .Clear();
myMapEdgeType.Clear();
myAncestors .Clear();
myFaceOffsetMap.Clear();
myReplacement.Clear();
myDescendants.Clear();
myNewFaces .Clear();
myGenerated.Clear();
}
//=======================================================================
//function : BRepOffset_ListOfInterval&
//purpose :
//=======================================================================
const BRepOffset_ListOfInterval& BRepOffset_Analyse::Type(const TopoDS_Edge& E)
const
const BRepOffset_ListOfInterval& BRepOffset_Analyse::Type(const TopoDS_Edge& E) const
{
return mapEdgeType (E);
return myMapEdgeType (E);
}
//=======================================================================
//function : Edges
//purpose :
//=======================================================================
void BRepOffset_Analyse::Edges(const TopoDS_Vertex& V,
const ChFiDS_TypeOfConcavity T,
TopTools_ListOfShape& LE)
const
const ChFiDS_TypeOfConcavity T,
TopTools_ListOfShape& LE) const
{
LE.Clear();
const TopTools_ListOfShape& L = Ancestors (V);
@@ -236,15 +659,19 @@ const
for ( ;it.More(); it.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(it.Value());
TopoDS_Vertex V1,V2;
BRepOffset_Tool::EdgeVertices (E,V1,V2);
if (V1.IsSame(V)) {
if (mapEdgeType(E).Last().Type() == T)
LE.Append(E);
}
if (V2.IsSame(V)) {
if (mapEdgeType(E).First().Type() == T)
LE.Append(E);
const BRepOffset_ListOfInterval *pIntervals = myMapEdgeType.Seek (E);
if (pIntervals && pIntervals->Extent() > 0)
{
TopoDS_Vertex V1,V2;
BRepOffset_Tool::EdgeVertices (E,V1,V2);
if (V1.IsSame(V)) {
if (pIntervals->Last().Type() == T)
LE.Append (E);
}
if (V2.IsSame(V)) {
if (pIntervals->First().Type() == T)
LE.Append (E);
}
}
}
}
@@ -254,15 +681,13 @@ const
//function : Edges
//purpose :
//=======================================================================
void BRepOffset_Analyse::Edges(const TopoDS_Face& F,
const ChFiDS_TypeOfConcavity T,
TopTools_ListOfShape& LE)
const
const ChFiDS_TypeOfConcavity T,
TopTools_ListOfShape& LE) const
{
LE.Clear();
TopExp_Explorer exp(F, TopAbs_EDGE);
for ( ;exp.More(); exp.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
@@ -278,14 +703,12 @@ const
//function : TangentEdges
//purpose :
//=======================================================================
void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge ,
const TopoDS_Vertex& Vertex,
TopTools_ListOfShape& Edges ) const
{
gp_Vec V,VRef;
Standard_Real U,URef;
BRepAdaptor_Curve C3d, C3dRef;
@@ -307,49 +730,23 @@ void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge ,
V = C3d.DN(U,1);
CorrectOrientationOfTangent(V, Vertex, CurE);
if (V.SquareMagnitude() < gp::Resolution()) continue;
if (V.IsOpposite(VRef,angle)) {
if (V.IsOpposite(VRef,myAngle)) {
Edges.Append(CurE);
}
}
}
//=======================================================================
//function : HasAncestor
//purpose :
//=======================================================================
Standard_Boolean BRepOffset_Analyse::HasAncestor (const TopoDS_Shape& S) const
{
return ancestors.Contains(S);
}
//=======================================================================
//function : Ancestors
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepOffset_Analyse::Ancestors
(const TopoDS_Shape& S) const
{
return ancestors.FindFromKey(S);
}
//=======================================================================
//function : Explode
//purpose :
//=======================================================================
void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
const ChFiDS_TypeOfConcavity T ) const
void BRepOffset_Analyse::Explode (TopTools_ListOfShape& List,
const ChFiDS_TypeOfConcavity T) const
{
List.Clear();
BRep_Builder B;
TopTools_MapOfShape Map;
TopExp_Explorer Fexp;
for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) {
if ( Map.Add(Fexp.Current())) {
@@ -369,10 +766,9 @@ void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
//function : Explode
//purpose :
//=======================================================================
void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
const ChFiDS_TypeOfConcavity T1,
const ChFiDS_TypeOfConcavity T2) const
void BRepOffset_Analyse::Explode (TopTools_ListOfShape& List,
const ChFiDS_TypeOfConcavity T1,
const ChFiDS_TypeOfConcavity T2) const
{
List.Clear();
BRep_Builder B;
@@ -393,67 +789,70 @@ void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
}
}
//=======================================================================
//function : AddFaces
//purpose :
//=======================================================================
void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
TopoDS_Compound& Co,
TopTools_MapOfShape& Map,
const ChFiDS_TypeOfConcavity T) const
TopoDS_Compound& Co,
TopTools_MapOfShape& Map,
const ChFiDS_TypeOfConcavity T) const
{
BRep_Builder B;
TopExp_Explorer exp(Face,TopAbs_EDGE);
for ( ; exp.More(); exp.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
const TopTools_ListOfShape *pLE = Descendants (Face);
if (!pLE)
return;
for (TopTools_ListOfShape::Iterator it (*pLE); it.More(); it.Next())
{
const TopoDS_Edge& E = TopoDS::Edge (it.Value());
const BRepOffset_ListOfInterval& LI = Type(E);
if (!LI.IsEmpty() && LI.First().Type() == T) {
// so <NewFace> is attached to G1 by <Face>
const TopTools_ListOfShape& L = Ancestors(E);
if (L.Extent() == 2) {
TopoDS_Face F1 = TopoDS::Face(L.First());
if ( F1.IsSame(Face))
F1 = TopoDS::Face(L.Last ());
if ( Map.Add(F1)) {
B.Add(Co,F1);
AddFaces(F1,Co,Map,T);
}
TopoDS_Face F1 = TopoDS::Face (L.First());
if (F1.IsSame (Face))
F1 = TopoDS::Face (L.Last());
if (Map.Add (F1)) {
B.Add (Co, F1);
AddFaces (F1, Co, Map, T);
}
}
}
}
}
//=======================================================================
//function : AddFaces
//purpose :
//=======================================================================
void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
TopoDS_Compound& Co,
TopTools_MapOfShape& Map,
const ChFiDS_TypeOfConcavity T1,
const ChFiDS_TypeOfConcavity T2) const
TopoDS_Compound& Co,
TopTools_MapOfShape& Map,
const ChFiDS_TypeOfConcavity T1,
const ChFiDS_TypeOfConcavity T2) const
{
BRep_Builder B;
TopExp_Explorer exp(Face,TopAbs_EDGE);
for ( ; exp.More(); exp.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
const TopTools_ListOfShape *pLE = Descendants (Face);
if (!pLE)
return;
for (TopTools_ListOfShape::Iterator it (*pLE); it.More(); it.Next())
{
const TopoDS_Edge& E = TopoDS::Edge (it.Value());
const BRepOffset_ListOfInterval& LI = Type(E);
if (!LI.IsEmpty() &&
(LI.First().Type() == T1 || LI.First().Type() == T2)) {
(LI.First().Type() == T1 || LI.First().Type() == T2)) {
// so <NewFace> is attached to G1 by <Face>
const TopTools_ListOfShape& L = Ancestors(E);
if (L.Extent() == 2) {
TopoDS_Face F1 = TopoDS::Face(L.First());
if ( F1.IsSame(Face))
F1 = TopoDS::Face(L.Last ());
if ( Map.Add(F1)) {
B.Add(Co,F1);
AddFaces(F1,Co,Map,T1,T2);
}
TopoDS_Face F1 = TopoDS::Face (L.First());
if (F1.IsSame (Face))
F1 = TopoDS::Face (L.Last());
if (Map.Add (F1)) {
B.Add (Co, F1);
AddFaces (F1, Co, Map, T1, T2);
}
}
}
}
}

View File

@@ -28,6 +28,9 @@
#include <Standard_Real.hxx>
#include <BRepOffset_ListOfInterval.hxx>
#include <ChFiDS_TypeOfConcavity.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapOfShapeReal.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
class TopoDS_Shape;
@@ -36,102 +39,164 @@ class TopoDS_Vertex;
class TopoDS_Face;
class TopoDS_Compound;
//! Analyse of a shape consit to
//! Find the part of edges convex concave tangent.
//! Analyses the shape to find the parts of edges
//! connecting the convex, concave or tangent faces.
class BRepOffset_Analyse
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructors
//! Empty c-tor
Standard_EXPORT BRepOffset_Analyse();
//! C-tor performing the job inside
Standard_EXPORT BRepOffset_Analyse (const TopoDS_Shape& theS,
const Standard_Real theAngle);
Standard_EXPORT BRepOffset_Analyse(const TopoDS_Shape& S, const Standard_Real Angle);
Standard_EXPORT void Perform (const TopoDS_Shape& S, const Standard_Real Angle);
Standard_EXPORT Standard_Boolean IsDone() const;
Standard_EXPORT void Clear();
Standard_EXPORT const BRepOffset_ListOfInterval& Type (const TopoDS_Edge& E) const;
public: //! @name Performing analysis
//! Performs the analysis
Standard_EXPORT void Perform (const TopoDS_Shape& theS,
const Standard_Real theAngle);
public: //! @name Results
//! Returns status of the algorithm
Standard_Boolean IsDone() const
{
return myDone;
}
//! Returns the connectivity type of the edge
Standard_EXPORT const BRepOffset_ListOfInterval& Type (const TopoDS_Edge& theE) const;
//! Stores in <L> all the edges of Type <T>
//! on the vertex <V>.
Standard_EXPORT void Edges (const TopoDS_Vertex& V,
const ChFiDS_TypeOfConcavity T,
TopTools_ListOfShape& L) const;
Standard_EXPORT void Edges (const TopoDS_Vertex& theV,
const ChFiDS_TypeOfConcavity theType,
TopTools_ListOfShape& theL) const;
//! Stores in <L> all the edges of Type <T>
//! on the face <F>.
Standard_EXPORT void Edges (const TopoDS_Face& F,
const ChFiDS_TypeOfConcavity T,
TopTools_ListOfShape& L) const;
Standard_EXPORT void Edges (const TopoDS_Face& theF,
const ChFiDS_TypeOfConcavity theType,
TopTools_ListOfShape& theL) const;
//! set in <Edges> all the Edges of <Shape> which are
//! tangent to <Edge> at the vertex <Vertex>.
Standard_EXPORT void TangentEdges (const TopoDS_Edge& Edge,
const TopoDS_Vertex& Vertex,
TopTools_ListOfShape& Edges) const;
Standard_EXPORT Standard_Boolean HasAncestor (const TopoDS_Shape& S) const;
Standard_EXPORT const TopTools_ListOfShape& Ancestors (const TopoDS_Shape& S) const;
Standard_EXPORT void TangentEdges (const TopoDS_Edge& theEdge,
const TopoDS_Vertex& theVertex,
TopTools_ListOfShape& theEdges) const;
//! Checks if the given shape has ancestors
Standard_Boolean HasAncestor (const TopoDS_Shape& theS) const
{
return myAncestors.Contains (theS);
}
//! Returns ancestors for the shape
const TopTools_ListOfShape& Ancestors (const TopoDS_Shape& theS) const
{
return myAncestors.FindFromKey (theS);
}
//! Explode in compounds of faces where
//! all the connex edges are of type <Side>
Standard_EXPORT void Explode (TopTools_ListOfShape& L,
const ChFiDS_TypeOfConcavity Type) const;
Standard_EXPORT void Explode (TopTools_ListOfShape& theL,
const ChFiDS_TypeOfConcavity theType) const;
//! Explode in compounds of faces where
//! all the connex edges are of type <Side1> or <Side2>
Standard_EXPORT void Explode (TopTools_ListOfShape& L,
const ChFiDS_TypeOfConcavity Type1,
const ChFiDS_TypeOfConcavity Type2) const;
Standard_EXPORT void Explode (TopTools_ListOfShape& theL,
const ChFiDS_TypeOfConcavity theType1,
const ChFiDS_TypeOfConcavity theType2) const;
//! Add in <CO> the faces of the shell containing <Face>
//! where all the connex edges are of type <Side>.
Standard_EXPORT void AddFaces (const TopoDS_Face& Face,
TopoDS_Compound& Co,
TopTools_MapOfShape& Map,
const ChFiDS_TypeOfConcavity Type) const;
Standard_EXPORT void AddFaces (const TopoDS_Face& theFace,
TopoDS_Compound& theCo,
TopTools_MapOfShape& theMap,
const ChFiDS_TypeOfConcavity theType) const;
//! Add in <CO> the faces of the shell containing <Face>
//! where all the connex edges are of type <Side1> or <Side2>.
Standard_EXPORT void AddFaces (const TopoDS_Face& Face,
TopoDS_Compound& Co,
TopTools_MapOfShape& Map,
const ChFiDS_TypeOfConcavity Type1,
const ChFiDS_TypeOfConcavity Type2) const;
Standard_EXPORT void AddFaces (const TopoDS_Face& theFace,
TopoDS_Compound& theCo,
TopTools_MapOfShape& theMap,
const ChFiDS_TypeOfConcavity theType1,
const ChFiDS_TypeOfConcavity theType2) const;
void SetOffsetValue (const Standard_Real theOffset)
{
myOffset = theOffset;
}
//! Sets the face-offset data map to analyze tangential cases
void SetFaceOffsetMap (const TopTools_DataMapOfShapeReal& theMap)
{
myFaceOffsetMap = theMap;
}
//! Returns the new faces constructed between tangent faces
//! having different offset values on the shape
const TopTools_ListOfShape& NewFaces() const { return myNewFaces; }
protected:
//! Returns the new face constructed for the edge connecting
//! the two tangent faces having different offset values
Standard_EXPORT TopoDS_Shape Generated (const TopoDS_Shape& theS) const;
//! Checks if the edge has generated a new face.
Standard_Boolean HasGenerated (const TopoDS_Shape& theS) const
{
return myGenerated.Seek (theS) != NULL;
}
//! Returns the replacement of the edge in the face.
//! If no replacement exists, returns the edge
Standard_EXPORT const TopoDS_Edge& EdgeReplacement (const TopoDS_Face& theFace,
const TopoDS_Edge& theEdge) const;
//! Returns the shape descendants.
Standard_EXPORT const TopTools_ListOfShape* Descendants (const TopoDS_Shape& theS,
const Standard_Boolean theUpdate = Standard_False) const;
public: //! @name Clearing the content
private:
//! Clears the content of the algorithm
Standard_EXPORT void Clear();
private: //! @name Treatment of tangential cases
//! Treatment of the tangential cases.
//! @param theEdges List of edges connecting tangent faces
Standard_EXPORT void TreatTangentFaces (const TopTools_ListOfShape& theEdges);
Standard_Boolean myDone;
TopoDS_Shape myShape;
BRepOffset_DataMapOfShapeListOfInterval mapEdgeType;
TopTools_IndexedDataMapOfShapeListOfShape ancestors;
Standard_Real angle;
private: //! @name Fields
// Inputs
TopoDS_Shape myShape; //!< Input shape to analyze
Standard_Real myAngle; //!< Criteria angle to check tangency
Standard_Real myOffset; //!< Offset value
TopTools_DataMapOfShapeReal myFaceOffsetMap; //!< Map to store offset values for the faces.
//! Should be set by the calling algorithm.
// Results
Standard_Boolean myDone; //!< Status of the algorithm
BRepOffset_DataMapOfShapeListOfInterval myMapEdgeType; //!< Map containing the list of intervals on the edge
TopTools_IndexedDataMapOfShapeListOfShape myAncestors; //!< Ancestors map
NCollection_DataMap<TopoDS_Shape,
TopTools_DataMapOfShapeShape,
TopTools_ShapeMapHasher> myReplacement; //!< Replacement of an edge in the face
mutable TopTools_DataMapOfShapeListOfShape myDescendants; //!< Map of shapes descendants built on the base of
//!< Ancestors map. Filled on the first query.
TopTools_ListOfShape myNewFaces; //!< New faces generated to close the gaps between adjacent
//! tangential faces having different offset values
TopTools_DataMapOfShapeShape myGenerated; //!< Binding between edge and face generated from the edge
};
#endif // _BRepOffset_Analyse_HeaderFile

View File

@@ -34,6 +34,7 @@
#include <BRepAlgo_AsDes.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepOffset_Analyse.hxx>
#include <BRepOffset_Inter2d.hxx>
#include <BRepOffset_Offset.hxx>
#include <BRepOffset_Tool.hxx>
@@ -1451,6 +1452,7 @@ void BRepOffset_Inter2d::ConnexIntByInt
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset,
const Standard_Real Tol,
const BRepOffset_Analyse& Analyse,
TopTools_IndexedMapOfShape& FacesWithVerts,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
{
@@ -1523,6 +1525,9 @@ void BRepOffset_Inter2d::ConnexIntByInt
TopoDS_Vertex Vref = CommonVertex(CurE, NextE);
gp_Pnt Pref = BRep_Tool::Pnt(Vref);
CurE = Analyse.EdgeReplacement (FI, CurE);
NextE = Analyse.EdgeReplacement (FI, NextE);
TopoDS_Shape aLocalShape = OFI.Generated(CurE);
TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
aLocalShape = OFI.Generated(NextE);
@@ -1582,18 +1587,20 @@ void BRepOffset_Inter2d::ConnexIntByInt
}
}
else {
if (MES.IsBound(CEO)) {
TopoDS_Vertex V = CommonVertex(CEO,NEO);
UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
AsDes2d->Add (MES(CEO),V);
}
else if (MES.IsBound(NEO)) {
TopoDS_Vertex V = CommonVertex(CEO,NEO);
UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
AsDes2d->Add (MES(NEO),V);
TopoDS_Vertex V = CommonVertex(CEO,NEO);
if (!V.IsNull())
{
if (MES.IsBound(CEO)) {
UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
AsDes2d->Add (MES(CEO),V);
}
if (MES.IsBound(NEO)) {
UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
AsDes2d->Add (MES(NEO),V);
}
}
}
CurE = NextE;
CurE = wexp.Current();
ToReverse1 = ToReverse2;
}
}
@@ -1611,6 +1618,7 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Tol,
const BRepOffset_Analyse& Analyse,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
{
TopoDS_Face FIO = TopoDS::Face(OFI.Face());
@@ -1657,7 +1665,10 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
CurE = NextE;
continue;
}
//
CurE = Analyse.EdgeReplacement (FI, CurE);
NextE = Analyse.EdgeReplacement (FI, NextE);
TopoDS_Shape aLocalShape = OFI.Generated(CurE);
TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
aLocalShape = OFI.Generated(NextE);
@@ -1678,7 +1689,7 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
NE2 = MES(CEO);
}
else {
CurE = NextE;
CurE = wexp.Current();
continue;
}
//
@@ -1731,7 +1742,7 @@ void BRepOffset_Inter2d::ConnexIntByIntInVert
}
}
}
CurE = NextE;
CurE = wexp.Current();
}
}
}

View File

@@ -27,6 +27,7 @@
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
class BRepAlgo_AsDes;
class TopoDS_Face;
class BRepOffset_Analyse;
class BRepOffset_Offset;
@@ -63,6 +64,7 @@ public:
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset,
const Standard_Real Tol,
const BRepOffset_Analyse& Analyse,
TopTools_IndexedMapOfShape& FacesWithVerts,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
@@ -79,6 +81,7 @@ public:
const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Tol,
const BRepOffset_Analyse& Analyse,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
//! Fuses the chains of vertices in the theDMVV

View File

@@ -399,88 +399,148 @@ void BRepOffset_Inter3d::ConnexIntByInt
TopTools_ListOfShape& Failed,
const Standard_Boolean bIsPlanar)
{
//TopExp_Explorer Exp(SI,TopAbs_EDGE);
TopTools_IndexedMapOfShape VEmap;
TopTools_IndexedDataMapOfShapeListOfShape aMVF;
TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
TopAbs_State CurSide = mySide;
BRep_Builder B;
Standard_Boolean bEdge;
Standard_Integer i, aNb;
Standard_Integer i, aNb = 0;
TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
//
TopExp::MapShapes(SI, TopAbs_EDGE , VEmap);
// map the shape for vertices
if (bIsPlanar) {
TopExp::MapShapes (SI, TopAbs_EDGE, VEmap);
// Take the vertices for treatment
if (bIsPlanar)
{
aNb = VEmap.Extent();
for (i = 1; i <= aNb; ++i)
{
const TopoDS_Edge& aE = TopoDS::Edge (VEmap (i));
TopoDS_Shape aFGen = Analyse.Generated (aE);
if (!aFGen.IsNull())
TopExp::MapShapes (aFGen, TopAbs_EDGE, VEmap);
}
// Add vertices for treatment
TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
//
// make vertex-faces connexity map with unique ancestors
TopExp::MapShapesAndUniqueAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
for (TopTools_ListOfShape::Iterator itNF (Analyse.NewFaces()); itNF.More(); itNF.Next())
TopExp::MapShapes (itNF.Value(), TopAbs_VERTEX, VEmap);
}
//
TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2, aDMIntFF;
TopTools_IndexedDataMapOfShapeListOfShape aDMIntE;
//
if (bIsPlanar) {
aNb = VEmap.Extent();
for (i = 1; i <= aNb; ++i) {
if (bIsPlanar)
{
// Find internal edges in the faces to skip them while preparing faces
// for intersection through vertices
NCollection_DataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aDMFEI;
{
for (TopExp_Explorer expF (SI, TopAbs_FACE); expF.More(); expF.Next())
{
const TopoDS_Shape& aFx = expF.Current();
TopTools_MapOfShape aMEI;
for (TopExp_Explorer expE (aFx, TopAbs_EDGE); expE.More(); expE.Next())
{
const TopoDS_Shape& aEx = expE.Current();
if (aEx.Orientation() != TopAbs_FORWARD &&
aEx.Orientation() != TopAbs_REVERSED)
aMEI.Add (aEx);
}
if (!aMEI.IsEmpty())
aDMFEI.Bind (aFx, aMEI);
}
}
// Analyze faces connected through vertices
for (i = aNb + 1, aNb = VEmap.Extent(); i <= aNb; ++i)
{
const TopoDS_Shape& aS = VEmap(i);
if (aS.ShapeType() != TopAbs_VERTEX) {
if (aS.ShapeType() != TopAbs_VERTEX)
continue;
// Find faces connected to the vertex
TopTools_ListOfShape aLF;
{
const TopTools_ListOfShape& aLE = Analyse.Ancestors (aS);
for (TopTools_ListOfShape::Iterator itLE (aLE); itLE.More(); itLE.Next())
{
const TopTools_ListOfShape& aLEA = Analyse.Ancestors (itLE.Value());
for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
{
if (!aLF.Contains (itLEA.Value()))
aLF.Append (itLEA.Value());
}
}
}
//
// faces connected by the vertex
const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS);
if (aLF.Extent() < 2) {
if (aLF.Extent() < 2)
continue;
}
// build lists of faces connected to the same vertex by looking for
// the pairs in which the vertex is alone (not connected to shared edges)
TopTools_ListOfShape aLF1, aLF2;
//
it.Initialize(aLF);
for (; it.More(); it.Next()) {
for (; it.More(); it.Next())
{
const TopoDS_Shape& aFV1 = it.Value();
//
// get edges of first face connected to current vertex
TopTools_MapOfShape aME;
TopExp_Explorer aExp(aFV1, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aE = aExp.Current();
if (aE.Orientation() != TopAbs_FORWARD &&
aE.Orientation() != TopAbs_REVERSED)
// Face is connected to the vertex through internal edge
const TopTools_MapOfShape *pF1Internal = aDMFEI.Seek (aFV1);
const TopTools_ListOfShape* pLE1 = Analyse.Descendants (aFV1);
if (!pLE1)
continue;
TopTools_ListOfShape::Iterator itLE1 (*pLE1);
for (; itLE1.More(); itLE1.Next())
{
const TopoDS_Shape& aE = itLE1.Value();
if (pF1Internal && pF1Internal->Contains (aE))
break;
TopoDS_Iterator aItV(aE);
for (; aItV.More(); aItV.Next()) {
if (aS.IsSame(aItV.Value())) {
for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next())
{
if (aS.IsSame (aItV.Value()))
{
aME.Add(aE);
break;
}
}
}
if (aExp.More())
if (itLE1.More())
continue;
// get to the next face in the list
it1 = it;
for (it1.Next(); it1.More(); it1.Next()) {
const TopoDS_Shape& aFV2 = it1.Value();
//
aExp.Init(aFV2, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aEV2 = aExp.Current();
if (aME.Contains(aEV2) &&
(Analyse.Ancestors(aEV2).Extent() == 2 || // Multi-connexity is not supported in Analyzer
(aEV2.Orientation() != TopAbs_FORWARD && // Avoid intersection of faces connected by internal edge
aEV2.Orientation() != TopAbs_REVERSED))) {
const TopoDS_Face& aFV2 = TopoDS::Face (it1.Value());
const TopTools_MapOfShape *pF2Internal = aDMFEI.Seek (aFV2);
const TopTools_ListOfShape* pLE2 = Analyse.Descendants (aFV2);
if (!pLE2)
continue;
TopTools_ListOfShape::Iterator itLE2 (*pLE2);
for (; itLE2.More(); itLE2.Next())
{
const TopoDS_Shape& aEV2 = itLE2.Value();
if (!aME.Contains (aEV2))
continue;
if (pF2Internal && pF2Internal->Contains (aEV2))
// Avoid intersection of faces connected by internal edge
break;
if (Analyse.HasAncestor (aEV2) &&
Analyse.Ancestors (aEV2).Extent() == 2)
// Faces will be intersected through the edge
break;
}
}
//
if (!aExp.More()) {
// faces share only vertex - make pair for intersection
if (!itLE2.More())
{
aLF1.Append(aFV1);
aLF2.Append(aFV2);
}

View File

@@ -245,7 +245,7 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
// static methods
//=======================================================================
static
void GetEnlargedFaces(const TopoDS_Shape& theShape,
void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
const BRepOffset_DataMapOfShapeOffset& theMapSF,
const TopTools_DataMapOfShapeShape& theMES,
TopTools_DataMapOfShapeShape& theFacesOrigins,
@@ -292,6 +292,7 @@ static
static
void TrimEdges(const TopoDS_Shape& theShape,
const Standard_Real theOffset,
const BRepOffset_Analyse& Analyse,
BRepOffset_DataMapOfShapeOffset& theMapSF,
TopTools_DataMapOfShapeShape& theMES,
TopTools_DataMapOfShapeShape& theBuild,
@@ -648,6 +649,8 @@ void BRepOffset_MakeOffset::Clear()
myFaceOffset .Clear();
myAsDes ->Clear();
myDone = Standard_False;
myGenerated.Clear();
myResMap.Clear();
}
//=======================================================================
@@ -805,6 +808,11 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
// There are possible second variant: analytical continuation of arcsin.
Standard_Real TolAngleCoeff = Min(myTol / (Abs(myOffset * 0.5) + Precision::Confusion()), 1.0);
Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar)
{
myAnalyse.SetOffsetValue (myOffset);
myAnalyse.SetFaceOffsetMap (myFaceOffset);
}
myAnalyse.Perform(myShape,TolAngle);
//---------------------------------------------------
// Construction of Offset from preanalysis.
@@ -870,6 +878,10 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
// Coding of regularities.
//----------------------------------
EncodeRegularity();
//----------------------------------
// Replace roots in history maps
//----------------------------------
ReplaceRoots();
//----------------------
// Creation of solids.
//----------------------
@@ -1054,7 +1066,7 @@ void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& the
TopTools_ListIteratorOfListOfShape itl(Let);
for (; itl.More(); itl.Next()) {
const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
if ( !ShapeTgt.IsBound(Cur)) {
if ( !ShapeTgt.IsBound(Cur) && !myAnalyse.HasGenerated (Cur)) {
TopoDS_Shape aLocalShape = OF.Generated(Cur);
const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
ShapeTgt.Bind(Cur,OF.Generated(Cur));
@@ -1079,6 +1091,14 @@ void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& the
}
theMapSF.Bind(aF,OF);
}
//
const TopTools_ListOfShape& aNewFaces = myAnalyse.NewFaces();
for (TopTools_ListOfShape::Iterator it (aNewFaces); it.More(); it.Next())
{
const TopoDS_Face& aF = TopoDS::Face (it.Value());
BRepOffset_Offset OF(aF, 0.0, ShapeTgt, OffsetOutside, myJoin);
theMapSF.Bind (aF, OF);
}
}
//=======================================================================
@@ -1126,12 +1146,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
// Intersection with caps.
Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
TopTools_ListOfShape aLFaces;
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next())
aLFaces.Append (Exp.Current());
for (TopTools_ListOfShape::Iterator it (myAnalyse.NewFaces()); it.More(); it.Next())
aLFaces.Append (it.Value());
//---------------------------------------------------------------------------------
// Extension of neighbor edges of new edges and intersection between neighbors.
//--------------------------------------------------------------------------------
Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
IntersectEdges(myShape, MapSF, MES, Build, AsDes, AsDes2d);
IntersectEdges(aLFaces, MapSF, MES, Build, AsDes, AsDes2d);
//-----------------------------------------------------------
// Great restriction of new edges and update of AsDes.
//------------------------------------------ ----------------
@@ -1142,7 +1168,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
//Map of edges obtained after FACE-FACE (offsetted) intersection.
//Key1 is edge trimmed by intersection points with other edges;
//Item is not-trimmed edge.
TrimEdges(myShape, myOffset, MapSF, MES, Build, AsDes, AsDes2d, NewEdges, aETrimEInf, anEdgesOrigins);
TrimEdges(myShape, myOffset, myAnalyse, MapSF, MES, Build, AsDes, AsDes2d, NewEdges, aETrimEInf, anEdgesOrigins);
//
//---------------------------------
// Intersection 2D on //
@@ -1151,7 +1177,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
TopTools_DataMapOfShapeShape aFacesOrigins; // offset face - initial face
TopTools_ListOfShape LFE;
BRepAlgo_Image IMOE;
GetEnlargedFaces(myShape, MapSF, MES, aFacesOrigins, IMOE, LFE);
GetEnlargedFaces(aLFaces, MapSF, MES, aFacesOrigins, IMOE, LFE);
//
TopTools_ListIteratorOfListOfShape itLFE(LFE);
for (; itLFE.More(); itLFE.Next())
@@ -1179,7 +1205,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
TopTools_MapOfShape aMFDone;
//
if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
BuildSplitsOfExtendedFaces(LFE, AsDes, anEdgesOrigins, aFacesOrigins, aETrimEInf, IMOE);
BuildSplitsOfExtendedFaces(LFE, myAnalyse, AsDes, anEdgesOrigins, aFacesOrigins, aETrimEInf, IMOE);
//
TopTools_ListIteratorOfListOfShape aItLF(LFE);
for (; aItLF.More(); aItLF.Next()) {
@@ -1197,8 +1223,9 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
//---------------------------
// MAJ SD. for faces //
//---------------------------
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
const TopoDS_Shape& FI = Exp.Current();
for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
{
const TopoDS_Shape& FI = it.Value();
myInitOffsetFace.SetRoot(FI);
TopoDS_Face OF = MapSF(FI).Face();
if (MES.IsBound(OF)) {
@@ -1327,9 +1354,9 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
// Add methods for supporting history.
TopTools_MapOfShape aMapEdges;
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
const TopoDS_Shape& aFaceRef = Exp.Current();
for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
{
const TopoDS_Shape& aFaceRef = it.Value();
Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
for (; Exp2.More(); Exp2.Next()) {
@@ -1435,6 +1462,46 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
DEBVerticesControl (COES,myAsDes);
if ( ChronBuild) Clock.Show();
#endif
}
//=======================================================================
//function : ReplaceRoots
//purpose :
//=======================================================================
void BRepOffset_MakeOffset::ReplaceRoots()
{
// Replace the artificial faces and edges in InitOffset maps with the original ones.
TopTools_MapOfShape View;
for (TopExp_Explorer anExpF (myShape, TopAbs_EDGE); anExpF.More(); anExpF.Next())
{
const TopoDS_Shape& aF = anExpF.Current();
for (TopExp_Explorer anExpE (aF, TopAbs_EDGE); anExpE.More(); anExpE.Next())
{
const TopoDS_Shape& aE = anExpE.Current();
if (!View.Add (aE))
continue;
TopoDS_Shape aFGen = myAnalyse.Generated (aE);
if (aFGen.IsNull())
continue;
myInitOffsetFace.ReplaceRoot (aFGen, aE);
for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
{
const TopoDS_Shape& aV = itV.Value();
if (!View.Add (aV))
continue;
TopoDS_Shape aEGen = myAnalyse.Generated (aV);
if (aEGen.IsNull())
continue;
myInitOffsetEdge.ReplaceRoot (aEGen, aV);
}
}
}
}
//=======================================================================
@@ -3822,7 +3889,7 @@ void UpdateHistory(const TopTools_ListOfShape& theLF,
//function : IntersectEdges
//purpose :
//=======================================================================
void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
void BRepOffset_MakeOffset::IntersectEdges(const TopTools_ListOfShape& theFaces,
BRepOffset_DataMapOfShapeOffset& theMapSF,
TopTools_DataMapOfShapeShape& theMES,
TopTools_DataMapOfShapeShape& theBuild,
@@ -3831,14 +3898,14 @@ void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
{
Standard_Real aTolF;
TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
TopExp_Explorer aExp(theShape, TopAbs_FACE);
// intersect edges created from edges
TopTools_IndexedMapOfShape aMFV;
for (; aExp.More(); aExp.Next()) {
const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
aTolF = BRep_Tool::Tolerance(aF);
for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
{
const TopoDS_Face& aF = TopoDS::Face (it.Value());
aTolF = BRep_Tool::Tolerance (aF);
BRepOffset_Inter2d::ConnexIntByInt
(aF, theMapSF(aF), theMES, theBuild, theAsDes2d, myOffset, aTolF, aMFV, aDMVV);
(aF, theMapSF (aF), theMES, theBuild, theAsDes2d, myOffset, aTolF, myAnalyse, aMFV, aDMVV);
}
// intersect edges created from vertices
Standard_Integer i, aNbF = aMFV.Extent();
@@ -3846,7 +3913,7 @@ void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
const TopoDS_Face& aF = TopoDS::Face(aMFV(i));
aTolF = BRep_Tool::Tolerance(aF);
BRepOffset_Inter2d::ConnexIntByIntInVert
(aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, aTolF, aDMVV);
(aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, aTolF, myAnalyse, aDMVV);
}
//
// fuse vertices on edges
@@ -3859,6 +3926,7 @@ void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
//=======================================================================
void TrimEdges(const TopoDS_Shape& theShape,
const Standard_Real theOffset,
const BRepOffset_Analyse& Analyse,
BRepOffset_DataMapOfShapeOffset& theMapSF,
TopTools_DataMapOfShapeShape& theMES,
TopTools_DataMapOfShapeShape& theBuild,
@@ -3872,9 +3940,24 @@ void TrimEdges(const TopoDS_Shape& theShape,
TopoDS_Shape NE;
TopoDS_Edge TNE;
TopoDS_Face NF;
//
for (Exp.Init(theShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
TopTools_ListOfShape aLFaces;
for (Exp.Init (theShape, TopAbs_FACE); Exp.More(); Exp.Next())
aLFaces.Append (Exp.Current());
TopTools_MapOfShape aMFGenerated;
TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
for (TopTools_ListOfShape::Iterator it (Analyse.NewFaces()); it.More(); it.Next())
{
const TopoDS_Shape& aFG = it.Value();
aLFaces.Append (aFG);
aMFGenerated.Add (aFG);
TopExp::MapShapesAndUniqueAncestors (aFG, TopAbs_EDGE, TopAbs_FACE, aDMEF);
}
for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
{
const TopoDS_Face& FI = TopoDS::Face (it.Value());
NF = theMapSF(FI).Face();
if (theMES.IsBound(NF)) {
NF = TopoDS::Face(theMES(NF));
@@ -3937,7 +4020,9 @@ void TrimEdges(const TopoDS_Shape& theShape,
if (aS.ShapeType() != TopAbs_EDGE) {
continue;
}
//
if (aMFGenerated.Contains (FI) && aDMEF.FindFromKey (aS).Extent() == 1)
continue;
NE = theMapSF(FI).Generated(aS);
//// modified by jgv, 19.12.03 for OCC4455 ////
NE.Orientation(aS.Orientation());
@@ -4068,22 +4153,21 @@ void TrimEdge(TopoDS_Edge& NE,
//function : GetEnlargedFaces
//purpose :
//=======================================================================
void GetEnlargedFaces(const TopoDS_Shape& theShape,
void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
const BRepOffset_DataMapOfShapeOffset& theMapSF,
const TopTools_DataMapOfShapeShape& theMES,
TopTools_DataMapOfShapeShape& theFacesOrigins,
BRepAlgo_Image& theImage,
TopTools_ListOfShape& theLSF)
{
TopExp_Explorer aExp(theShape, TopAbs_FACE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& FI = aExp.Current();
for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
{
const TopoDS_Shape& FI = it.Value();
const TopoDS_Shape& OFI = theMapSF(FI).Face();
if (theMES.IsBound(OFI)) {
const TopoDS_Face& aLocalFace = TopoDS::Face(theMES(OFI));
theLSF.Append(aLocalFace);
theImage.SetRoot(aLocalFace);
//
theFacesOrigins.Bind(aLocalFace, FI);
}
}
@@ -4246,6 +4330,113 @@ Standard_Boolean BuildShellsCompleteInter(const TopTools_ListOfShape& theLF,
return GetSubShapes(aResult3, TopAbs_SHELL, theShells);
}
//=======================================================================
//function : Generated
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepOffset_MakeOffset::Generated (const TopoDS_Shape& theS)
{
myGenerated.Clear();
const TopAbs_ShapeEnum aType = theS.ShapeType();
switch (aType)
{
case TopAbs_VERTEX:
{
if (myAnalyse.HasAncestor (theS))
{
TopTools_MapOfShape aMFence;
const TopTools_ListOfShape& aLA = myAnalyse.Ancestors (theS);
TopTools_ListOfShape::Iterator itLA (aLA);
for (; myGenerated.IsEmpty() && itLA.More(); itLA.Next())
{
const TopoDS_Shape& aE = itLA.Value();
if (!myInitOffsetEdge.HasImage (aE))
continue;
TopTools_ListOfShape aLEIm;
myInitOffsetEdge.LastImage (aE, aLEIm);
TopTools_ListOfShape::Iterator itLEIm (aLEIm);
for (; myGenerated.IsEmpty() && itLEIm.More(); itLEIm.Next())
{
TopoDS_Iterator itV (itLEIm.Value());
for (; itV.More(); itV.Next())
{
if (!aMFence.Add (itV.Value()))
{
myGenerated.Append (itV.Value());
break;
}
}
}
}
}
}
Standard_FALLTHROUGH
case TopAbs_EDGE:
{
if (myInitOffsetEdge.HasImage (theS))
{
myInitOffsetEdge.LastImage (theS, myGenerated);
}
}
Standard_FALLTHROUGH
case TopAbs_FACE:
{
if (myInitOffsetFace.HasImage (theS))
{
myInitOffsetFace.LastImage (theS, myGenerated);
}
break;
}
case TopAbs_SOLID:
{
if (theS.IsSame (myShape))
myGenerated.Append (myOffsetShape);
break;
}
default:
break;
}
if (myResMap.IsEmpty())
TopExp::MapShapes (myOffsetShape, myResMap);
for (TopTools_ListOfShape::Iterator it (myGenerated); it.More();)
{
if (myResMap.Contains (it.Value()))
it.Next();
else
myGenerated.Remove (it);
}
return myGenerated;
}
//=======================================================================
//function : Modified
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepOffset_MakeOffset::Modified (const TopoDS_Shape&)
{
myGenerated.Clear();
return myGenerated;
}
//=======================================================================
//function : IsDeleted
//purpose :
//=======================================================================
Standard_Boolean BRepOffset_MakeOffset::IsDeleted (const TopoDS_Shape& theS)
{
if (myResMap.IsEmpty())
TopExp::MapShapes (myOffsetShape, myResMap);
if (myResMap.Contains (theS))
return Standard_False;
return Generated (theS).IsEmpty()
&& Modified (theS).IsEmpty();
}
//=======================================================================
//function : GetSubShapes
//purpose :

View File

@@ -92,6 +92,11 @@ public:
Standard_EXPORT const TopoDS_Shape& Shape() const;
const TopoDS_Shape& InitShape() const
{
return myShape;
}
//! returns information about offset state.
Standard_EXPORT BRepOffset_Error Error() const;
@@ -121,6 +126,17 @@ public:
//! Return bad shape, which obtained in CheckInputData.
Standard_EXPORT const TopoDS_Shape& GetBadShape() const;
public: //! @name History methods
//! Returns the list of shapes generated from the shape <S>.
Standard_EXPORT const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS);
//! Returns the list of shapes modified from the shape <S>.
Standard_EXPORT const TopTools_ListOfShape& Modified (const TopoDS_Shape& theS);
//! Returns true if the shape S has been deleted.
Standard_EXPORT Standard_Boolean IsDeleted (const TopoDS_Shape& S);
protected:
@@ -152,6 +168,9 @@ private:
Standard_EXPORT void EncodeRegularity();
//! Replace roots in history maps
Standard_EXPORT void ReplaceRoots();
Standard_EXPORT void MakeSolid();
Standard_EXPORT void ToContext (BRepOffset_DataMapOfShapeOffset& MapSF);
@@ -169,7 +188,7 @@ private:
Standard_EXPORT void RemoveInternalEdges();
//! Intersects edges
Standard_EXPORT void IntersectEdges (const TopoDS_Shape& theShape,
Standard_EXPORT void IntersectEdges (const TopTools_ListOfShape& theFaces,
BRepOffset_DataMapOfShapeOffset& theMapSF,
TopTools_DataMapOfShapeShape& theMES,
TopTools_DataMapOfShapeShape& theBuild,
@@ -181,6 +200,7 @@ private:
//! for BRepOffset_MakeLoops::Build method.
//! Currently the Complete intersection mode is limited to work only on planar cases.
Standard_EXPORT void BuildSplitsOfExtendedFaces(const TopTools_ListOfShape& theLF,
const BRepOffset_Analyse& theAnalyse,
Handle(BRepAlgo_AsDes)& theAsDes,
TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
TopTools_DataMapOfShapeShape& theFacesOrigins,
@@ -217,7 +237,8 @@ private:
Standard_Boolean myIsPerformSewing; // Handle bad walls in thicksolid mode.
Standard_Boolean myIsPlanar;
TopoDS_Shape myBadShape;
TopTools_ListOfShape myGenerated;
TopTools_MapOfShape myResMap;
};
#endif // _BRepOffset_MakeOffset_HeaderFile

View File

@@ -107,6 +107,7 @@ static
void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
const TopTools_MapOfShape& theModifiedEdges,
const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
const BRepOffset_Analyse* theAnalyse,
Handle(BRepAlgo_AsDes)& theAsDes,
TopTools_DataMapOfShapeShape& theFacesOrigins,
TopTools_DataMapOfShapeListOfShape& theOEImages,
@@ -155,6 +156,7 @@ static
const TopTools_ListOfShape& theLFImages,
const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
const TopTools_DataMapOfShapeShape& theFacesOrigins,
const BRepOffset_Analyse* theAnalyse,
const TopTools_DataMapOfShapeListOfShape& theOEImages,
const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
TopTools_IndexedMapOfShape& theInvEdges,
@@ -594,6 +596,7 @@ static
static
Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
const TopoDS_Shape& theSWhere,
const BRepOffset_Analyse* theAnalyse,
TopoDS_Shape& theRes);
static
@@ -667,6 +670,7 @@ void BRepOffset_MakeOffset::BuildSplitsOfTrimmedFaces(const TopTools_ListOfShape
// these invalidities will be rebuilt.
//=======================================================================
void BRepOffset_MakeOffset::BuildSplitsOfExtendedFaces(const TopTools_ListOfShape& theLF,
const BRepOffset_Analyse& theAnalyse,
Handle(BRepAlgo_AsDes)& theAsDes,
TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
TopTools_DataMapOfShapeShape& theFacesOrigins,
@@ -704,7 +708,7 @@ void BRepOffset_MakeOffset::BuildSplitsOfExtendedFaces(const TopTools_ListOfShap
// solid build from the new splits
TopoDS_Shape aSolids;
// now we can split the faces
BuildSplitsOfFaces(theLF, aNewEdges, theEdgesOrigins, theAsDes, theFacesOrigins,
BuildSplitsOfFaces(theLF, aNewEdges, theEdgesOrigins, &theAnalyse, theAsDes, theFacesOrigins,
anOEImages, anOEOrigins, aLastInvEdges, anEdgesToAvoid, anInvEdges, aValidEdges,
anInvertedEdges, anAlreadyInvFaces, anInvFaces, anArtInvFaces, aFImages,
aDMFNewHoles, aSolids, aSSInterfs);
@@ -778,7 +782,7 @@ void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theF
//
TopoDS_Shape aSolids;
//
BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, theAsDes, theFacesOrigins,
BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, NULL, theAsDes, theFacesOrigins,
theOEImages, theOEOrigins, theLastInvEdges, theEdgesToAvoid, anInvEdges, theValidEdges,
anInvertedEdges, theAlreadyInvFaces, anInvFaces, anArtInvFaces, theFImages,
theDMFNewHoles, aSolids, aSSInterfs);
@@ -805,6 +809,7 @@ void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theF
void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
const TopTools_MapOfShape& theModifiedEdges,
const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
const BRepOffset_Analyse* theAnalyse,
Handle(BRepAlgo_AsDes)& theAsDes,
TopTools_DataMapOfShapeShape& theFacesOrigins,
TopTools_DataMapOfShapeListOfShape& theOEImages,
@@ -961,7 +966,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
}
//
// find invalid edges
FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, theOEImages,
FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, theAnalyse, theOEImages,
theOEOrigins, theInvEdges, theValidEdges, aDMFLVE, aDMFLNE, aDMFLIE,
aDMFLVIE, aDMEOrLEIm, theInvertedEdges, aMEdgeInvalidByVertex);
//
@@ -1552,6 +1557,7 @@ void FindInvalidEdges(const TopoDS_Face& theF,
const TopTools_ListOfShape& theLFImages,
const TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
const TopTools_DataMapOfShapeShape& theFacesOrigins,
const BRepOffset_Analyse* theAnalyse,
const TopTools_DataMapOfShapeListOfShape& theOEImages,
const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
TopTools_IndexedMapOfShape& theInvEdges,
@@ -1655,9 +1661,9 @@ void FindInvalidEdges(const TopoDS_Face& theF,
}
}
//
TopTools_MapOfShape aME, aMV;
TopTools_MapOfShape aME, aMV, aMF;
Standard_Boolean bInvalid = Standard_False, bChecked = Standard_False;
Standard_Integer aNbP = NbPoints(aEIm);
Standard_Integer aNbP = NbPoints(aEIm), aNbInv = 0;
Standard_Boolean bUseVertex = !aNbVOr ? Standard_False :
(aNbVOr == 1 &&
aDMEF.FindFromKey(aEIm).Extent() == 1 &&
@@ -1693,7 +1699,7 @@ void FindInvalidEdges(const TopoDS_Face& theF,
}
}
else {
FindShape(aSOr, aFOr, aEOrF);
FindShape(aSOr, aFOr, theAnalyse, aEOrF);
//
TopTools_ListOfShape *pLEIm = theDMEOrLEIm.ChangeSeek(aSOr);
if (!pLEIm) {
@@ -1732,10 +1738,17 @@ void FindInvalidEdges(const TopoDS_Face& theF,
const TopoDS_Shape& aV = aExpE.Current();
aMV.Add(aV);
}
if (theAnalyse)
{
for (TopTools_ListOfShape::Iterator itFA (theAnalyse->Ancestors (aEOrF));
itFA.More(); itFA.Next())
aMF.Add (itFA.Value());
}
}
//
if (aCos < Precision::Confusion()) {
bInvalid = Standard_True;
aNbInv++;
if (bVertex) {
theEdgesInvalidByVertex.Add(aEIm);
}
@@ -1747,25 +1760,55 @@ void FindInvalidEdges(const TopoDS_Face& theF,
continue;
}
//
Standard_Boolean bLocalOnly = Standard_False;
Standard_Integer aNbE = aME.Extent(), aNbV = aMV.Extent();
if ((aNbE > 1) && (aNbV == 2*aNbE)) {
continue;
if (aNbE > 1 && aNbV == 2*aNbE)
{
Standard_Boolean bSkip = Standard_True;
// Allow the edge to be analyzed if it is:
// * originated from more than two faces
// * unanimously considered valid or invalid
// * not a boundary edge in the splits
if (aMF.Extent () > 2 && (aNbInv == 0 || aNbInv == aNbE))
{
if (theLFImages.Extent() > 2)
{
TopoDS_Iterator itV (aEIm);
for (; itV.More(); itV.Next())
{
TopTools_ListOfShape::Iterator itE (aDMVE.FindFromKey (itV.Value()));
for (; itE.More(); itE.Next())
if (aDMEF.FindFromKey (itE.Value()).Extent() < 2)
break;
if (itE.More())
break;
}
bSkip = itV.More();
}
}
if (bSkip)
continue;
else
bLocalOnly = Standard_True;
}
//
if (bInvalid) {
theInvEdges.Add(aEIm);
if (!bLocalOnly)
theInvEdges.Add(aEIm);
aLIE.Append(aEIm);
aMEInv.Add(aEIm);
continue;
}
//
// check if the edge has been inverted
Standard_Boolean bInverted = !aNbE ? Standard_False :
Standard_Boolean bInverted = !aNbE || bLocalOnly ? Standard_False :
CheckInverted(aEIm, aFOr, theOEImages, theOEOrigins,
theEdgesOrigins, aDMVE, aMEdges, theMEInverted);
//
if (!bInverted || !aNbVOr) {
theValidEdges.Add(aEIm);
if (!bLocalOnly)
theValidEdges.Add(aEIm);
aLVE.Append(aEIm);
aMEVal.Add(aEIm);
}
@@ -1927,8 +1970,9 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
//
bValid = theValidEdges.Contains(aEIm);
bInvalid = theInvEdges.Contains(aEIm);
bNeutral = aMEN.Contains(aEIm);
//
if (!bValid && !bInvalid) {
if (!bValid && !bInvalid && !bNeutral) {
// edge has not been checked for some reason
continue;
}
@@ -1936,16 +1980,15 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
++aNbChecked;
//
bInvalidLoc = aMIE.Contains(aEIm);
bHasReallyInvalid = bInvalidLoc && !bValid && !theEdgesInvalidByVertex.Contains(aEIm);
bHasReallyInvalid = bInvalid && bInvalidLoc && !bValid && !theEdgesInvalidByVertex.Contains(aEIm);
if (bHasReallyInvalid) {
break;
}
//
bNeutral = aMEN.Contains(aEIm);
bValidLoc = aMVE.Contains(aEIm);
//
bInverted = theMEInverted.Contains(aEIm);
if (!bInvalid && bTreatInvertedAsInvalid) {
if (!bInvalid && !bInvalidLoc && bTreatInvertedAsInvalid) {
bInvalid = bInverted;
}
//
@@ -1954,7 +1997,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
}
//
bAllValid &= bValidLoc;
bAllInvalid &= bInvalid;
bAllInvalid &= (bInvalid || bInvalidLoc);
bAllInvNeutral &= (bAllInvalid && bNeutral);
bIsInvalidByInverted &= (bInvalidLoc || bInverted);
}
@@ -2399,7 +2442,7 @@ Standard_Boolean CheckInverted(const TopoDS_Edge& theEIm,
const TopoDS_Shape& aEO = aItLOE.Value();
if (aEO.ShapeType() == TopAbs_EDGE && aMFence.Add(aEO)) {
TopoDS_Shape aEOin;
if (FindShape(aEO, theFOr, aEOin)) {
if (FindShape(aEO, theFOr, NULL, aEOin)) {
AppendToList(aLOE, aEO);
}
}
@@ -3105,7 +3148,7 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
const TopoDS_Shape& aFSol = pLSols->First();
//
TopoDS_Shape aFx;
if (!FindShape(aFInvIm, aFSol, aFx)) {
if (!FindShape(aFInvIm, aFSol, NULL, aFx)) {
continue;
}
//
@@ -7118,6 +7161,7 @@ Standard_Integer NbPoints(const TopoDS_Edge& theEdge)
//=======================================================================
Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
const TopoDS_Shape& theSWhere,
const BRepOffset_Analyse* theAnalyse,
TopoDS_Shape& theRes)
{
Standard_Boolean bFound = Standard_False;
@@ -7131,6 +7175,25 @@ Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
break;
}
}
if (!bFound && theAnalyse)
{
const TopTools_ListOfShape *pLD = theAnalyse->Descendants (theSWhere);
if (pLD)
{
for (TopTools_ListOfShape::Iterator it (*pLD); it.More(); it.Next())
{
const TopoDS_Shape& aS = it.Value();
if (aS.IsSame (theSWhat))
{
theRes = aS;
bFound = Standard_True;
break;
}
}
}
}
return bFound;
}

View File

@@ -1613,50 +1613,52 @@ TopoDS_Shape BRepOffset_Offset::Generated(const TopoDS_Shape& Shape) const
{
TopoDS_Shape aShape;
switch ( myShape.ShapeType()) {
case TopAbs_FACE:
switch ( myShape.ShapeType())
{
case TopAbs_FACE:
{
TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
TopExp_Explorer expo(myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE);
for ( ; exp.More() && expo.More(); exp.Next(), expo.Next()) {
if ( Shape.IsSame(exp.Current())) {
if ( myShape.Orientation() == TopAbs_REVERSED)
aShape = expo.Current().Reversed();
else
aShape = expo.Current();
}
TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
TopExp_Explorer expo (myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE);
for (; exp.More() && expo.More(); exp.Next(), expo.Next())
{
if (Shape.IsSame (exp.Current()))
{
if (myShape.Orientation() == TopAbs_REVERSED)
aShape = expo.Current().Reversed();
else
aShape = expo.Current();
break;
}
}
}
break;
case TopAbs_EDGE:
case TopAbs_EDGE:
// have generate a pipe.
{
TopoDS_Vertex V1, V2;
TopExp::Vertices(TopoDS::Edge(myShape), V1, V2);
TopExp_Explorer expf(myFace .Oriented(TopAbs_FORWARD), TopAbs_WIRE);
TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD),
TopAbs_EDGE);
TopExp_Explorer expf(myFace.Oriented(TopAbs_FORWARD), TopAbs_WIRE);
TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD), TopAbs_EDGE);
expo.Next();
expo.Next();
if ( V2.IsSame(Shape)) {
if ( expf.Current().Orientation() == TopAbs_REVERSED)
aShape = expo.Current().Reversed();
else
aShape = expo.Current();
if (expf.Current().Orientation() == TopAbs_REVERSED)
aShape = expo.Current().Reversed();
else
aShape = expo.Current();
}
else {
expo.Next();
if ( expf.Current().Orientation() == TopAbs_REVERSED)
aShape = expo.Current().Reversed();
else
aShape = expo.Current();
expo.Next();
if (expf.Current().Orientation() == TopAbs_REVERSED)
aShape = expo.Current().Reversed();
else
aShape = expo.Current();
}
if ( myFace.Orientation() == TopAbs_REVERSED)
aShape.Reverse();
if (myFace.Orientation() == TopAbs_REVERSED)
aShape.Reverse();
}
break;
default:

View File

@@ -2948,7 +2948,11 @@ static void CompactUVBounds (const TopoDS_Face& F,
C.D0(U2,P);
B.Add(P);
}
B.Get(UMin,VMin,UMax,VMax);
if (!B.IsVoid())
B.Get(UMin,VMin,UMax,VMax);
else
BRep_Tool::Surface(F)->Bounds (UMin, UMax, VMin, VMax);
}
//=======================================================================

View File

@@ -118,24 +118,14 @@ void BRepOffsetAPI_MakeOffsetShape::Build()
const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::Generated (const TopoDS_Shape& S)
{
myGenerated.Clear();
if (myLastUsedAlgo == OffsetAlgo_JOIN && !myOffsetShape.ClosingFaces().Contains(S))
if (myLastUsedAlgo == OffsetAlgo_JOIN)
{
myOffsetShape.OffsetFacesFromShapes ().LastImage (S, myGenerated);
if (!myOffsetShape.ClosingFaces().IsEmpty())
{
// Reverse generated shapes in case of small solids.
// Useful only for faces without influence on others.
TopTools_ListIteratorOfListOfShape it(myGenerated);
for (; it.More(); it.Next())
it.Value().Reverse();
}
myGenerated = myOffsetShape.Generated (S);
}
else if (myLastUsedAlgo == OffsetAlgo_SIMPLE)
{
TopoDS_Shape aGenShape = mySimpleOffsetShape.Generated(S);
if (!aGenShape.IsNull())
if (!aGenShape.IsNull() && !aGenShape.IsSame (S))
myGenerated.Append(aGenShape);
}
@@ -143,33 +133,39 @@ const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::Generated (const Topo
}
//=======================================================================
//function : GeneratedEdge
//function : Modified
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::GeneratedEdge (const TopoDS_Shape& S)
const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::Modified (const TopoDS_Shape& S)
{
myGenerated.Clear();
if (myLastUsedAlgo == OffsetAlgo_JOIN)
{
myOffsetShape.OffsetEdgesFromShapes().LastImage (S, myGenerated);
if (!myGenerated.IsEmpty())
{
if (S.IsSame(myGenerated.First()))
myGenerated.RemoveFirst();
}
myGenerated = myOffsetShape.Modified (S);
}
else if (myLastUsedAlgo == OffsetAlgo_SIMPLE)
{
TopoDS_Shape aGenShape = mySimpleOffsetShape.Generated(S);
if (!aGenShape.IsNull())
TopoDS_Shape aGenShape = mySimpleOffsetShape.Modified(S);
if (!aGenShape.IsNull() && !aGenShape.IsSame (S))
myGenerated.Append(aGenShape);
}
return myGenerated;
}
//=======================================================================
//function : IsDeleted
//purpose :
//=======================================================================
Standard_Boolean BRepOffsetAPI_MakeOffsetShape::IsDeleted (const TopoDS_Shape& S)
{
if (myLastUsedAlgo == OffsetAlgo_JOIN)
{
return myOffsetShape.IsDeleted(S);
}
return Standard_False;
}
//=======================================================================
//function : GetJoinType
//purpose : Query offset join type.

View File

@@ -133,12 +133,15 @@ public:
//! Does nothing.
Standard_EXPORT virtual void Build() Standard_OVERRIDE;
//! Returns the list of shapes generated from the shape <S>.
//! Returns the list of shapes generated from the shape <S>.
Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& S) Standard_OVERRIDE;
//! Returns the list of edges generated from the shape <S>.
Standard_EXPORT const TopTools_ListOfShape& GeneratedEdge (const TopoDS_Shape& S);
//! Returns the list of shapes Modified from the shape <S>.
Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& S) Standard_OVERRIDE;
//! Returns true if the shape has been removed from the result.
Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& S) Standard_OVERRIDE;
//! Returns offset join type.
Standard_EXPORT GeomAbs_JoinType GetJoinType() const;

View File

@@ -1132,6 +1132,14 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands,
reportOffsetState(theCommands, aRetCode);
}
// Store the history of Boolean operation into the session
if (BRepTest_Objects::IsHistoryNeeded())
{
TopTools_ListOfShape aLA;
aLA.Append (TheOffset.InitShape());
BRepTest_Objects::SetHistory<BRepOffset_MakeOffset>(aLA, TheOffset);
}
return 0;
}

View File

@@ -55,6 +55,8 @@ ChFiDS_TypeOfConcavity ChFi3d::DefineConnectType(const TopoDS_Edge& E,
if (F1.IsSame(F2))
EE.Reverse();
Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(EE,F2,f,l);
if (C1.IsNull() || C2.IsNull())
return ChFiDS_Other;
BRepAdaptor_Curve C(E);
f = C.FirstParameter();