1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-07 18:30:55 +03:00

0024861: Extra solid is in the result of General Fuse Operation

I. New features:
No new features.

II. Changes:
II.1. class BOPAlgo_ShellSplitter
   - statc function:
void RefineShell(TopoDS_Shell& theShell);
has been addded.
The function provides splitting connexity block of faces when the block begins with
the face that is intended to be internal.

II.2. class BOPAlgo_ShellSplitter
   - statc function:
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
has been modified to process empty shells.

II.3. class BOPAlgo_ShellSplitter
   - method:
void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB);
has been modified to process connexity blocks of faces when the block
begins with the face that is intended to be internal [ II.1 ].

III. Modified entities:
packages:
BOPAlgo

Test case for issue CR24861
This commit is contained in:
pkv 2014-04-21 15:54:03 +04:00 committed by abv
parent 7759e404df
commit 69b558c435
4 changed files with 254 additions and 106 deletions

View File

@ -37,16 +37,57 @@
#include <BOPTools.hxx> #include <BOPTools.hxx>
#include <BOPTools_AlgoTools.hxx> #include <BOPTools_AlgoTools.hxx>
#include <BOPTools_CoupleOfShape.hxx> #include <BOPTools_CoupleOfShape.hxx>
//
typedef BOPCol_NCVector<BOPTools_ConnexityBlock> \
BOPAlgo_ShellSplitter_VectorOfConnexityBlock;
// //
static static
Standard_Boolean IsClosedShell(const TopoDS_Shell& ); Standard_Boolean IsClosedShell(const TopoDS_Shell& );
//
static static
void MakeShell(const BOPCol_ListOfShape& , void MakeShell(const BOPCol_ListOfShape& ,
TopoDS_Shell& ); TopoDS_Shell& );
//
static
void RefineShell(TopoDS_Shell& theShell);
//=======================================================================
//class : BOPAlgo_CBK
//purpose :
//=======================================================================
class BOPAlgo_CBK {
public:
BOPAlgo_CBK() :
myPCB (NULL) {
}
//
~BOPAlgo_CBK() {
}
//
void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) {
myPCB=(BOPTools_ConnexityBlock*)&aCB;
}
//
BOPTools_ConnexityBlock& ConnexityBlock () {
return *myPCB;
}
//
void Perform() {
BOPAlgo_ShellSplitter::SplitBlock(*myPCB);
}
protected:
BOPTools_ConnexityBlock *myPCB;
};
//=======================================================================
typedef BOPCol_NCVector
<BOPAlgo_CBK> BOPAlgo_VectorOfCBK;
//
typedef BOPCol_TBBFunctor
<BOPAlgo_CBK,
BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
//
typedef BOPCol_TBBCnt
<BOPAlgo_CBKFunctor,
BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
//
//======================================================================= //=======================================================================
//function : //function :
//purpose : //purpose :
@ -148,7 +189,8 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
if (!aMEP.Contains(aSE)) { if (!aMEP.Contains(aSE)) {
aMEP.Add(aSE); aMEP.Add(aSE);
BOPTools::MapShapesAndAncestors(aSE, BOPTools::MapShapesAndAncestors(aSE,
TopAbs_EDGE, TopAbs_FACE, TopAbs_EDGE,
TopAbs_FACE,
aMEF); aMEF);
} }
else { else {
@ -236,7 +278,8 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
// //
if (bRegular) { if (bRegular) {
BOPTools::MapShapesAndAncestors(aFR, BOPTools::MapShapesAndAncestors(aFR,
TopAbs_EDGE, TopAbs_FACE, TopAbs_EDGE,
TopAbs_FACE,
aMEFR); aMEFR);
} }
} }
@ -288,8 +331,10 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
aItF.Initialize (myShapes); aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) { for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aFF = aItF.Value(); const TopoDS_Shape& aFF = aItF.Value();
BOPTools::MapShapesAndAncestors BOPTools::MapShapesAndAncestors (aFF,
(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); TopAbs_EDGE,
TopAbs_FACE,
aEFMap);
} }
// //
aItF.Initialize (myShapes); aItF.Initialize (myShapes);
@ -306,7 +351,8 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
// //
aMEFP.Clear(); aMEFP.Clear();
BOPTools::MapShapesAndAncestors(aFF, BOPTools::MapShapesAndAncestors(aFF,
TopAbs_EDGE, TopAbs_FACE, TopAbs_EDGE,
TopAbs_FACE,
aMEFP); aMEFP);
// //
// loop on faces added to Shell; // loop on faces added to Shell;
@ -381,88 +427,188 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2())); aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
} }
else if (aNbOff>1){ else if (aNbOff>1){
BOPTools_AlgoTools::GetFaceOff(aE, aF, BOPTools_AlgoTools::GetFaceOff(aE,
aLCSOff, aSelF, aContext); aF,
aLCSOff,
aSelF,
aContext);
} }
// //
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
aBB.Add(aShell, aSelF); aBB.Add(aShell, aSelF);
BOPTools::MapShapesAndAncestors(aSelF, BOPTools::MapShapesAndAncestors(aSelF,
TopAbs_EDGE, TopAbs_FACE, TopAbs_EDGE,
TopAbs_FACE,
aMEFP); aMEFP);
} }
} // for (; aEdgeExp.More(); aEdgeExp.Next()) { } // for (; aExp.More(); aExp.Next()) {
} //for (; aItAddedF.More(); aItAddedF.Next()) { } // for (; aItS.More(); aItS.Next()) {
// //
if (IsClosedShell(aShell)) { if (IsClosedShell(aShell)) {
myLoops.Append(aShell); myLoops.Append(aShell);
} }
else {
RefineShell(aShell);
if (IsClosedShell(aShell)) {
myLoops.Append(aShell);
}
}
} // for (; aItF.More(); aItF.Next()) { } // for (; aItF.More(); aItF.Next()) {
} }
//======================================================================= //=======================================================================
//class : ShellSplitterFunctor //function : RefineShell
//purpose : Auxiliary class //purpose :
//======================================================================= //=======================================================================
class BOPAlgo_ShellSplitterFunctor { void RefineShell(TopoDS_Shell& theShell)
protected: {
TopoDS_Face myFace; TopoDS_Iterator aIt;
BOPAlgo_ShellSplitter_VectorOfConnexityBlock* myPVCB;
// //
public: aIt.Initialize(theShell);
BOPAlgo_ShellSplitterFunctor if(!aIt.More()) {
(BOPAlgo_ShellSplitter_VectorOfConnexityBlock& aVCB) return;
: myPVCB(&aVCB) {
} }
// //
void operator()( const flexible_range<Standard_Size>& aBR ) const{ Standard_Integer i, aNbMEF, aNbF;
Standard_Size i, iBeg, iEnd; BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
TopoDS_Builder aBB;
TopExp_Explorer aExp;
BOPCol_MapOfShape aMEStop, aMFB;
BOPCol_MapIteratorOfMapOfShape aItM;
BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
BOPCol_ListOfShape aLFP, aLFP1;
// //
BOPAlgo_ShellSplitter_VectorOfConnexityBlock& aVCB=*myPVCB; // Branch points
// BOPTools::MapShapesAndAncestors (theShell,
iBeg=aBR.begin(); TopAbs_EDGE,
iEnd=aBR.end(); TopAbs_FACE,
for(i=iBeg; i!=iEnd; ++i) { aMEF);
BOPTools_ConnexityBlock& aCB=aVCB((Standard_Integer)i); aNbMEF=aMEF.Extent();
// for (i=1; i<=aNbMEF; ++i) {
BOPAlgo_ShellSplitter::SplitBlock(aCB); const TopoDS_Shape& aE=aMEF.FindKey(i);
const BOPCol_ListOfShape& aLF=aMEF.FindFromIndex(i);
aNbF=aLF.Extent();
if (aNbF>2) {
aMEStop.Add(aE);
} }
} }
}; //
if (aMEStop.IsEmpty()) {
return;
}
//
// The first Face
const TopoDS_Shape& aF1=aIt.Value();
aMFB.Add(aF1);
aLFP.Append(aF1);
//
// Trying to reach the branch point
for (;;) {
aItLFP.Initialize(aLFP);
for (; aItLFP.More(); aItLFP.Next()) {
const TopoDS_Shape& aFP=aItLFP.Value();
//
aExp.Init(aFP, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (aMEStop.Contains(aE)) {
continue;
}
//
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
if (aFP1.IsSame(aFP)) {
continue;
}
if (aMFB.Contains(aFP1)) {
continue;
}
aMFB.Add(aFP1);
aLFP1.Append(aFP1);
}// for (; aItLF.More(); aItLF.Next()) {
}// for (; aExp.More(); aExp.Next()) {
}// for (; aItLFP.More(); aItLFP.Next()) {
//
//
if (aLFP1.IsEmpty()) {
break;
}
//
aLFP.Clear();
aItLF.Initialize(aLFP1);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFP1=aItLF.Value();
aLFP.Append(aFP1);
}
aLFP1.Clear();
}// for (;;) {
//
// Remove all faces before the branch point
aItM.Initialize(aMFB);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFB=aItM.Value();
aBB.Remove(theShell, aFB);
}
}
//======================================================================= //=======================================================================
//class : BOPAlgo_ShellSplitterCnt //function : IsClosedShell
//purpose : Auxiliary class //purpose :
//======================================================================= //=======================================================================
class BOPAlgo_ShellSplitterCnt { Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
public: {
//------------------------------- Standard_Integer i, aNbE;
// Perform Standard_Boolean bRet;
Standard_EXPORT TopoDS_Iterator aIt;
static void Perform TopExp_Explorer aExp;
(const Standard_Boolean bRunParallel, BOPCol_MapOfShape aM;
BOPAlgo_ShellSplitter_VectorOfConnexityBlock& aVCB) {
// //
BOPAlgo_ShellSplitterFunctor aSSF(aVCB); bRet=Standard_False;
Standard_Size aNbVCB=aVCB.Extent();
// //
if (bRunParallel) { aIt.Initialize(theShell);
flexible_for(flexible_range<Standard_Size>(0,aNbVCB), aSSF); for(i=0; aIt.More(); aIt.Next(), ++i) {
const TopoDS_Shape& aF=aIt.Value();
//
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aE)) {
continue;
} }
else { //
aSSF.operator()(flexible_range<Standard_Size>(0,aNbVCB)); if (aE.Orientation()==TopAbs_INTERNAL) {
continue;
}
if (!aM.Add(aE)) {
aM.Remove(aE);
} }
} }
}; }
//
if(i) {
aNbE=aM.Extent();
if (!aNbE) {
bRet=!bRet;
}
}
return bRet;
}
//======================================================================= //=======================================================================
//function : MMakeShells //function : MakeShells
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_ShellSplitter::MakeShells() void BOPAlgo_ShellSplitter::MakeShells()
{ {
Standard_Boolean bIsRegular; Standard_Boolean bIsRegular;
Standard_Integer aNbVCB, k; Standard_Integer aNbVCBK, k;
BOPTools_ListIteratorOfListOfConnexityBlock aItCB; BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
BOPCol_ListIteratorOfListOfShape aIt; BOPCol_ListIteratorOfListOfShape aIt;
BOPAlgo_ShellSplitter_VectorOfConnexityBlock aVCB; BOPAlgo_VectorOfCBK aVCBK;
// //
myErrorStatus=0; myErrorStatus=0;
myShells.Clear(); myShells.Clear();
@ -480,16 +626,18 @@ void BOPAlgo_ShellSplitter::MakeShells()
myShells.Append(aShell); myShells.Append(aShell);
} }
else { else {
aVCB.Append(aCB); BOPAlgo_CBK& aCBK=aVCBK.Append1();
aCBK.SetConnexityBlock(aCB);
} }
} }
// //
aNbVCB=aVCB.Extent(); aNbVCBK=aVCBK.Extent();
//=================================================== //===================================================
BOPAlgo_ShellSplitterCnt::Perform(myRunParallel, aVCB); BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK);
//=================================================== //===================================================
for (k=0; k<aNbVCB; ++k) { for (k=0; k<aNbVCBK; ++k) {
const BOPTools_ConnexityBlock& aCB=aVCB(k); BOPAlgo_CBK& aCBK=aVCBK(k);
const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock();
const BOPCol_ListOfShape& aLS=aCB.Loops(); const BOPCol_ListOfShape& aLS=aCB.Loops();
aIt.Initialize(aLS); aIt.Initialize(aLS);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next()) {
@ -500,44 +648,6 @@ void BOPAlgo_ShellSplitter::MakeShells()
} }
} }
//======================================================================= //=======================================================================
//function : IsClosedShell
//purpose :
//=======================================================================
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
{
Standard_Integer aNbE;
Standard_Boolean bRet;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
BOPCol_MapOfShape aM;
//
bRet=Standard_False;
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
if (aE.Orientation()==TopAbs_INTERNAL) {
continue;
}
if (!aM.Add(aE)) {
aM.Remove(aE);
}
}
}
//
aNbE=aM.Extent();
if (!aNbE) {
bRet=!bRet;
}
return bRet;
}
//=======================================================================
//function : MakeShell //function : MakeShell
//purpose : //purpose :
//======================================================================= //=======================================================================

