1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-01 10:26:12 +03:00

0029179: Result of Boolean common depends on an order of arguments

Usage of Bnd_Box-filtering is eliminated while putting a (definitely) common vertex between two faces on the intersection curve.

Algorithm of putting not-common (ON/IN) vertices has not been changed.
This commit is contained in:
nbv 2017-12-07 11:28:20 +03:00 committed by bugmaster
parent 624c599cd3
commit 6f1ea0f4b1
10 changed files with 174 additions and 93 deletions

View File

@ -254,15 +254,16 @@ protected:
Standard_EXPORT Standard_Boolean IsExistingVertex (const gp_Pnt& theP, const Standard_Real theTol, const TColStd_MapOfInteger& theMVOn) const; Standard_EXPORT Standard_Boolean IsExistingVertex (const gp_Pnt& theP, const Standard_Real theTol, const TColStd_MapOfInteger& theMVOn) const;
//! Checks and puts paves from <theMVOn> on the curve <theNC>. //! Checks and puts paves from <theMVOnIn> on the curve <theNC>.
Standard_EXPORT void PutPavesOnCurve (const TColStd_MapOfInteger& theMVOn, //! At that, common (from theMVCommon) and not common vertices
//! are processed differently.
Standard_EXPORT void PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn,
const TColStd_MapOfInteger& theMVCommon,
BOPDS_Curve& theNC, BOPDS_Curve& theNC,
const Standard_Integer nF1,
const Standard_Integer nF2,
const TColStd_MapOfInteger& theMI, const TColStd_MapOfInteger& theMI,
const TColStd_MapOfInteger& theMVEF, const TColStd_MapOfInteger& theMVEF,
TColStd_DataMapOfIntegerReal& theMVTol, TColStd_DataMapOfIntegerReal& theMVTol,
TColStd_DataMapOfIntegerListOfInteger& aDMVLV); TColStd_DataMapOfIntegerListOfInteger& theDMVLV);
Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC); Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC);

View File

