mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +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:
parent
7c4ce93bab
commit
385d47dde7
@ -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()) {
|
||||
// add the warning
|
||||
|
||||
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));
|
||||
}
|
||||
aLSNew.Assign(aLS);
|
||||
else
|
||||
{
|
||||
if (aType == TopAbs_EDGE || aType == TopAbs_FACE)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else {
|
||||
if (RemoveInternals(aLS, aLSNew)) {
|
||||
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 and add new shapes to result
|
||||
aItLS.Initialize(aLSNew);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
// update materials maps
|
||||
for (aItLS.Initialize(aLSNew); aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aS = aItLS.Value();
|
||||
aBB.Add(aResult, aS);
|
||||
if (!myShapeMaterial.IsBound(aS)) {
|
||||
myShapeMaterial.Bind(aS, iMaterial);
|
||||
}
|
||||
aLS.Assign(aLSNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
//
|
||||
@ -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;
|
||||
}
|
||||
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 :
|
||||
|
@ -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
|
||||
|
@ -39,6 +39,10 @@ bcadd result f1 1 f2 1 f3 1 -m 2
|
||||
bcadd result f1 0 f2 1 f3 1 -m 2
|
||||
bcremoveint result
|
||||
|
||||
if {![regexp {This shape seems to be OK.} [bopcheck result]]} {
|
||||
puts "Error: result shape is self intersected"
|
||||
}
|
||||
|
||||
donly result
|
||||
fit
|
||||
|
||||
|
56
tests/boolean/cells_test/K1
Normal file
56
tests/boolean/cells_test/K1
Normal file
@ -0,0 +1,56 @@
|
||||
puts "=========="
|
||||
puts "OCC28245"
|
||||
puts "=========="
|
||||
puts ""
|
||||
#################################################################################################
|
||||
# Result of Cells Builder algorithm becomes invalid after removal of internal boundaries on faces
|
||||
#################################################################################################
|
||||
|
||||
circle c1 0 0 0 0 0 1 10
|
||||
circle c2 10 0 0 0 0 1 10
|
||||
circle c3 5 9 0 0 0 1 10
|
||||
|
||||
mkedge e1 c1
|
||||
mkedge e2 c2
|
||||
mkedge e3 c3
|
||||
|
||||
wire w1 e1
|
||||
wire w2 e2
|
||||
wire w3 e3
|
||||
|
||||
mkplane f1 w1
|
||||
mkplane f2 w2
|
||||
mkplane f3 w3
|
||||
|
||||
bclearobjects
|
||||
bcleartools
|
||||
baddobjects f1 f2 f3
|
||||
bfillds
|
||||
bcbuild rx
|
||||
|
||||
bcadd r1 f1 1 -m 1 -u
|
||||
bcadd r1 f2 1 -m 2 -u
|
||||
|
||||
checknbshapes r1 -face 2
|
||||
checkprops r1 -s 505.482
|
||||
|
||||
bcremoveall
|
||||
bcadd r2 f1 1 -m 1 -u
|
||||
bcadd r2 f2 1 -m 1 -u
|
||||
|
||||
checknbshapes r2 -face 1
|
||||
checkprops r2 -s 505.482
|
||||
|
||||
bcremoveall
|
||||
bcadd result f1 1 -m 1
|
||||
bcadd result f2 1 f3 0 -m 1
|
||||
bcadd result f3 1 f1 0 -m 2
|
||||
bcremoveint result
|
||||
|
||||
set bcheck [bopcheck result]
|
||||
if {![regexp {This shape seems to be OK.} $bcheck]} {
|
||||
puts "Error: result shape is self intersected"
|
||||
}
|
||||
|
||||
checknbshapes result -edge 8 -face 2
|
||||
checkprops result -s 651.238
|
Loading…
x
Reference in New Issue
Block a user