View File

@ -1,5 +1,3 @@
puts "TODO OCC12345 ALL: Error : The square of result shape is"
puts "=========" puts "========="
puts " OCC497 " puts " OCC497 "
puts "(case 1)" puts "(case 1)"
@ -15,10 +13,14 @@ checkshape a_1
restore [locate_data_file OCC497b.brep] a_2 restore [locate_data_file OCC497b.brep] a_2
checkshape a_2 checkshape a_2
if [catch {bcut result a_1 a_2 } catch_result] { explode a_2 so
bop a_2_1 a_2_2
bopfuse r1
if [catch {bcut result a_1 r1 } catch_result] {
puts "Faulty OCC497:function CUT works wrongly " puts "Faulty OCC497:function CUT works wrongly "
} else { } else {
puts "OCC497 : function CUT works without hangs up " puts "OCC497 : function CUT works without hangs up "
} }
set square 0 set square 646.969
set 2dviewer 0 set 2dviewer 0

View File

@ -1,3 +1,6 @@
puts "TODO OCC24861 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC24861 ALL: Error : The square of result shape is"
puts "=========" puts "========="
puts " OCC497 " puts " OCC497 "
puts "(case 5)" puts "(case 5)"

View File

@ -0,0 +1,33 @@
puts "========="
puts "OCC24861"
puts "========="
puts ""
###########################################################
# Extra solid is in the result of General Fuse Operation
###########################################################
restore [locate_data_file bug24861_b1.brep] b1
restore [locate_data_file bug24861_b2.brep] b2
explode b2
bclearobjects
bcleartools
baddobjects b1 b2_1 b2_2 b2_3 b2_4 b2_5 b2_6 b2_7
bfillds -s
bbuild result -s
set square 1780.37
set nb_v_good 18
set nb_e_good 38
set nb_w_good 32
set nb_f_good 29
set nb_sh_good 9
set nb_sol_good 7
set nb_compsol_good 0
set nb_compound_good 1
set nb_shape_good 134
set 2dviewer 1