@ -391,7 +391,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
NCollection_BaseAllocator::CommonBaseAllocator(); NCollection_BaseAllocator::CommonBaseAllocator();
// //
TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator); TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
TColStd_MapOfInteger aMVOnIn(100, aAllocator), TColStd_MapOfInteger aMVOnIn(100, aAllocator), aMVCommon(100, aAllocator),
aMVStick(100,aAllocator), aMVEF(100, aAllocator), aMVStick(100,aAllocator), aMVEF(100, aAllocator),
aMI(100, aAllocator), aMVBounds(100, aAllocator); aMI(100, aAllocator), aMVBounds(100, aAllocator);
BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator); BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
@ -432,13 +432,14 @@ void BOPAlgo_PaveFiller::MakeBlocks()
BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2); BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
// //
aMVOnIn.Clear(); aMVOnIn.Clear();
aMVCommon.Clear();
aMPBOnIn.Clear(); aMPBOnIn.Clear();
aMPBCommon.Clear(); aMPBCommon.Clear();
aDMBV.Clear(); aDMBV.Clear();
aMVTol.Clear(); aMVTol.Clear();
aLSE.Clear(); aLSE.Clear();
// //
myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon); myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMVCommon, aMPBOnIn, aMPBCommon);
myDS->SharedEdges(nF1, nF2, aLSE, aAllocator); myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
// //
Standard_Boolean bHasRealSectionEdge = Standard_False; Standard_Boolean bHasRealSectionEdge = Standard_False;
@ -470,7 +471,13 @@ void BOPAlgo_PaveFiller::MakeBlocks()
// DEBt // DEBt
aNC.InitPaveBlock1(); aNC.InitPaveBlock1();
// //
PutPavesOnCurve(aMVOnIn, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV); // In order to avoid problems connected with
// extending tolerance of vertex while putting
// (e.g. see "bugs modalg_6 bug26789_1" test case),
// all not-common vertices will be checked by
// BndBoxes before putting. For common-vertices,
// filtering by BndBoxes is not necessary.
PutPavesOnCurve(aMVOnIn, aMVCommon, aNC, aMI, aMVEF, aMVTol, aDMVLV);
} }
// if some E-F vertex was put on a curve due to large E-F intersection range, // if some E-F vertex was put on a curve due to large E-F intersection range,
@ -706,6 +713,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
aMVStick.Clear(); aMVStick.Clear();
aMPBOnIn.Clear(); aMPBOnIn.Clear();
aMVOnIn.Clear(); aMVOnIn.Clear();
aMVCommon.Clear();
aDMExEdges.Clear(); aDMExEdges.Clear();
aMI.Clear(); aMI.Clear();
aDMNewSD.Clear(); aDMNewSD.Clear();
@ -1570,57 +1578,54 @@ void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
//function : PutPavesOnCurve //function : PutPavesOnCurve
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_PaveFiller::PutPavesOnCurve void BOPAlgo_PaveFiller::PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn,
(const TColStd_MapOfInteger& aMVOnIn, const TColStd_MapOfInteger& theMVCommon,
BOPDS_Curve& aNC, BOPDS_Curve& theNC,
const Standard_Integer nF1, const TColStd_MapOfInteger& theMI,
const Standard_Integer nF2, const TColStd_MapOfInteger& theMVEF,
const TColStd_MapOfInteger& aMI, TColStd_DataMapOfIntegerReal& theMVTol,
const TColStd_MapOfInteger& aMVEF, TColStd_DataMapOfIntegerListOfInteger& theDMVLV)
TColStd_DataMapOfIntegerReal& aMVTol,
TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
{ {
Standard_Boolean bInBothFaces;
Standard_Integer nV; Standard_Integer nV;
TColStd_MapIteratorOfMapOfInteger aIt; TColStd_MapIteratorOfMapOfInteger aIt;
// //
const Bnd_Box& aBoxC=aNC.Box(); const Bnd_Box& aBoxC = theNC.Box();
Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance()); const Standard_Real aTolR3D = Max(theNC.Tolerance(), theNC.TangentialTolerance());
// //
//Put EF vertices first //Put EF vertices first
aIt.Initialize(aMVEF); aIt.Initialize(theMVEF);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next())
nV=aIt.Value(); {
PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2); nV = aIt.Value();
PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 2);
} }
//Put all other vertices //Put all other vertices
aIt.Initialize(aMVOnIn); aIt.Initialize(theMVOnIn);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next())
nV=aIt.Value(); {
if (aMVEF.Contains(nV)) { nV = aIt.Value();
if (theMVEF.Contains(nV))
{
continue; continue;
} }
if (!theMVCommon.Contains(nV))
{
const BOPDS_ShapeInfo& aSIV = myDS->ShapeInfo(nV);
const Bnd_Box& aBoxV = aSIV.Box();
// //
const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV); if (aBoxC.IsOut(aBoxV))
const Bnd_Box& aBoxV=aSIV.Box(); {
//
if (aBoxC.IsOut(aBoxV)){
continue; continue;
} }
if (!myDS->IsNewShape(nV)) { if (!myDS->IsNewShape(nV))
const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1); {
const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
//
bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
aFI1.VerticesIn().Contains(nV))&&
(aFI2.VerticesOn().Contains(nV) ||
aFI2.VerticesIn().Contains(nV));
if (!bInBothFaces) {
continue; continue;
} }
} }
// //
PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1); PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 1);
} }
} }

View File

