mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-03 14:10:33 +03:00
0031307: Modeling Algorithms - Offset algorithm produces incorrect result in mode "Complete" join type "Intersection"
Do not classify edges originated from combination of edges and vertices as the classification will likely be unstable. Mark faces containing valid inverted edges as invalid but do not remove them from valid splits. Extend the debug command DBRep_SetComp to allow different containers for creating the TopoDS_Compound.
This commit is contained in:
@@ -70,6 +70,8 @@
|
||||
|
||||
typedef NCollection_DataMap
|
||||
<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> BRepOffset_DataMapOfShapeMapOfShape;
|
||||
typedef NCollection_DataMap
|
||||
<TopoDS_Shape, TopTools_IndexedMapOfShape, TopTools_ShapeMapHasher> BRepOffset_DataMapOfShapeIndexedMapOfShape;
|
||||
|
||||
static
|
||||
void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF,
|
||||
@@ -161,24 +163,25 @@ static
|
||||
const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
|
||||
TopTools_IndexedMapOfShape& theInvEdges,
|
||||
TopTools_IndexedMapOfShape& theValidEdges,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLVE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLNE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLIE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLVIE,
|
||||
BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE,
|
||||
BRepOffset_DataMapOfShapeMapOfShape& theDMFMNE,
|
||||
BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE,
|
||||
BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm,
|
||||
TopTools_MapOfShape& theMEInverted,
|
||||
TopTools_MapOfShape& theEdgesInvalidByVertex);
|
||||
TopTools_MapOfShape& theEdgesInvalidByVertex,
|
||||
TopTools_MapOfShape& theEdgesValidByVertex);
|
||||
|
||||
static
|
||||
void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
const TopTools_IndexedMapOfShape& theInvEdges,
|
||||
const TopTools_IndexedMapOfShape& theValidEdges,
|
||||
const TopTools_DataMapOfShapeListOfShape& theDMFLVE,
|
||||
const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
|
||||
const TopTools_ListOfShape& theLENeutral,
|
||||
const TopTools_ListOfShape& theLEValInverted,
|
||||
const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE,
|
||||
const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE,
|
||||
const TopTools_MapOfShape& theLENeutral,
|
||||
const TopTools_MapOfShape& theMEInverted,
|
||||
const TopTools_MapOfShape& theEdgesInvalidByVertex,
|
||||
const TopTools_MapOfShape& theEdgesValidByVertex,
|
||||
const TopTools_MapOfShape& theMFHoles,
|
||||
TopTools_IndexedMapOfShape& theMFInvInHole,
|
||||
TopTools_ListOfShape& theInvFaces,
|
||||
@@ -234,6 +237,7 @@ static
|
||||
void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
|
||||
const TopTools_DataMapOfShapeShape& theArtInvFaces,
|
||||
const TopTools_MapOfShape& theMEInverted,
|
||||
const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& theFImages);
|
||||
|
||||
static
|
||||
@@ -286,8 +290,9 @@ static
|
||||
TopTools_DataMapOfShapeListOfShape& theOEOrigins);
|
||||
|
||||
static
|
||||
void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
|
||||
void FilterInvalidFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
|
||||
const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF,
|
||||
const TopTools_IndexedMapOfShape& theInvEdges,
|
||||
const TopTools_IndexedMapOfShape& theMERemoved,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
|
||||
TopTools_DataMapOfShapeShape& theArtInvFaces);
|
||||
@@ -295,7 +300,7 @@ static
|
||||
static
|
||||
void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
|
||||
const TopTools_DataMapOfShapeShape& theArtInvFaces,
|
||||
const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
|
||||
const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE,
|
||||
const TopTools_IndexedMapOfShape& theMERemoved,
|
||||
TopTools_IndexedMapOfShape& theInvEdges);
|
||||
|
||||
@@ -836,18 +841,20 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
//
|
||||
// processed faces
|
||||
TopTools_ListOfShape aLFDone;
|
||||
// extended face - list of neutral edges, i.e. in one splits - valid and in others - invalid
|
||||
TopTools_DataMapOfShapeListOfShape aDMFLNE;
|
||||
// list of valid edges for each face
|
||||
TopTools_DataMapOfShapeListOfShape aDMFLVE;
|
||||
// list of invalid edges for each face
|
||||
TopTools_DataMapOfShapeListOfShape aDMFLIE;
|
||||
// extended face - map of neutral edges, i.e. in one split - valid and in other - invalid
|
||||
BRepOffset_DataMapOfShapeMapOfShape aDMFMNE;
|
||||
// map of valid edges for each face
|
||||
BRepOffset_DataMapOfShapeMapOfShape aDMFMVE;
|
||||
// map of invalid edges for each face
|
||||
BRepOffset_DataMapOfShapeIndexedMapOfShape aDMFMIE;
|
||||
// map of valid inverted edges for the face
|
||||
TopTools_DataMapOfShapeListOfShape aDMFLVIE;
|
||||
BRepOffset_DataMapOfShapeMapOfShape aDMFMVIE;
|
||||
// map of splits to check for internals
|
||||
TopTools_IndexedMapOfShape aMFToCheckInt;
|
||||
// map of edges created from vertex and marked as invalid
|
||||
TopTools_MapOfShape aMEdgeInvalidByVertex;
|
||||
// map of edges created from vertex and marked as valid
|
||||
TopTools_MapOfShape aMEdgeValidByVertex;
|
||||
// connection map from old edges to new ones
|
||||
TopTools_DataMapOfShapeListOfShape aDMEOrLEIm;
|
||||
//
|
||||
@@ -937,7 +944,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
}
|
||||
//
|
||||
if (bArtificialCase) {
|
||||
TopTools_ListOfShape aLEInv;
|
||||
TopTools_IndexedMapOfShape aMEInv;
|
||||
// make the face invalid
|
||||
theArtInvFaces.Bind(aF, aCE);
|
||||
//
|
||||
@@ -950,7 +957,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
const TopoDS_Shape& aE = aExpE.Current();
|
||||
if (aMapEInv.Contains(aE)) {
|
||||
theInvEdges.Add(aE);
|
||||
AppendToList(aLEInv, aE);
|
||||
aMEInv.Add (aE);
|
||||
}
|
||||
else {
|
||||
theValidEdges.Add(aE);
|
||||
@@ -958,7 +965,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
}
|
||||
}
|
||||
//
|
||||
aDMFLIE.Bind(aF, aLEInv);
|
||||
aDMFMIE.Bind(aF, aMEInv);
|
||||
aLFDone.Append(aF);
|
||||
//
|
||||
continue;
|
||||
@@ -967,8 +974,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
//
|
||||
// find invalid edges
|
||||
FindInvalidEdges(aF, aLFImages, theEdgesOrigins, theFacesOrigins, theAnalyse, theOEImages,
|
||||
theOEOrigins, theInvEdges, theValidEdges, aDMFLVE, aDMFLNE, aDMFLIE,
|
||||
aDMFLVIE, aDMEOrLEIm, theInvertedEdges, aMEdgeInvalidByVertex);
|
||||
theOEOrigins, theInvEdges, theValidEdges, aDMFMVE, aDMFMNE, aDMFMIE,
|
||||
aDMFMVIE, aDMEOrLEIm, theInvertedEdges, aMEdgeInvalidByVertex, aMEdgeValidByVertex);
|
||||
//
|
||||
// save the new splits
|
||||
if (!pLFIm) {
|
||||
@@ -982,7 +989,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
aLFDone.Append(aF);
|
||||
}
|
||||
//
|
||||
if (theInvEdges.IsEmpty() && theArtInvFaces.IsEmpty()) {
|
||||
if (theInvEdges.IsEmpty() && theArtInvFaces.IsEmpty() && aDMFMIE.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
@@ -1035,7 +1042,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
}
|
||||
}
|
||||
|
||||
TopTools_ListOfShape anEmptyList;
|
||||
TopTools_MapOfShape anEmptyMap;
|
||||
// invalid faces inside the holes
|
||||
TopTools_IndexedMapOfShape aMFInvInHole;
|
||||
// all hole faces
|
||||
@@ -1055,18 +1062,13 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
if (bArtificialCase) {
|
||||
aLFInv = aLFImages;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// neutral edges
|
||||
TopTools_ListOfShape* pLNE = aDMFLNE.ChangeSeek(aF);
|
||||
if (!pLNE) {
|
||||
pLNE = &anEmptyList;
|
||||
const TopTools_MapOfShape* pMNE = aDMFMNE.ChangeSeek(aF);
|
||||
if (!pMNE) {
|
||||
pMNE = &anEmptyMap;
|
||||
}
|
||||
// valid inverted edges
|
||||
TopTools_ListOfShape* pLIVE = aDMFLVIE.ChangeSeek(aF);
|
||||
if (!pLIVE) {
|
||||
pLIVE = &anEmptyList;
|
||||
}
|
||||
//
|
||||
// find faces inside holes wires
|
||||
TopTools_MapOfShape aMFHoles;
|
||||
const TopoDS_Face& aFOr = TopoDS::Face(theFacesOrigins.Find(aF));
|
||||
@@ -1079,8 +1081,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
}
|
||||
//
|
||||
// find invalid faces
|
||||
FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aDMFLIE,
|
||||
*pLNE, *pLIVE, theInvertedEdges, aMEdgeInvalidByVertex,
|
||||
FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFMVE, aDMFMIE,
|
||||
*pMNE, theInvertedEdges, aMEdgeInvalidByVertex, aMEdgeValidByVertex,
|
||||
aMFHoles, aMFInvInHole, aLFInv, anInvertedFaces);
|
||||
}
|
||||
//
|
||||
@@ -1128,7 +1130,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
}
|
||||
//
|
||||
// remove invalid splits from valid splits
|
||||
RemoveInvalidSplitsFromValid(theInvFaces, theArtInvFaces, theInvertedEdges, theFImages);
|
||||
RemoveInvalidSplitsFromValid (theInvFaces, theArtInvFaces, theInvertedEdges,
|
||||
aDMFMVIE, theFImages);
|
||||
//
|
||||
// remove inside faces
|
||||
TopTools_IndexedMapOfShape aMEInside;
|
||||
@@ -1157,7 +1160,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
FilterEdgesImages(aCFIm, theOEImages, theOEOrigins);
|
||||
//
|
||||
// filter invalid faces
|
||||
FilterInvalidFaces(theFImages, aDMEF, aMEInside, theInvFaces, theArtInvFaces);
|
||||
FilterInvalidFaces(theFImages, aDMEF, theInvEdges, aMEInside, theInvFaces, theArtInvFaces);
|
||||
aNb = theInvFaces.Extent();
|
||||
if (!aNb) {
|
||||
theInvEdges.Clear();
|
||||
@@ -1180,7 +1183,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
|
||||
#endif
|
||||
//
|
||||
// filter invalid edges
|
||||
FilterInvalidEdges(theInvFaces, theArtInvFaces, aDMFLIE, aMERemoved, theInvEdges);
|
||||
FilterInvalidEdges(theInvFaces, theArtInvFaces, aDMFMIE, aMERemoved, theInvEdges);
|
||||
//
|
||||
#ifdef OFFSET_DEBUG
|
||||
// show invalid edges
|
||||
@@ -1562,13 +1565,14 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
|
||||
TopTools_IndexedMapOfShape& theInvEdges,
|
||||
TopTools_IndexedMapOfShape& theValidEdges,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLVE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLNE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLIE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMFLVIE,
|
||||
BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE,
|
||||
BRepOffset_DataMapOfShapeMapOfShape& theDMFMNE,
|
||||
BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE,
|
||||
BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE,
|
||||
TopTools_DataMapOfShapeListOfShape& theDMEOrLEIm,
|
||||
TopTools_MapOfShape& theMEInverted,
|
||||
TopTools_MapOfShape& theEdgesInvalidByVertex)
|
||||
TopTools_MapOfShape& theEdgesInvalidByVertex,
|
||||
TopTools_MapOfShape& theEdgesValidByVertex)
|
||||
{
|
||||
// Edge is considered as invalid in the following cases:
|
||||
// 1. Its orientation on the face has changed comparing to the originals edge and face;
|
||||
@@ -1590,6 +1594,8 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
// maps for checking the inverted edges
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aDMVE, aDMEF;
|
||||
TopTools_IndexedMapOfShape aMEdges;
|
||||
// back map from the original shapes to their offset images
|
||||
TopTools_DataMapOfShapeListOfShape anImages;
|
||||
//
|
||||
TopTools_ListIteratorOfListOfShape aItLF(theLFImages);
|
||||
for (; aItLF.More(); aItLF.Next()) {
|
||||
@@ -1619,6 +1625,22 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
}
|
||||
AppendToList(*pLE, aE);
|
||||
}
|
||||
|
||||
// back map from original edges to their offset images
|
||||
const TopTools_ListOfShape* pLOr = theEdgesOrigins.Seek (aE);
|
||||
if (!pLOr)
|
||||
continue;
|
||||
for (TopTools_ListOfShape::Iterator itOr (*pLOr); itOr.More(); itOr.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSOr = itOr.Value();
|
||||
TopoDS_Shape aSInF;
|
||||
if (!FindShape (aSOr, aFOr, theAnalyse, aSInF))
|
||||
continue;
|
||||
TopTools_ListOfShape* pImages = anImages.ChangeSeek (aSInF);
|
||||
if (!pImages)
|
||||
pImages = anImages.Bound (aSInF, TopTools_ListOfShape());
|
||||
AppendToList (*pImages, aE);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -1631,9 +1653,9 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
|
||||
//
|
||||
// valid edges for this split
|
||||
TopTools_ListOfShape aLVE;
|
||||
TopTools_MapOfShape aMVE;
|
||||
// invalid edges for this split
|
||||
TopTools_ListOfShape aLIE;
|
||||
TopTools_IndexedMapOfShape aMIE;
|
||||
//
|
||||
TopExp_Explorer aExp(aFIm, TopAbs_EDGE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
@@ -1660,6 +1682,8 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
++aNbVOr;
|
||||
}
|
||||
}
|
||||
if (aNbVOr > 1 && (aLEOr.Extent() - aNbVOr) > 1)
|
||||
continue;
|
||||
//
|
||||
TopTools_MapOfShape aME, aMV, aMF;
|
||||
Standard_Boolean bInvalid = Standard_False, bChecked = Standard_False;
|
||||
@@ -1690,12 +1714,22 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
if (pLEFOr) {
|
||||
TopoDS_Compound aCEOr;
|
||||
BRep_Builder().MakeCompound(aCEOr);
|
||||
// Avoid classification of edges originated from vertices
|
||||
// located between tangent edges
|
||||
Standard_Boolean bAllTgt = Standard_True;
|
||||
TopTools_ListIteratorOfListOfShape aItLEFOr(*pLEFOr);
|
||||
for (; aItLEFOr.More(); aItLEFOr.Next()) {
|
||||
gp_Vec aVRef = GetAverageTangent (aItLEFOr.Value(), aNbP);
|
||||
for (; aItLEFOr.More(); aItLEFOr.Next())
|
||||
{
|
||||
const TopoDS_Shape& aEOr = aItLEFOr.Value();
|
||||
BRep_Builder().Add(aCEOr, aEOr);
|
||||
|
||||
gp_Vec aVCur = GetAverageTangent (aEOr, aNbP);
|
||||
if (!aVRef.IsParallel (aVCur, Precision::Angular()))
|
||||
bAllTgt = Standard_False;
|
||||
}
|
||||
aEOrF = aCEOr;
|
||||
if (!bAllTgt)
|
||||
aEOrF = aCEOr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1712,22 +1746,56 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
// the edge has not been found
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Check orientations of the image edge and original edge.
|
||||
// In case the 3d curves are having the same direction the orientations
|
||||
// must be the same. Otherwise the orientations should also be different.
|
||||
//
|
||||
// get average tangent vector for each curve taking into account
|
||||
// the orientations of the edges, i.e. the edge is reversed
|
||||
// the vector is reversed as well
|
||||
gp_Vec aVSum1 = GetAverageTangent(aEIm, aNbP);
|
||||
gp_Vec aVSum2 = GetAverageTangent(aEOrF, aNbP);
|
||||
//
|
||||
aVSum1.Normalize();
|
||||
aVSum2.Normalize();
|
||||
//
|
||||
Standard_Real aCos = aVSum1.Dot(aVSum2);
|
||||
if (!bVertex) {
|
||||
|
||||
if (bVertex)
|
||||
{
|
||||
TopTools_MapOfShape aMVTotal;
|
||||
Standard_Integer aNbChecked = 0;
|
||||
// Just check if the original edges sharing the vertex do not share it any more.
|
||||
for (TopoDS_Iterator it (aEOrF); it.More(); it.Next())
|
||||
{
|
||||
const TopoDS_Shape& aEOr = it.Value();
|
||||
const TopTools_ListOfShape* aLIm = anImages.Seek (aEOr);
|
||||
if (!aLIm)
|
||||
continue;
|
||||
++aNbChecked;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMVLoc;
|
||||
for (TopTools_ListOfShape::Iterator itLIM (*aLIm); itLIM.More(); itLIM.Next())
|
||||
TopExp::MapShapesAndAncestors (itLIM.Value(), TopAbs_VERTEX, TopAbs_EDGE, aMVLoc);
|
||||
for (Standard_Integer i = 1; i <= aMVLoc.Extent(); ++i)
|
||||
{
|
||||
if (aMVLoc(i).Extent() > 1 && !aMVTotal.Add (aMVLoc.FindKey (i)))
|
||||
{
|
||||
bInvalid = Standard_True;
|
||||
theEdgesInvalidByVertex.Add(aEIm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bInvalid)
|
||||
break;
|
||||
}
|
||||
if (!bInvalid && aNbChecked < 2)
|
||||
continue;
|
||||
else
|
||||
theEdgesValidByVertex.Add (aEIm);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Check orientations of the image edge and original edge.
|
||||
// In case the 3d curves are having the same direction the orientations
|
||||
// must be the same. Otherwise the orientations should also be different.
|
||||
//
|
||||
// get average tangent vector for each curve taking into account
|
||||
// the orientations of the edges, i.e. the edge is reversed
|
||||
// the vector is reversed as well
|
||||
gp_Vec aVSum1 = GetAverageTangent(aEIm, aNbP);
|
||||
gp_Vec aVSum2 = GetAverageTangent(aEOrF, aNbP);
|
||||
//
|
||||
aVSum1.Normalize();
|
||||
aVSum2.Normalize();
|
||||
//
|
||||
Standard_Real aCos = aVSum1.Dot(aVSum2);
|
||||
if (Abs(aCos) < 0.9999) {
|
||||
continue;
|
||||
}
|
||||
@@ -1744,13 +1812,10 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
itFA.More(); itFA.Next())
|
||||
aMF.Add (itFA.Value());
|
||||
}
|
||||
}
|
||||
//
|
||||
if (aCos < Precision::Confusion()) {
|
||||
bInvalid = Standard_True;
|
||||
aNbInv++;
|
||||
if (bVertex) {
|
||||
theEdgesInvalidByVertex.Add(aEIm);
|
||||
//
|
||||
if (aCos < Precision::Confusion()) {
|
||||
bInvalid = Standard_True;
|
||||
aNbInv++;
|
||||
}
|
||||
}
|
||||
bChecked = Standard_True;
|
||||
@@ -1760,7 +1825,7 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
continue;
|
||||
}
|
||||
//
|
||||
Standard_Boolean bLocalOnly = Standard_False;
|
||||
Standard_Boolean bLocalOnly = (aNbVOr > 1 && (aLEOr.Extent() - aNbVOr) > 1);
|
||||
Standard_Integer aNbE = aME.Extent(), aNbV = aMV.Extent();
|
||||
if (aNbE > 1 && aNbV == 2*aNbE)
|
||||
{
|
||||
@@ -1796,7 +1861,7 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
if (bInvalid) {
|
||||
if (!bLocalOnly)
|
||||
theInvEdges.Add(aEIm);
|
||||
aLIE.Append(aEIm);
|
||||
aMIE.Add (aEIm);
|
||||
aMEInv.Add(aEIm);
|
||||
continue;
|
||||
}
|
||||
@@ -1809,27 +1874,29 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
if (!bInverted || !aNbVOr) {
|
||||
if (!bLocalOnly)
|
||||
theValidEdges.Add(aEIm);
|
||||
aLVE.Append(aEIm);
|
||||
aMVE.Add (aEIm);
|
||||
aMEVal.Add(aEIm);
|
||||
}
|
||||
}
|
||||
//
|
||||
// valid edges
|
||||
if (aLVE.Extent()) {
|
||||
theDMFLVE.Bind(aFIm, aLVE);
|
||||
if (aMVE.Extent())
|
||||
{
|
||||
theDMFMVE.Bind (aFIm, aMVE);
|
||||
}
|
||||
//
|
||||
// invalid edges
|
||||
if (aLIE.Extent()) {
|
||||
theDMFLIE.Bind(aFIm, aLIE);
|
||||
if (aMIE.Extent())
|
||||
{
|
||||
theDMFMIE.Bind (aFIm, aMIE);
|
||||
}
|
||||
}
|
||||
//
|
||||
// process invalid edges:
|
||||
// check for the inverted edges
|
||||
TopTools_ListOfShape aLVIE;
|
||||
TopTools_MapOfShape aMVIE;
|
||||
// fill neutral edges
|
||||
TopTools_ListOfShape aLNE;
|
||||
TopTools_MapOfShape aMNE;
|
||||
//
|
||||
Standard_Integer i, aNbEInv = aMEInv.Extent();
|
||||
for (i = 1; i <= aNbEInv; ++i) {
|
||||
@@ -1837,8 +1904,9 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
//
|
||||
// neutral edges - on the splits of the same offset face
|
||||
// it is valid for one split and invalid for other
|
||||
if (aMEVal.Contains(aEIm)) {
|
||||
aLNE.Append(aEIm);
|
||||
if (aMEVal.Contains(aEIm))
|
||||
{
|
||||
aMNE.Add (aEIm);
|
||||
continue;
|
||||
}
|
||||
//
|
||||
@@ -1864,18 +1932,20 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
!aMEInv.Contains(aEIm1) && !aMEInt.Contains(aEIm1) &&
|
||||
theMEInverted.Contains(aEIm1)) {
|
||||
theInvEdges.Add(aEIm1);
|
||||
aLVIE.Append(aEIm1);
|
||||
aMVIE.Add (aEIm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
if (aLNE.Extent()) {
|
||||
theDMFLNE.Bind(theF, aLNE);
|
||||
if (aMNE.Extent())
|
||||
{
|
||||
theDMFMNE.Bind (theF, aMNE);
|
||||
}
|
||||
//
|
||||
if (aLVIE.Extent()) {
|
||||
theDMFLVIE.Bind(theF, aLVIE);
|
||||
if (aMVIE.Extent())
|
||||
{
|
||||
theDMFMVIE.Bind (theF, aMVIE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1886,12 +1956,12 @@ void FindInvalidEdges(const TopoDS_Face& theF,
|
||||
void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
const TopTools_IndexedMapOfShape& theInvEdges,
|
||||
const TopTools_IndexedMapOfShape& theValidEdges,
|
||||
const TopTools_DataMapOfShapeListOfShape& theDMFLVE,
|
||||
const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
|
||||
const TopTools_ListOfShape& theLENeutral,
|
||||
const TopTools_ListOfShape& theLEValInverted,
|
||||
const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVE,
|
||||
const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE,
|
||||
const TopTools_MapOfShape& theMENeutral,
|
||||
const TopTools_MapOfShape& theMEInverted,
|
||||
const TopTools_MapOfShape& theEdgesInvalidByVertex,
|
||||
const TopTools_MapOfShape& theEdgesValidByVertex,
|
||||
const TopTools_MapOfShape& theMFHoles,
|
||||
TopTools_IndexedMapOfShape& theMFInvInHole,
|
||||
TopTools_ListOfShape& theInvFaces,
|
||||
@@ -1910,21 +1980,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral;
|
||||
Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral, bInverted;
|
||||
Standard_Boolean bIsInvalidByInverted;
|
||||
Standard_Integer i, aNbChecked;
|
||||
//
|
||||
// neutral edges
|
||||
TopTools_MapOfShape aMEN;
|
||||
for (TopTools_ListIteratorOfListOfShape aItLE(theLENeutral); aItLE.More(); aItLE.Next())
|
||||
{
|
||||
aMEN.Add(aItLE.Value());
|
||||
}
|
||||
//
|
||||
// valid inverted edges
|
||||
TopTools_MapOfShape aMEValInverted;
|
||||
for (TopTools_ListIteratorOfListOfShape aItLE(theLEValInverted); aItLE.More(); aItLE.Next())
|
||||
{
|
||||
aMEValInverted.Add(aItLE.Value());
|
||||
}
|
||||
Standard_Integer aNbChecked;
|
||||
//
|
||||
Standard_Boolean bTreatInvertedAsInvalid = (theLFImages.Extent() == 1);
|
||||
//
|
||||
@@ -1934,26 +1990,22 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
// faces for post treat
|
||||
TopTools_ListOfShape aLFPT;
|
||||
//
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
|
||||
TopTools_ListIteratorOfListOfShape aItLF(theLFImages);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
|
||||
TopExp::MapShapesAndAncestors (aFIm, TopAbs_EDGE, TopAbs_FACE, aDMEF);
|
||||
}
|
||||
|
||||
aItLF.Initialize (theLFImages);
|
||||
for (; aItLF.More(); ) {
|
||||
const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
|
||||
//
|
||||
// valid edges for this split
|
||||
TopTools_MapOfShape aMVE;
|
||||
const TopTools_MapOfShape* pMVE = theDMFMVE.Seek (aFIm);
|
||||
// invalid edges for this split
|
||||
TopTools_MapOfShape aMIE;
|
||||
//
|
||||
for (i = 0; i < 2; ++i) {
|
||||
TopTools_MapOfShape& aME = !i ? aMVE : aMIE;
|
||||
const TopTools_ListOfShape* pLE = !i ? theDMFLVE.Seek(aFIm) : theDMFLIE.Seek(aFIm);
|
||||
if (pLE) {
|
||||
TopTools_ListIteratorOfListOfShape aItLE(*pLE);
|
||||
for (; aItLE.More(); aItLE.Next()) {
|
||||
const TopoDS_Shape& aE = aItLE.Value();
|
||||
aME.Add(aE);
|
||||
}
|
||||
}
|
||||
}
|
||||
const TopTools_IndexedMapOfShape* pMIE = theDMFMIE.Seek (aFIm);
|
||||
//
|
||||
bHasValid = Standard_False;
|
||||
bAllValid = Standard_True;
|
||||
@@ -1970,29 +2022,34 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
//
|
||||
bValid = theValidEdges.Contains(aEIm);
|
||||
bInvalid = theInvEdges.Contains(aEIm);
|
||||
bNeutral = aMEN.Contains(aEIm);
|
||||
bNeutral = theMENeutral.Contains(aEIm);
|
||||
//
|
||||
if (!bValid && !bInvalid && !bNeutral) {
|
||||
// edge has not been checked for some reason
|
||||
continue;
|
||||
}
|
||||
//
|
||||
|
||||
// skip not-boundary edges originated from vertex
|
||||
if ((theEdgesInvalidByVertex.Contains (aEIm) ||
|
||||
theEdgesValidByVertex.Contains (aEIm)) &&
|
||||
aDMEF.FindFromKey (aEIm).Extent() != 1)
|
||||
continue;
|
||||
|
||||
++aNbChecked;
|
||||
//
|
||||
bInvalidLoc = aMIE.Contains(aEIm);
|
||||
bInvalidLoc = pMIE && pMIE->Contains (aEIm);
|
||||
bHasReallyInvalid = bInvalid && bInvalidLoc && !bValid && !theEdgesInvalidByVertex.Contains(aEIm);
|
||||
if (bHasReallyInvalid) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
bValidLoc = aMVE.Contains(aEIm);
|
||||
//
|
||||
bValidLoc = pMVE && pMVE->Contains(aEIm);
|
||||
bInverted = theMEInverted.Contains(aEIm);
|
||||
if (!bInvalid && !bInvalidLoc && bTreatInvertedAsInvalid) {
|
||||
bInvalid = bInverted;
|
||||
}
|
||||
//
|
||||
if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) {
|
||||
if (bValidLoc && bNeutral) {
|
||||
bHasValid = Standard_True;
|
||||
}
|
||||
//
|
||||
@@ -2053,27 +2110,14 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
if (aLFPT.IsEmpty() || aMENRem.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
Standard_Integer aNb = aMENRem.Extent();
|
||||
for (i = 1; i <= aNb; ++i) {
|
||||
aMEN.Remove(aMENRem(i));
|
||||
}
|
||||
//
|
||||
|
||||
// check the splits once more
|
||||
aItLF.Initialize(aLFPT);
|
||||
for (; aItLF.More(); aItLF.Next()) {
|
||||
const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
|
||||
//
|
||||
// valid edges for this split
|
||||
TopTools_MapOfShape aMVE;
|
||||
const TopTools_ListOfShape* pLVE = theDMFLVE.Seek(aFIm);
|
||||
if (pLVE) {
|
||||
TopTools_ListIteratorOfListOfShape aItLE(*pLVE);
|
||||
for (; aItLE.More(); aItLE.Next()) {
|
||||
const TopoDS_Shape& aE = aItLE.Value();
|
||||
aMVE.Add(aE);
|
||||
}
|
||||
}
|
||||
const TopTools_MapOfShape* pMVE = theDMFMVE.Seek(aFIm);
|
||||
//
|
||||
bHasValid = Standard_False;
|
||||
bAllValid = Standard_True;
|
||||
@@ -2086,14 +2130,14 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
|
||||
//
|
||||
bValid = theValidEdges.Contains(aEIm);
|
||||
bInvalid = theInvEdges.Contains(aEIm);
|
||||
bNeutral = aMEN.Contains(aEIm);
|
||||
bValidLoc = aMVE.Contains(aEIm);
|
||||
bNeutral = theMENeutral.Contains(aEIm) && !aMENRem.Contains (aEIm);
|
||||
bValidLoc = pMVE && pMVE->Contains(aEIm);
|
||||
//
|
||||
if (!bInvalid && bTreatInvertedAsInvalid) {
|
||||
bInvalid = theMEInverted.Contains(aEIm);
|
||||
}
|
||||
//
|
||||
if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) {
|
||||
if (bValidLoc && bNeutral) {
|
||||
bHasValid = Standard_True;
|
||||
}
|
||||
//
|
||||
@@ -2836,6 +2880,7 @@ void RemoveInvalidSplitsByInvertedEdges(const TopTools_MapOfShape& theMEInverted
|
||||
void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
|
||||
const TopTools_DataMapOfShapeShape& theArtInvFaces,
|
||||
const TopTools_MapOfShape& theMEInverted,
|
||||
const BRepOffset_DataMapOfShapeMapOfShape& theDMFMVIE,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& theFImages)
|
||||
{
|
||||
// Decide whether to remove the found invalid faces or not.
|
||||
@@ -2911,22 +2956,49 @@ void RemoveInvalidSplitsFromValid(const TopTools_IndexedDataMapOfShapeListOfShap
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
|
||||
TopExp::MapShapesAndAncestors(aCB, TopAbs_EDGE, TopAbs_FACE, aDMEF);
|
||||
//
|
||||
TopTools_DataMapOfShapeListOfShape aDMFF;
|
||||
aExp.Init(aCB, TopAbs_FACE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
const TopoDS_Shape& aFCB = aExp.Current();
|
||||
//
|
||||
TopExp_Explorer aExpE(aFCB, TopAbs_EDGE);
|
||||
for (; aExpE.More(); aExpE.Next()) {
|
||||
const TopoDS_Shape& aECB = aExpE.Current();
|
||||
if (aDMEF.FindFromKey(aECB).Extent() > 1) {
|
||||
if (!theMEInverted.Contains(aECB)) {
|
||||
const TopoDS_Shape& aF = aDMIFOF.Find (aFCB);
|
||||
TopTools_ListOfShape* pList = aDMFF.ChangeSeek (aF);
|
||||
if (!pList)
|
||||
pList = aDMFF.Bound (aF, TopTools_ListOfShape());
|
||||
pList->Append (aFCB);
|
||||
}
|
||||
|
||||
for (TopTools_DataMapOfShapeListOfShape::Iterator itM (aDMFF); itM.More(); itM.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = itM.Key();
|
||||
const TopTools_MapOfShape* pValidInverted = theDMFMVIE.Seek (aF);
|
||||
|
||||
// either remove all of these faces or none.
|
||||
const TopTools_ListOfShape& aLFCB = itM.Value();
|
||||
TopTools_ListOfShape::Iterator itL (aLFCB);
|
||||
for (; itL.More(); itL.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFCB = itL.Value();
|
||||
TopExp_Explorer aExpE(aFCB, TopAbs_EDGE);
|
||||
for (; aExpE.More(); aExpE.Next()) {
|
||||
const TopoDS_Shape& aECB = aExpE.Current();
|
||||
if (pValidInverted && pValidInverted->Contains (aECB))
|
||||
break;
|
||||
if (aDMEF.FindFromKey(aECB).Extent() > 1)
|
||||
{
|
||||
if (!theMEInverted.Contains(aECB))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!aExpE.More())
|
||||
// if one removed - remove all
|
||||
break;
|
||||
}
|
||||
//
|
||||
if (!aExpE.More()) {
|
||||
aMFToRem.Add(aFCB);
|
||||
if (itL.More())
|
||||
{
|
||||
for (itL.Initialize (aLFCB); itL.More(); itL.Next())
|
||||
{
|
||||
aMFToRem.Add (itL.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3752,8 +3824,9 @@ void FilterEdgesImages(const TopoDS_Shape& theS,
|
||||
//function : FilterInvalidFaces
|
||||
//purpose : Filtering of the invalid faces
|
||||
//=======================================================================
|
||||
void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
|
||||
void FilterInvalidFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
|
||||
const TopTools_IndexedDataMapOfShapeListOfShape& theDMEF,
|
||||
const TopTools_IndexedMapOfShape& theInvEdges,
|
||||
const TopTools_IndexedMapOfShape& theMERemoved,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
|
||||
TopTools_DataMapOfShapeShape& theArtInvFaces)
|
||||
@@ -3764,10 +3837,12 @@ void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFIma
|
||||
// do not remove invalid faces if it creates free edges
|
||||
//
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aReallyInvFaces;
|
||||
// Edge-Face connexity map of all splits, both invalid and valid
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aDMEFAll;
|
||||
TopTools_ListIteratorOfListOfShape aItLF;
|
||||
//
|
||||
Standard_Integer i, aNb = theInvFaces.Extent();
|
||||
for (i = 1; i <= aNb; ++i) {
|
||||
const Standard_Integer aNb = theInvFaces.Extent();
|
||||
for (Standard_Integer i = 1; i <= aNb; ++i) {
|
||||
const TopoDS_Shape& aF = theInvFaces.FindKey(i);
|
||||
const TopTools_ListOfShape& aLFInv = theInvFaces(i);
|
||||
//
|
||||
@@ -3785,7 +3860,7 @@ void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFIma
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF);
|
||||
TopTools_ListOfShape& aLFIm = theFImages.ChangeFromKey(aF);
|
||||
Standard_Boolean bInvalid = aLFIm.IsEmpty();
|
||||
//
|
||||
if (!bInvalid) {
|
||||
@@ -3837,6 +3912,55 @@ void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFIma
|
||||
bInvalid = aItLF.More();
|
||||
}
|
||||
}
|
||||
if (bInvalid)
|
||||
{
|
||||
if (aDMEFAll.IsEmpty())
|
||||
{
|
||||
aDMEFAll = theDMEF;
|
||||
for (Standard_Integer iF = 1; iF <= aNb; ++iF)
|
||||
for (TopTools_ListOfShape::Iterator itLFInv (theInvFaces(iF)); itLFInv.More(); itLFInv.Next())
|
||||
TopExp::MapShapesAndAncestors (itLFInv.Value(), TopAbs_EDGE, TopAbs_FACE, aDMEFAll);
|
||||
}
|
||||
|
||||
TopTools_MapOfShape aLocalSplits;
|
||||
for (Standard_Integer j = 0; j < 2; ++j)
|
||||
for (aItLF.Initialize((!j ? aLFIm : aLFInv)); aItLF.More(); aItLF.Next())
|
||||
aLocalSplits.Add (aItLF.Value());
|
||||
|
||||
// Check if all invalid edges are located inside the split and do not touch
|
||||
// any other faces both invalid and valid
|
||||
aItLF.Initialize(aLFInv);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFIm = aItLF.Value();
|
||||
TopExp_Explorer aExp(aFIm, TopAbs_EDGE);
|
||||
for (; aExp.More(); aExp.Next())
|
||||
{
|
||||
const TopoDS_Shape& aE = aExp.Current();
|
||||
if (theInvEdges.Contains (aE) && !theMERemoved.Contains (aE))
|
||||
{
|
||||
const TopTools_ListOfShape& aLF = aDMEFAll.FindFromKey (aE);
|
||||
TopTools_ListOfShape::Iterator itLF (aLF);
|
||||
for (; itLF.More(); itLF.Next())
|
||||
{
|
||||
if (!aLocalSplits.Contains (itLF.Value()))
|
||||
break;
|
||||
}
|
||||
if (itLF.More())
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aExp.More())
|
||||
break;
|
||||
}
|
||||
bInvalid = aItLF.More();
|
||||
if (!bInvalid)
|
||||
{
|
||||
aItLF.Initialize(aLFInv);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
AppendToList (aLFIm, aItLF.Value());
|
||||
}
|
||||
}
|
||||
//
|
||||
if (bInvalid) {
|
||||
aReallyInvFaces.Add(aF, aLFInv);
|
||||
@@ -3852,7 +3976,7 @@ void FilterInvalidFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFIma
|
||||
//=======================================================================
|
||||
void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
|
||||
const TopTools_DataMapOfShapeShape& theArtInvFaces,
|
||||
const TopTools_DataMapOfShapeListOfShape& theDMFLIE,
|
||||
const BRepOffset_DataMapOfShapeIndexedMapOfShape& theDMFMIE,
|
||||
const TopTools_IndexedMapOfShape& theMERemoved,
|
||||
TopTools_IndexedMapOfShape& theInvEdges)
|
||||
{
|
||||
@@ -3907,10 +4031,11 @@ void FilterInvalidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theInvF
|
||||
for (i = 1; i <= aNb; ++i) {
|
||||
const TopoDS_Shape& aF = theInvFaces.FindKey(i);
|
||||
if (theArtInvFaces.IsBound(aF)) {
|
||||
const TopTools_ListOfShape& aLEInv = theDMFLIE.Find(aF);
|
||||
aItLF.Initialize(aLEInv);
|
||||
for (; aItLF.More(); aItLF.Next()) {
|
||||
const TopoDS_Shape& aE = aItLF.Value();
|
||||
const TopTools_IndexedMapOfShape& aMIE = theDMFMIE.Find(aF);
|
||||
const Standard_Integer aNbIE = aMIE.Extent();
|
||||
for (Standard_Integer iE = 1; iE <= aNbIE; ++iE)
|
||||
{
|
||||
const TopoDS_Shape& aE = aMIE (iE);
|
||||
if (aMEInv.Contains(aE) && !aMEInvToAvoid.Contains(aE)) {
|
||||
aReallyInvEdges.Add(aE);
|
||||
}
|
||||
|
Reference in New Issue
Block a user