#include <BOPTools_AlgoTools3D.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools2D.hxx>
+#include <BOPTools_Set.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_ShrunkRange.hxx>
static
void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
const TopTools_MapOfShape& theModifiedEdges,
+ const BRepOffset_Analyse* theAnalyse,
TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
TopTools_MapOfShape& theEdgesInvalidByVertex,
TopTools_MapOfShape& theEdgesValidByVertex);
+static
+ void FindInvalidEdges (const TopTools_ListOfShape& theLFOffset,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
+ const TopTools_DataMapOfShapeShape& theFacesOrigins,
+ const BRepOffset_Analyse* theAnalyse,
+ const TopTools_IndexedMapOfShape& theInvEdges,
+ const TopTools_IndexedMapOfShape& theValidEdges,
+ BRepOffset_DataMapOfShapeIndexedMapOfShape& theLocInvEdges,
+ BRepOffset_DataMapOfShapeMapOfShape& theLocValidEdges,
+ BRepOffset_DataMapOfShapeMapOfShape& theNeutralEdges);
+
static
void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
const TopTools_IndexedMapOfShape& theInvEdges,
const TopTools_MapOfShape& theFSelfRebAvoid,
const TopoDS_Shape& theSolids,
const TopTools_DataMapOfShapeListOfShape& theSSInterfs,
+ const BRepOffset_Analyse* theAnalyse,
TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
if (aFToRebuild.Extent()) {
// vertices to avoid
TopTools_MapOfShape aVAEmpty;
- RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, aFImages, aDMFNewHoles,
+ RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, &theAnalyse, aFImages, aDMFNewHoles,
theEdgesOrigins, theFacesOrigins, anOEImages, anOEOrigins, aLastInvEdges,
anEdgesToAvoid, anInvEdges, aValidEdges, anInvertedEdges, anAlreadyInvFaces,
anInvFaces, anArtInvFaces, aVAEmpty, theETrimEInf, theAsDes);
//=======================================================================
void BuildSplitsOfInvFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
const TopTools_MapOfShape& theModifiedEdges,
+ const BRepOffset_Analyse* theAnalyse,
TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
//
TopoDS_Shape aSolids;
//
- BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, NULL, theAsDes, theFacesOrigins,
+ BuildSplitsOfFaces(aLF, theModifiedEdges, theEdgesOrigins, theAnalyse, theAsDes, theFacesOrigins,
theOEImages, theOEOrigins, theLastInvEdges, theEdgesToAvoid, anInvEdges, theValidEdges,
anInvertedEdges, theAlreadyInvFaces, anInvFaces, anArtInvFaces, theFImages,
theDMFNewHoles, aSolids, aSSInterfs);
FindFacesToRebuild(theFImages, anInvEdges, anInvFaces, aSSInterfs, aFToRebuild, aFSelfRebAvoid);
//
if (aFToRebuild.Extent()) {
- RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, theFImages, theDMFNewHoles,
+ RebuildFaces(aFToRebuild, aFSelfRebAvoid, aSolids, aSSInterfs, theAnalyse, theFImages, theDMFNewHoles,
theEdgesOrigins, theFacesOrigins, theOEImages, theOEOrigins, theLastInvEdges,
theEdgesToAvoid, anInvEdges, theValidEdges, anInvertedEdges, theAlreadyInvFaces,
anInvFaces, anArtInvFaces, theVertsToAvoid, theETrimEInf, theAsDes);
if (theInvEdges.IsEmpty() && theArtInvFaces.IsEmpty() && aDMFMIE.IsEmpty()) {
return;
}
- //
+
+ // Additional step to find invalid edges by checking unclassified edges
+ // in the splits of SD faces
+ FindInvalidEdges (aLFDone, theFImages, theFacesOrigins, theAnalyse,
+ theInvEdges, theValidEdges, aDMFMIE, aDMFMVE, aDMFMNE);
+
#ifdef OFFSET_DEBUG
// show invalid edges
TopoDS_Compound aCEInv1;
}
}
+namespace
+{
+ static void addAsNeutral (const TopoDS_Shape& theE,
+ const TopoDS_Shape& theFInv,
+ const TopoDS_Shape& theFVal,
+ BRepOffset_DataMapOfShapeIndexedMapOfShape& theLocInvEdges,
+ BRepOffset_DataMapOfShapeMapOfShape& theLocValidEdges)
+ {
+ TopTools_IndexedMapOfShape* pMEInv = theLocInvEdges.ChangeSeek (theFInv);
+ if (!pMEInv)
+ pMEInv = theLocInvEdges.Bound (theFInv, TopTools_IndexedMapOfShape());
+ pMEInv->Add (theE);
+
+ TopTools_MapOfShape* pMEVal = theLocValidEdges.ChangeSeek (theFVal);
+ if (!pMEVal)
+ pMEVal = theLocValidEdges.Bound (theFVal, TopTools_MapOfShape());
+ pMEVal->Add (theE);
+ }
+
+}
+//=======================================================================
+//function : FindInvalidEdges
+//purpose : Additional method to look for invalid faces
+//=======================================================================
+void FindInvalidEdges (const TopTools_ListOfShape& theLFOffset,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
+ const TopTools_DataMapOfShapeShape& theFacesOrigins,
+ const BRepOffset_Analyse* theAnalyse,
+ const TopTools_IndexedMapOfShape& theInvEdges,
+ const TopTools_IndexedMapOfShape& theValidEdges,
+ BRepOffset_DataMapOfShapeIndexedMapOfShape& theLocInvEdges,
+ BRepOffset_DataMapOfShapeMapOfShape& theLocValidEdges,
+ BRepOffset_DataMapOfShapeMapOfShape& theNeutralEdges)
+{
+ // 1. Find edges unclassified in faces
+ // 2. Find SD faces in which the same edge is classified
+ // 3. Check if the edge is neutral in face in which it wasn't classified
+
+ NCollection_IndexedDataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aMEUnclassified;
+ TopTools_DataMapOfShapeShape aFSplitFOffset;
+
+ // Avoid artificial faces
+ TopTools_MapOfShape aNewFaces;
+ if (theAnalyse)
+ {
+ TopTools_MapOfShape aMapNewTmp;
+ for (TopTools_ListOfShape::Iterator it (theAnalyse->NewFaces()); it.More(); it.Next())
+ aMapNewTmp.Add (it.Value());
+
+ for (TopTools_ListOfShape::Iterator it (theLFOffset); it.More(); it.Next())
+ {
+ const TopoDS_Shape& aFOffset = it.Value();
+ const TopoDS_Shape& aFOrigin = theFacesOrigins.Find (aFOffset);
+ if (aMapNewTmp.Contains (aFOrigin))
+ aNewFaces.Add (aFOffset);
+ }
+ }
+
+ TopTools_IndexedDataMapOfShapeListOfShape anEFMap;
+ for (TopTools_ListOfShape::Iterator itLFO (theLFOffset); itLFO.More(); itLFO.Next())
+ {
+ const TopoDS_Shape& aF = itLFO.Value();
+ if (aNewFaces.Contains (aF))
+ continue;
+
+ const TopTools_ListOfShape& aLFImages = theFImages.FindFromKey (aF);
+ for (TopTools_ListOfShape::Iterator itLF (aLFImages); itLF.More(); itLF.Next())
+ {
+ const TopoDS_Shape& aFIm = itLF.Value();
+
+ TopExp::MapShapesAndAncestors (aFIm, TopAbs_EDGE, TopAbs_FACE, anEFMap);
+
+ const TopTools_IndexedMapOfShape* pMEInvalid = theLocInvEdges.Seek (aFIm);
+ const TopTools_MapOfShape* pMEValid = theLocValidEdges.Seek (aFIm);
+
+ for (TopExp_Explorer expE (aFIm, TopAbs_EDGE); expE.More(); expE.Next())
+ {
+ const TopoDS_Shape& aE = expE.Current();
+ if (theInvEdges.Contains (aE) != theValidEdges.Contains (aE))
+ {
+ // edge is classified in some face
+
+ if ((!pMEInvalid || !pMEInvalid->Contains (aE)) &&
+ (!pMEValid || !pMEValid->Contains (aE)))
+ {
+ // but not in the current one
+ TopTools_MapOfShape *pMap = aMEUnclassified.ChangeSeek (aE);
+ if (!pMap)
+ pMap = &aMEUnclassified (aMEUnclassified.Add (aE, TopTools_MapOfShape()));
+ pMap->Add (aFIm);
+
+ aFSplitFOffset.Bind (aFIm, aF);
+ }
+ }
+ }
+ }
+ }
+
+ if (aMEUnclassified.IsEmpty())
+ return;
+
+ // Analyze unclassified edges
+ const Standard_Integer aNbE = aMEUnclassified.Extent();
+ for (Standard_Integer iE = 1; iE <= aNbE; ++iE)
+ {
+ const TopoDS_Shape& aE = aMEUnclassified.FindKey (iE);
+ const TopTools_MapOfShape& aMFUnclassified = aMEUnclassified (iE);
+
+ const TopTools_ListOfShape& aLF = anEFMap.FindFromKey (aE);
+
+ for (TopTools_ListOfShape::Iterator itLF (aLF); itLF.More(); itLF.Next())
+ {
+ const TopoDS_Shape& aFClassified = itLF.Value();
+ if (aMFUnclassified.Contains (aFClassified))
+ continue;
+
+ BOPTools_Set anEdgeSetClass;
+ anEdgeSetClass.Add (aFClassified, TopAbs_EDGE);
+
+ TopoDS_Shape aEClassified;
+ FindShape (aE, aFClassified, NULL, aEClassified);
+ TopAbs_Orientation anOriClass = aEClassified.Orientation();
+
+ gp_Dir aDNClass;
+ BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (TopoDS::Edge (aEClassified), TopoDS::Face (aFClassified), aDNClass);
+
+ const TopTools_IndexedMapOfShape* pMEInvalid = theLocInvEdges.Seek (aFClassified);
+ Standard_Boolean isInvalid = pMEInvalid && pMEInvalid->Contains (aE);
+
+ for (TopTools_MapOfShape::Iterator itM (aMFUnclassified); itM.More(); itM.Next())
+ {
+ const TopoDS_Shape& aFUnclassified = itM.Value();
+
+ BOPTools_Set anEdgeSetUnclass;
+ anEdgeSetUnclass.Add (aFUnclassified, TopAbs_EDGE);
+
+ if (anEdgeSetClass.IsEqual (anEdgeSetUnclass))
+ {
+ gp_Dir aDNUnclass;
+ BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (TopoDS::Edge (aE), TopoDS::Face (aFUnclassified), aDNUnclass);
+
+ Standard_Boolean isSameOri = aDNClass.IsEqual (aDNUnclass, Precision::Angular());
+
+ // Among other splits of the same face find those where the edge is contained with different
+ // orientation
+ const TopoDS_Shape& aFOffset = aFSplitFOffset.Find (aFUnclassified);
+ const TopTools_ListOfShape& aLFSplits = theFImages.FindFromKey (aFOffset);
+ TopTools_ListOfShape::Iterator itLFSp (aLFSplits);
+ for (; itLFSp.More(); itLFSp.Next())
+ {
+ const TopoDS_Shape& aFSp = itLFSp.Value();
+
+ if (!aFSp.IsSame (aFUnclassified) && aMFUnclassified.Contains (aFSp))
+ {
+ TopoDS_Shape aEUnclassified;
+ FindShape (aE, aFSp, NULL, aEUnclassified);
+
+ TopAbs_Orientation anOriUnclass = aEUnclassified.Orientation();
+ if (!isSameOri)
+ anOriUnclass = TopAbs::Reverse (anOriUnclass);
+
+ if (anOriClass != anOriUnclass)
+ {
+ // make the edge neutral for the face
+ TopTools_MapOfShape* pMENeutral = theNeutralEdges.ChangeSeek (aFOffset);
+ if (!pMENeutral)
+ pMENeutral = theNeutralEdges.Bound (aFOffset, TopTools_MapOfShape());
+ pMENeutral->Add (aE);
+
+ if (isInvalid && isSameOri)
+ {
+ // make edge invalid in aFUnclassified and valid in aFSp
+ addAsNeutral (aE, aFClassified, aFSp, theLocInvEdges, theLocValidEdges);
+ }
+ else
+ {
+ // make edge invalid in aFSp and valid in aFUnclassified
+ addAsNeutral (aE, aFSp, aFClassified, theLocInvEdges, theLocValidEdges);
+ }
+ }
+ }
+ }
+ if (itLFSp.More())
+ break;
+ }
+ }
+ }
+ }
+}
+
//=======================================================================
//function : FindInvalidFaces
//purpose : Looking for the invalid faces by analyzing their invalid edges
const TopTools_MapOfShape& theFSelfRebAvoid,
const TopoDS_Shape& theSolids,
const TopTools_DataMapOfShapeListOfShape& theSSInterfs,
+ const BRepOffset_Analyse* theAnalyse,
TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
TopTools_DataMapOfShapeListOfShape& theDMFNewHoles,
TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
theInvFaces, theArtInvFaces, theVertsToAvoid, theETrimEInf, aModifiedEdges, theAsDes);
//
// 2. Repeat steps to build the correct faces
- BuildSplitsOfInvFaces(theFToRebuild, aModifiedEdges, theFImages, theDMFNewHoles, theEdgesOrigins,
+ BuildSplitsOfInvFaces(theFToRebuild, aModifiedEdges, theAnalyse, theFImages, theDMFNewHoles, theEdgesOrigins,
theFacesOrigins, theOEImages, theOEOrigins, theLastInvEdges,
theEdgesToAvoid, theVertsToAvoid, theAlreadyInvFaces, theValidEdges,
theETrimEInf, theAsDes);