mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +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:
@@ -732,236 +732,24 @@
|
||||
//function : FillIn3DParts
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepFeat_Builder::FillIn3DParts(TopTools_DataMapOfShapeListOfShape& theInParts,
|
||||
TopTools_DataMapOfShapeShape& theDraftSolids,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
void BRepFeat_Builder::FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids)
|
||||
{
|
||||
GetReport()->Clear();
|
||||
//
|
||||
Standard_Boolean bIsIN, bHasImage;
|
||||
Standard_Integer aNbS, i, j, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP;
|
||||
TopAbs_ShapeEnum aType;
|
||||
TopAbs_State aState;
|
||||
TopoDS_Iterator aIt, aItF;
|
||||
BRep_Builder aBB;
|
||||
TopoDS_Solid aSolidSp;
|
||||
TopoDS_Face aFP;
|
||||
TopTools_ListIteratorOfListOfShape aItS, aItFP, aItEx;
|
||||
TopTools_MapIteratorOfMapOfShape aItMS, aItMS1;
|
||||
//
|
||||
TopTools_ListOfShape aLIF(theAllocator);
|
||||
TopTools_MapOfShape aMFDone(100, theAllocator);
|
||||
TopTools_MapOfShape aMSolids(100, theAllocator);
|
||||
TopTools_MapOfShape aMFaces(100, theAllocator);
|
||||
TopTools_MapOfShape aMFIN(100, theAllocator);
|
||||
TopTools_IndexedMapOfShape aMS(100, theAllocator);
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
|
||||
//
|
||||
theDraftSolids.Clear();
|
||||
//
|
||||
aNbS=myDS->NbSourceShapes();
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
const TopoDS_Shape& aS=aSI.Shape();
|
||||
//
|
||||
aType=aSI.ShapeType();
|
||||
switch(aType) {
|
||||
case TopAbs_SOLID: {
|
||||
aMSolids.Add(aS);
|
||||
break;
|
||||
}
|
||||
//
|
||||
case TopAbs_FACE: {
|
||||
// all faces (originals or images)
|
||||
if (myImages.IsBound(aS)) {
|
||||
const TopTools_ListOfShape& aLS=myImages.Find(aS);
|
||||
aItS.Initialize(aLS);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Shape& aFx=aItS.Value();
|
||||
if (!myRemoved.Contains(aFx)) {
|
||||
aMFaces.Add(aFx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!myRemoved.Contains(aS)) {
|
||||
aMFaces.Add(aS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
//
|
||||
default:
|
||||
break;
|
||||
|
||||
BOPAlgo_Builder::FillIn3DParts(theDraftSolids);
|
||||
|
||||
// Clear the IN parts of the solids from the removed faces
|
||||
TopTools_DataMapOfShapeListOfShape::Iterator itM(myInParts);
|
||||
for (; itM.More(); itM.Next())
|
||||
{
|
||||
TopTools_ListOfShape& aList = itM.ChangeValue();
|
||||
TopTools_ListOfShape::Iterator itL(aList);
|
||||
for (; itL.More();)
|
||||
{
|
||||
if (myRemoved.Contains(itL.Value()))
|
||||
aList.Remove(itL);
|
||||
else
|
||||
itL.Next();
|
||||
}
|
||||
}
|
||||
//
|
||||
aItMS.Initialize(aMSolids);
|
||||
for (; aItMS.More(); aItMS.Next()) {
|
||||
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItMS.Value()));
|
||||
//
|
||||
aMFDone.Clear();
|
||||
aMFIN.Clear();
|
||||
aMEF.Clear();
|
||||
//
|
||||
aBB.MakeSolid(aSolidSp);
|
||||
//
|
||||
// Draft solid and its pure internal faces => aSolidSp, aLIF
|
||||
aLIF.Clear();
|
||||
BuildDraftSolid(aSolid, aSolidSp, aLIF);
|
||||
aNbLIF=aLIF.Extent();
|
||||
//
|
||||
// 1 all faces/edges from aSolid [ aMS ]
|
||||
bHasImage=Standard_False;
|
||||
aMS.Clear();
|
||||
aIt.Initialize(aSolid);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aShell=aIt.Value();
|
||||
//
|
||||
if (myImages.IsBound(aShell)) {
|
||||
bHasImage=Standard_True;
|
||||
//
|
||||
const TopTools_ListOfShape& aLS=myImages.Find(aShell);
|
||||
aItS.Initialize(aLS);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Shape& aSx=aItS.Value();
|
||||
aMS.Add(aSx);
|
||||
TopExp::MapShapes(aSx, TopAbs_FACE, aMS);
|
||||
TopExp::MapShapes(aSx, TopAbs_EDGE, aMS);
|
||||
TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//aMS.Add(aShell);
|
||||
TopExp::MapShapes(aShell, TopAbs_FACE, aMS);
|
||||
TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2 all faces that are not from aSolid [ aLFP1 ]
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMEFP(100, theAllocator);
|
||||
TopTools_ListOfShape aLFP1(theAllocator);
|
||||
TopTools_ListOfShape aLFP(theAllocator);
|
||||
TopTools_ListOfShape aLCBF(theAllocator);
|
||||
TopTools_ListOfShape aLFIN(theAllocator);
|
||||
TopTools_ListOfShape aLEx(theAllocator);
|
||||
//
|
||||
// for all non-solid faces build EF map [ aMEFP ]
|
||||
aItMS1.Initialize(aMFaces);
|
||||
for (; aItMS1.More(); aItMS1.Next()) {
|
||||
const TopoDS_Shape& aFace=aItMS1.Value();
|
||||
if (!aMS.Contains(aFace)) {
|
||||
TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
|
||||
}
|
||||
}
|
||||
//
|
||||
// among all faces from aMEFP select these that have same edges
|
||||
// with the solid (i.e aMEF). These faces will be treated first
|
||||
// to prevent the usage of 3D classifier.
|
||||
// The full list of faces to process is aLFP1.
|
||||
aNbEFP=aMEFP.Extent();
|
||||
for (j=1; j<=aNbEFP; ++j) {
|
||||
const TopoDS_Shape& aE=aMEFP.FindKey(j);
|
||||
//
|
||||
if (aMEF.Contains(aE)) { // !!
|
||||
const TopTools_ListOfShape& aLF=aMEFP(j);
|
||||
aItFP.Initialize(aLF);
|
||||
for (; aItFP.More(); aItFP.Next()) {
|
||||
const TopoDS_Shape& aF=aItFP.Value();
|
||||
if (aMFDone.Add(aF)) {
|
||||
aLFP1.Append(aF);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
aLEx.Append(aE);
|
||||
}
|
||||
}
|
||||
//
|
||||
aItEx.Initialize(aLEx);
|
||||
for (; aItEx.More(); aItEx.Next()) {
|
||||
const TopoDS_Shape& aE=aItEx.Value();
|
||||
const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE);
|
||||
aItFP.Initialize(aLF);
|
||||
for (; aItFP.More(); aItFP.Next()) {
|
||||
const TopoDS_Shape& aF=aItFP.Value();
|
||||
if (aMFDone.Add(aF)) {
|
||||
//aLFP2.Append(aF);
|
||||
aLFP1.Append(aF);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//==========
|
||||
//
|
||||
// 3 Process faces aLFP1
|
||||
aMFDone.Clear();
|
||||
aNbFP=aLFP1.Extent();
|
||||
aItFP.Initialize(aLFP1);
|
||||
for (; aItFP.More(); aItFP.Next()) {
|
||||
const TopoDS_Shape& aSP=aItFP.Value();
|
||||
if (!aMFDone.Add(aSP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// first face to process
|
||||
aFP=(*(TopoDS_Face*)(&aSP));
|
||||
bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
|
||||
aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
|
||||
//
|
||||
// collect faces to process [ aFP is the first ]
|
||||
aLFP.Clear();
|
||||
aLFP.Append(aFP);
|
||||
aItS.Initialize(aLFP1);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Shape& aSk=aItS.Value();
|
||||
if (!aMFDone.Contains(aSk)) {
|
||||
aLFP.Append(aSk);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Connexity Block that spreads from aFP the Bound
|
||||
// or till the end of the block itself
|
||||
aLCBF.Clear();
|
||||
BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, theAllocator);
|
||||
//
|
||||
// fill states for the Connexity Block
|
||||
aItS.Initialize(aLCBF);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Shape& aSx=aItS.Value();
|
||||
aMFDone.Add(aSx);
|
||||
if (aState==TopAbs_IN) {
|
||||
aMFIN.Add(aSx);
|
||||
}
|
||||
}
|
||||
//
|
||||
aNbFPx=aMFDone.Extent();
|
||||
if (aNbFPx==aNbFP) {
|
||||
break;
|
||||
}
|
||||
}//for (; aItFP.More(); aItFP.Next())
|
||||
//
|
||||
// faces Inside aSolid
|
||||
aLFIN.Clear();
|
||||
aNbFIN=aMFIN.Extent();
|
||||
if (aNbFIN || aNbLIF) {
|
||||
aItMS1.Initialize(aMFIN);
|
||||
for (; aItMS1.More(); aItMS1.Next()) {
|
||||
const TopoDS_Shape& aFIn=aItMS1.Value();
|
||||
aLFIN.Append(aFIn);
|
||||
}
|
||||
//
|
||||
aItS.Initialize(aLIF);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Shape& aFIN=aItS.Value();
|
||||
aLFIN.Append(aFIN);
|
||||
}
|
||||
//
|
||||
theInParts.Bind(aSolid, aLFIN);
|
||||
}
|
||||
if (aNbFIN || bHasImage) {
|
||||
theDraftSolids.Bind(aSolid, aSolidSp);
|
||||
}
|
||||
}// for (; aItMS.More(); aItMS.Next()) {
|
||||
}
|
||||
|
@@ -117,7 +117,14 @@ protected:
|
||||
Standard_EXPORT virtual void Prepare() Standard_OVERRIDE;
|
||||
|
||||
//! Function is redefined to avoid the usage of removed faces.
|
||||
Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts, TopTools_DataMapOfShapeShape& theDraftSolids, const Handle(NCollection_BaseAllocator)& theAllocator) Standard_OVERRIDE;
|
||||
Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeShape& theDraftSolids) Standard_OVERRIDE;
|
||||
|
||||
//! Avoid the check for open solids and always use the splits
|
||||
//! of solids for building the result shape.
|
||||
virtual Standard_Boolean CheckArgsForOpenSolid() Standard_OVERRIDE
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
||||
TopTools_MapOfShape myShapes;
|
||||
|
Reference in New Issue
Block a user