@ -1453,10 +1453,10 @@ void BOPDS_DS::AloneVertices(const Standard_Integer theI,
//function : VerticesOnIn //function : VerticesOnIn
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPDS_DS::SubShapesOnIn void BOPDS_DS::SubShapesOnIn(const Standard_Integer theNF1,
(const Standard_Integer nF1, const Standard_Integer theNF2,
const Standard_Integer nF2,
TColStd_MapOfInteger& theMVOnIn, TColStd_MapOfInteger& theMVOnIn,
TColStd_MapOfInteger& theMVCommon,
BOPDS_IndexedMapOfPaveBlock& thePBOnIn, BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
BOPDS_MapOfPaveBlock& theCommonPB)const BOPDS_MapOfPaveBlock& theCommonPB)const
{ {
@ -1464,41 +1464,56 @@ void BOPDS_DS::SubShapesOnIn
TColStd_MapIteratorOfMapOfInteger aIt; TColStd_MapIteratorOfMapOfInteger aIt;
BOPDS_IndexedMapOfPaveBlock pMPB[4]; BOPDS_IndexedMapOfPaveBlock pMPB[4];
// //
const BOPDS_FaceInfo& aFI1=FaceInfo(nF1); const BOPDS_FaceInfo& aFI1 = FaceInfo(theNF1);
const BOPDS_FaceInfo& aFI2=FaceInfo(nF2); const BOPDS_FaceInfo& aFI2 = FaceInfo(theNF2);
// //
pMPB[0]=aFI1.PaveBlocksOn(); pMPB[0] = aFI1.PaveBlocksOn();
pMPB[1]=aFI1.PaveBlocksIn(); pMPB[1] = aFI1.PaveBlocksIn();
pMPB[2]=aFI2.PaveBlocksOn(); pMPB[2] = aFI2.PaveBlocksOn();
pMPB[3]=aFI2.PaveBlocksIn(); pMPB[3] = aFI2.PaveBlocksIn();
// //
for (i=0; i<4; ++i) { for (i = 0; i < 4; ++i)
{
aNbPB = pMPB[i].Extent(); aNbPB = pMPB[i].Extent();
for (j = 1; j <= aNbPB; ++j) { for (j = 1; j <= aNbPB; ++j)
{
const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j); const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j);
thePBOnIn.Add(aPB); thePBOnIn.Add(aPB);
aPB->Indices(nV1, nV2); aPB->Indices(nV1, nV2);
theMVOnIn.Add(nV1); theMVOnIn.Add(nV1);
theMVOnIn.Add(nV2); theMVOnIn.Add(nV2);
if (i < 2) {
if (i < 2)
{
if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB)) if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB))
{
theCommonPB.Add(aPB); theCommonPB.Add(aPB);
theMVCommon.Add(nV1);
theMVCommon.Add(nV2);
}
} }
} }
} }
// //
const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn(); const TColStd_MapOfInteger& aMVOn1 = aFI1.VerticesOn();
const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn(); const TColStd_MapOfInteger& aMVIn1 = aFI1.VerticesIn();
const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn(); const TColStd_MapOfInteger& aMVOn2 = aFI2.VerticesOn();
const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn(); const TColStd_MapOfInteger& aMVIn2 = aFI2.VerticesIn();
// //
for (i=0; i<2; ++i) { for (i = 0; i < 2; ++i)
const TColStd_MapOfInteger& aMV1=(!i) ? aMVOn1 : aMVIn1; {
const TColStd_MapOfInteger& aMV1 = (!i) ? aMVOn1 : aMVIn1;
aIt.Initialize(aMV1); aIt.Initialize(aMV1);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next())
nV=aIt.Value(); {
if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) { nV = aIt.Value();
if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV))
{
theMVOnIn.Add(nV); theMVOnIn.Add(nV);
// Vertex taken from the 1st face is in the 2nd one.
theMVCommon.Add(nV);
} }
} }
} }

View File

@ -304,13 +304,15 @@ Standard_EXPORT virtual ~BOPDS_DS();
Standard_EXPORT void RefineFaceInfoOn(); Standard_EXPORT void RefineFaceInfoOn();
//! Returns information about ON/IN subshapes of the given faces. //! Returns information about ON/IN sub-shapes of the given faces.
//! @param theMVOnIn the indices of ON/IN vertices from both faces //! @param theMVOnIn the indices of ON/IN vertices from both faces
//! @param theMVCommon the indices of common vertices for both faces
//! @param thePBOnIn all On/In pave blocks from both faces //! @param thePBOnIn all On/In pave blocks from both faces
//! @param theCommonPB the common pave blocks (that are shared by both faces). //! @param theCommonPB the common pave blocks (that are shared by both faces).
Standard_EXPORT void SubShapesOnIn (const Standard_Integer theF1, Standard_EXPORT void SubShapesOnIn(const Standard_Integer theNF1,
const Standard_Integer theF2, const Standard_Integer theNF2,
TColStd_MapOfInteger& theMVOnIn, TColStd_MapOfInteger& theMVOnIn,
TColStd_MapOfInteger& theMVCommon,
BOPDS_IndexedMapOfPaveBlock& thePBOnIn, BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
BOPDS_MapOfPaveBlock& theCommonPB) const; BOPDS_MapOfPaveBlock& theCommonPB) const;

View File

@ -645,10 +645,14 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
} }
// !!<- process edges that are all on theRef // !!<- process edges that are all on theRef
if (!aE1.IsNull()) { if (!aE1.IsNull()) {
BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, const Standard_Integer anErrID = BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
aP2D, aP3D, theContext); aP2D, aP3D,
aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
theContext); theContext);
if(anErrID == 0)
{
aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
theContext);
}
} }
// //
return aState; return aState;

