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

0028245: Result of Cells Builder algorithm becomes invalid after removal of internal boundaries on faces

When removing internal boundaries between faces of the same material do it once for the whole shape, and at this keep boundaries between areas with different material.
This commit is contained in:
imn
2017-07-12 10:52:41 +03:00
committed by bugmaster
parent 7c4ce93bab
commit 385d47dde7
4 changed files with 158 additions and 33 deletions

View File

@@ -19,6 +19,7 @@
#include <BRep_Builder.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <BOPTools.hxx>
@@ -39,6 +40,9 @@ static
void MakeTypedContainers(const TopoDS_Shape& theSC,
TopoDS_Shape& theResult);
static void CollectMaterialBoundaries(const BOPCol_ListOfShape& theLS,
TopTools_MapOfShape& theMapKeepBnd);
//=======================================================================
//function : empty constructor
//purpose :
@@ -267,7 +271,8 @@ void BOPAlgo_CellsBuilder::AddToResult(const BOPCol_ListOfShape& theLSToTake,
BOPCol_ListIteratorOfListOfShape aItLP(aParts);
for (; aItLP.More(); aItLP.Next()) {
const TopoDS_Shape& aPart = aItLP.Value();
if (aResParts.Add(aPart)) {
// provide uniqueness of the parts
if (aResParts.Add(aPart) && !myShapeMaterial.IsBound(aPart)) {
BRep_Builder().Add(myShape, aPart);
bChanged = Standard_True;
}
@@ -459,6 +464,8 @@ void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
// try to remove the internal boundaries between the
// shapes of the same material
BOPCol_DataMapIteratorOfDataMapOfIntegerListOfShape aItM(myMaterials);
BOPCol_ListOfShape aLSUnify[2];
TopTools_MapOfShape aKeepMap[2];
for (; aItM.More(); aItM.Next()) {
Standard_Integer iMaterial = aItM.Key();
BOPCol_ListOfShape& aLS = aItM.ChangeValue();
@@ -485,34 +492,65 @@ void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
break;
}
}
//
BOPCol_ListOfShape aLSNew;
if (aItLS.More()) {
if (aItLS.More())
{
// add the warning
TopoDS_Compound aMultiDimS;
aBB.MakeCompound(aMultiDimS);
aBB.Add(aMultiDimS, aLS.First());
aBB.Add(aMultiDimS, aItLS.Value());
AddWarning(new BOPAlgo_AlertRemovalOfIBForMDimShapes(aMultiDimS));
}
else
{
if (aType == TopAbs_EDGE || aType == TopAbs_FACE)
{
TopoDS_Compound aMultiDimS;
aBB.MakeCompound(aMultiDimS);
aBB.Add(aMultiDimS, aLS.First());
aBB.Add(aMultiDimS, aItLS.Value());
//
AddWarning (new BOPAlgo_AlertRemovalOfIBForMDimShapes (aMultiDimS));
// for edges and faces, just collect shapes to unify them later after exiting the loop;
// collect boundaries of shapes of current material in the keep map
Standard_Integer iType = (aType == TopAbs_EDGE ? 0 : 1);
CollectMaterialBoundaries(aLS, aKeepMap[iType]);
// save shapes to unify later
BOPCol_ListOfShape aCopy(aLS);
aLSUnify[iType].Append(aCopy);
continue;
}
aLSNew.Assign(aLS);
}
else {
if (RemoveInternals(aLS, aLSNew)) {
bChanged = Standard_True;
else
{
// aType is Solid;
// remove internal faces between solids of the same material just now
BOPCol_ListOfShape aLSNew;
if (RemoveInternals(aLS, aLSNew))
{
bChanged = Standard_True;
// update materials maps
for (aItLS.Initialize(aLSNew); aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aS = aItLS.Value();
myShapeMaterial.Bind(aS, iMaterial);
}
aLS.Assign(aLSNew);
}
}
}
//
// update materials maps and add new shapes to result
aItLS.Initialize(aLSNew);
for (; aItLS.More(); aItLS.Next()) {
// add shapes to result (multidimensional and solids)
for (aItLS.Initialize(aLS); aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aS = aItLS.Value();
aBB.Add(aResult, aS);
}
}
// remove internal boundaries for edges and faces
for (Standard_Integer iType = 0; iType < 2; ++iType)
{
if (aLSUnify[iType].IsEmpty())
continue;
BOPCol_ListOfShape aLSN;
if (RemoveInternals(aLSUnify[iType], aLSN, aKeepMap[iType]))
bChanged = Standard_True;
// add shapes to result ([unified] edges or faces)
for (BOPCol_ListIteratorOfListOfShape aItLS(aLSN); aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aS = aItLS.Value();
aBB.Add(aResult, aS);
if (!myShapeMaterial.IsBound(aS)) {
myShapeMaterial.Bind(aS, iMaterial);
}
}
}
//
@@ -720,7 +758,8 @@ void BOPAlgo_CellsBuilder::MakeContainers()
//purpose :
//=======================================================================
Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape& theLS,
BOPCol_ListOfShape& theLSNew)
BOPCol_ListOfShape& theLSNew,
const TopTools_MapOfShape& theMapKeepBnd)
{
Standard_Boolean bRemoved = Standard_False;
if (theLS.Extent() < 2) {
@@ -750,8 +789,8 @@ Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape&
//
bFaces = (aType == TopAbs_FACE);
bEdges = (aType == TopAbs_EDGE);
//
ShapeUpgrade_UnifySameDomain anUnify (aShape, bEdges, bFaces);
anUnify.KeepShapes(theMapKeepBnd);
anUnify.Build();
const TopoDS_Shape& aSNew = anUnify.Shape();
//
@@ -783,14 +822,15 @@ Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape&
aNb = aMG.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aSS = aMG(i);
const Standard_Integer* pMaterial = myShapeMaterial.Seek(aSS);
const TopTools_ListOfShape& aLSMod = anUnify.History()->Modified(aSS);
TopTools_ListIteratorOfListOfShape aIt(aLSMod);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSU = aIt.Value();
if (!aSU.IsNull() && !aSS.IsSame(aSU)) {
myMapModified.Bind(aSS, aSU);
bRemoved = Standard_True;
}
myMapModified.Bind(aSS, aSU);
bRemoved = Standard_True;
if (pMaterial && !myShapeMaterial.IsBound(aSU))
myShapeMaterial.Bind(aSU, *pMaterial);
}
}
}
@@ -1073,6 +1113,33 @@ void MakeTypedContainers(const TopoDS_Shape& theSC,
}
}
//=======================================================================
//function : CollectMaterialBoundaries
//purpose : Add to theMapKeepBnd the boundary shapes of the area defined by shapes from the list
//=======================================================================
static void CollectMaterialBoundaries(const BOPCol_ListOfShape& theLS,
TopTools_MapOfShape& theMapKeepBnd)
{
TopAbs_ShapeEnum aType = theLS.First().ShapeType();
TopAbs_ShapeEnum aTypeSubsh = (aType == TopAbs_FACE ? TopAbs_EDGE : TopAbs_VERTEX);
TopTools_IndexedDataMapOfShapeListOfShape aMapSubSh;
BOPCol_ListIteratorOfListOfShape anIt(theLS);
for (; anIt.More(); anIt.Next())
{
const TopoDS_Shape& aS = anIt.Value();
TopExp::MapShapesAndAncestors(aS, aTypeSubsh, aType, aMapSubSh);
}
for (int i = 1; i <= aMapSubSh.Extent(); i++)
{
// check if the subshape belongs to boundary of the area
if (aMapSubSh(i).Extent() == 1)
{
// add to theMapKeepBnd
theMapKeepBnd.Add(aMapSubSh.FindKey(i));
}
}
}
//=======================================================================
//function : TypeToExplore
//purpose :

View File

@@ -23,7 +23,7 @@
#include <TopoDS_Shape.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BOPAlgo_Builder.hxx>
#include <BOPCol_ListOfShape.hxx>
@@ -265,7 +265,8 @@ class BOPAlgo_CellsBuilder : public BOPAlgo_Builder
//! Removes internal boundaries between cells with the same material.<br>
//! Returns TRUE if any internal boundaries have been removed.
Standard_EXPORT Standard_Boolean RemoveInternals(const BOPCol_ListOfShape& theLS,
BOPCol_ListOfShape& theLSNew);
BOPCol_ListOfShape& theLSNew,
const TopTools_MapOfShape& theMapKeepBnd = TopTools_MapOfShape());
// fields
TopoDS_Shape myAllParts;
@@ -273,9 +274,6 @@ class BOPAlgo_CellsBuilder : public BOPAlgo_Builder
BOPCol_DataMapOfIntegerListOfShape myMaterials;
BOPCol_DataMapOfShapeInteger myShapeMaterial;
BOPCol_DataMapOfShapeShape myMapModified;
private:
};
#endif //_BOPAlgo_CellsBuilder_HeaderFile