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

0030145: Modeling Algorithms - Boolean Operations on open solids

Provide possibility to perform Boolean operations on open solids.

Implementation of the new method *BOPAlgo_Builder::BuildBOP* performing the construction of the result shape for the given type of Boolean operation.
This approach does not rely on the splits of solid to be correct and looks for the faces with necessary state relatively opposite solids to build the result solid.
The call to this method is performed from BOP algorithm in case there were open solids in the arguments.

Implementation of the draw command *buildbop* performing a call to the method above.
This commit is contained in:
emv
2018-09-07 15:24:49 +03:00
committed by bugmaster
parent 60b1a085c7
commit 13c0e40223
35 changed files with 1686 additions and 446 deletions

View File

@@ -1643,3 +1643,148 @@ void BOPAlgo_Tools::ClassifyFaces(const TopTools_ListOfShape& theFaces,
theInParts.Add(aS, aLFIn);
}
}
//=======================================================================
//function : FillInternals
//purpose :
//=======================================================================
void BOPAlgo_Tools::FillInternals(const TopTools_ListOfShape& theSolids,
const TopTools_ListOfShape& theParts,
const TopTools_DataMapOfShapeListOfShape& theImages,
const Handle(IntTools_Context)& theContext)
{
if (theSolids.IsEmpty() || theParts.IsEmpty())
return;
// Map the solids to avoid classification of the own shapes of the solids
TopTools_IndexedMapOfShape aMSSolids;
TopTools_ListOfShape::Iterator itLS(theSolids);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aSolid = itLS.Value();
if (aSolid.ShapeType() == TopAbs_SOLID)
{
TopExp::MapShapes(aSolid, TopAbs_VERTEX, aMSSolids);
TopExp::MapShapes(aSolid, TopAbs_EDGE, aMSSolids);
TopExp::MapShapes(aSolid, TopAbs_FACE, aMSSolids);
}
}
// Extract BRep elements from the given parts and
// check them for possible splits
TopTools_ListOfShape aLPartsInput = theParts, aLParts;
TopTools_ListOfShape::Iterator itLP(aLPartsInput);
for (; itLP.More(); itLP.Next())
{
const TopoDS_Shape& aPart = itLP.Value();
switch (aPart.ShapeType())
{
case TopAbs_VERTEX:
case TopAbs_EDGE:
case TopAbs_FACE:
{
const TopTools_ListOfShape* pIm = theImages.Seek(aPart);
if (pIm)
{
TopTools_ListOfShape::Iterator itIm(*pIm);
for (; itIm.More(); itIm.Next())
{
const TopoDS_Shape& aPartIm = itIm.Value();
if (!aMSSolids.Contains(aPartIm))
aLParts.Append(aPartIm);
}
}
else if (!aMSSolids.Contains(aPart))
aLParts.Append(aPart);
break;
}
default:
{
for (TopoDS_Iterator it(aPart); it.More(); it.Next())
aLPartsInput.Append(it.Value());
break;
}
}
}
// Classify the given parts relatively solids.
// Add edges and vertices classified as IN into solids instantly,
// and collect faces classified as IN into a list for further shell creation
TopTools_DataMapOfShapeListOfShape anINFaces;
itLS.Initialize(theSolids);
for (; itLS.More(); itLS.Next())
{
const TopoDS_Shape& aSolid = itLS.Value();
if (aSolid.ShapeType() != TopAbs_SOLID)
continue;
TopoDS_Solid aSd = *(TopoDS_Solid*)&aSolid;
itLP.Initialize(aLParts);
for (; itLP.More();)
{
TopoDS_Shape aPart = itLP.Value();
TopAbs_State aState =
BOPTools_AlgoTools::ComputeStateByOnePoint(aPart, aSd, Precision::Confusion(), theContext);
if (aState == TopAbs_IN)
{
if (aPart.ShapeType() == TopAbs_FACE)
{
TopTools_ListOfShape *pFaces = anINFaces.ChangeSeek(aSd);
if (!pFaces)
pFaces = anINFaces.Bound(aSd, TopTools_ListOfShape());
pFaces->Append(aPart);
}
else
{
aPart.Orientation(TopAbs_INTERNAL);
BRep_Builder().Add(aSd, aPart);
}
aLParts.Remove(itLP);
}
else
itLP.Next();
}
}
// Make shells from faces and put them into solids
TopTools_DataMapOfShapeListOfShape::Iterator itM(anINFaces);
for (; itM.More(); itM.Next())
{
TopoDS_Solid aSd = *(TopoDS_Solid*)&itM.Key();
const TopTools_ListOfShape& aFaces = itM.Value();
TopoDS_Compound aCF;
BRep_Builder().MakeCompound(aCF);
TopTools_ListOfShape::Iterator itLF(aFaces);
for (; itLF.More(); itLF.Next())
BRep_Builder().Add(aCF, itLF.Value());
// Build blocks from the faces
TopTools_ListOfShape aLCB;
BOPTools_AlgoTools::MakeConnexityBlocks(aCF, TopAbs_EDGE, TopAbs_FACE, aLCB);
// Build shell from each block
TopTools_ListOfShape::Iterator itCB(aLCB);
for (; itCB.More(); itCB.Next())
{
const TopoDS_Shape& aCB = itCB.Value();
TopoDS_Shell aShell;
BRep_Builder().MakeShell(aShell);
// Add faces of the block to the shell
TopExp_Explorer expF(aCB, TopAbs_FACE);
for (; expF.More(); expF.Next())
{
TopoDS_Face aFInt = TopoDS::Face(expF.Current());
aFInt.Orientation(TopAbs_INTERNAL);
BRep_Builder().Add(aShell, aFInt);
}
BRep_Builder().Add(aSd, aShell);
}
}
}