View File

@ -1,7 +1,3 @@
puts "TODO OCC28802 Linux: Faulty shapes in variables faulty_1 to"
puts "TODO OCC28802 Linux: Error : The area of result shape is"
puts "TODO OCC28802 Linux: Error : The result of General Fuse operation is self-interfered shape"
puts "==========" puts "=========="
puts "OCC26938 " puts "OCC26938 "
puts "==========" puts "=========="
@ -27,4 +23,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
puts "Error : The result of General Fuse operation is self-interfered shape" puts "Error : The result of General Fuse operation is self-interfered shape"
} }
checknbshapes result -solid 1 -shell 1 -t -m "Result"
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,6 +1,3 @@
puts "TODO OCC28802 Linux: Error : The command is not valid. The area is 0"
puts "TODO OCC28802 Linux: Error : The area of result shape is 0"
puts "==========" puts "=========="
puts "OCC26938 " puts "OCC26938 "
puts "==========" puts "=========="
@ -26,4 +23,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
puts "Error : The result of General Fuse operation is self-interfered shape" puts "Error : The result of General Fuse operation is self-interfered shape"
} }
checknbshapes result -solid 1 -shell 1 -t -m "Result"
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,6 +1,6 @@
puts "TODO OCC28802 Linux: Error : The area of result shape is" puts "TODO OCC24694 All: Error : The result of cut operation is self-interfered shape"
puts "TODO OCC24694 Windows: Error : The result of cut operation is self-interfered shape" puts "TODO OCC24694 ALL: Result is WRONG because number of SHELL entities in shape \"result\" is 2"
puts "TODO OCC24694 ALL: Result is WRONG because number of SOLID entities in shape \"result\" is 2"
puts "==========" puts "=========="
puts "OCC26938 " puts "OCC26938 "
puts "==========" puts "=========="
@ -26,4 +26,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
puts "Error : The result of cut operation is self-interfered shape" puts "Error : The result of cut operation is self-interfered shape"
} }
checknbshapes result -solid 3 -shell 3 -t -m "Result"
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,4 +1,7 @@
puts "TODO OCC24694 ALL: Error : The result of cut operation is self-interfered shape" puts "TODO OCC24694 ALL: Error : The result of cut operation is self-interfered shape"
puts "TODO OCC24694 ALL: Result is WRONG because number of SHELL entities in shape \"result\" is 2"
puts "TODO OCC24694 ALL: Result is WRONG because number of SOLID entities in shape \"result\" is 2"
puts "==========" puts "=========="
puts "OCC26938 " puts "OCC26938 "
puts "==========" puts "=========="
@ -24,4 +27,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
puts "Error : The result of cut operation is self-interfered shape" puts "Error : The result of cut operation is self-interfered shape"
} }
checknbshapes result -solid 3 -shell 3 -t -m "Result"
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,50 @@
puts "========"
puts "OCC29179"
puts "========"
puts ""
#################################################
# Result of Boolean common depends on an order of arguments
#################################################
restore [locate_data_file bug26938.brep] a
explode a
bcommon res1 a_1 a_2
restore [locate_data_file bug26938.brep] a
explode a
bcommon res2 a_2 a_1
checkview -display res1 -2d -path ${imagedir}/${test_image}_1.png
checkview -display res2 -2d -path ${imagedir}/${test_image}_2.png
checkshape res1
checkshape res2
if {[regexp "Faulties" [bopargcheck res1]]} {
puts "Error: bopargcheck has found some faulties in res1"
}
if {[regexp "Faulties" [bopargcheck res2]]} {
puts "Error: bopargcheck has found some faulties in res2"
}
checkprops res1 -v 4.93528e+008
checkprops res2 -v 4.93528e+008
set nbshapes_expected "
Number of shapes in .*
VERTEX : 5
EDGE : 7
WIRE : 4
FACE : 4
SHELL : 1
SOLID : 1
COMPSOLID : 0
COMPOUND : 1
SHAPE : 23
"
checknbshapes res1 -ref ${nbshapes_expected} -t -m "1st COMMON"
checknbshapes res2 -ref ${nbshapes_expected} -t -m "2nd COMMON"