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

0028683: Wrong result of CUT operation

Avoid creation of the small section edges in the Boolean Operations algorithm.
This commit is contained in:
emv 2017-04-26 15:42:13 +03:00 committed by bugmaster
parent 7e3451c7a2
commit 6769ec6b34
9 changed files with 101 additions and 84 deletions

View File

@ -304,7 +304,8 @@ void BOPAlgo_PaveFiller::PerformInternal()
}
//
UpdateInterfsWithSDVertices();
RefineFaceInfoOn();
myDS->ReleasePaveBlocks();
myDS->RefineFaceInfoOn();
//
MakePCurves();
if (myErrorStatus) {

View File

@ -311,12 +311,6 @@ protected:
//! Keeps data for post treatment
Standard_EXPORT void PreparePostTreatFF (const Standard_Integer aInt, const Standard_Integer aCur, const Handle(BOPDS_PaveBlock)& aPB, BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB, BOPCol_DataMapOfShapeInteger& aMVI, BOPDS_ListOfPaveBlock& aLPB);
//! Refines the state On for the all faces having
//! state information
Standard_EXPORT void RefineFaceInfoOn();
//! Updates the information about faces
Standard_EXPORT void UpdateFaceInfo (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME, const BOPCol_DataMapOfIntegerInteger& theDMV);

View File

@ -465,9 +465,6 @@ void BOPAlgo_PaveFiller::PerformEF()
nF=aItMI.Value();
myDS->UpdateFaceInfoIn(nF);
}
// Refine FaceInfoOn to remove all formal pave blocks
// made during EF processing
//myDS->RefineFaceInfoOn();
//-----------------------------------------------------scope t
aMIEFC.Clear();
aMVCPB.Clear();

View File

@ -799,25 +799,37 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
for (k = 1; k <= aNbME; ++k) {
const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k));
//
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aEM, aV1, aV2);
TopoDS_Vertex aVerts[2];
TopExp::Vertices(aEM, aVerts[0], aVerts[1]);
for (Standard_Integer i = 0; i < 2; ++i) {
nV = myDS->Index(aVerts[i]);
const Standard_Integer* pSD = aDMNewSD.Seek(nV);
if (pSD) {
aVerts[i] = TopoDS::Vertex(myDS->Shape(*pSD));
}
//
if (anAddedSD.Add(aVerts[i])) {
aLS.Append(aVerts[i]);
}
}
//
aLS.Append(aV1);
aLS.Append(aV2);
if (aVerts[0].IsSame(aVerts[1])) {
continue;
}
//
// make sure these vertices will be united
const gp_Pnt& aP1 = BRep_Tool::Pnt(aV1);
const gp_Pnt& aP2 = BRep_Tool::Pnt(aV2);
const gp_Pnt& aP1 = BRep_Tool::Pnt(aVerts[0]);
const gp_Pnt& aP2 = BRep_Tool::Pnt(aVerts[1]);
//
Standard_Real aDist = aP1.Distance(aP2);
Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1);
Standard_Real aTolV2 = BRep_Tool::Tolerance(aV2);
Standard_Real aTolV1 = BRep_Tool::Tolerance(aVerts[0]);
Standard_Real aTolV2 = BRep_Tool::Tolerance(aVerts[1]);
//
aDist -= (aTolV1 + aTolV2);
if (aDist > 0.) {
aDist /= 2.;
aBB.UpdateVertex(aV1, aTolV1 + aDist);
aBB.UpdateVertex(aV2, aTolV2 + aDist);
aBB.UpdateVertex(aVerts[0], aTolV1 + aDist);
aBB.UpdateVertex(aVerts[1], aTolV2 + aDist);
}
}
//
@ -935,24 +947,10 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
aLPBC.Remove(aItLPB);
break;
}
}
}
}
//
if (!aNbLPBx) {
aE=aSx;
//
iE = myDS->Index(aE);
if (iE < 0) {
aSI.SetShapeType(aType);
aSI.SetShape(aE);
iE=myDS->Append(aSI);
}
// append new PaveBlock to aLPBC
aPB1->SetEdge(iE);
aLPBC.Append(aPB1);
} // if (!aNbLPBx) {
//
else {
if (aNbLPBx) {
aItLPB.Initialize(aLPBx);
for (; aItLPB.More(); aItLPB.Next()) {
const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
@ -2054,7 +2052,17 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
aMVTol.Bind(nVUsed, aTolV);
}
}
pList->Append(nV);
// avoid repeated elements in the list
BOPCol_ListIteratorOfListOfInteger aItLI(*pList);
for (; aItLI.More(); aItLI.Next()) {
if (aItLI.Value() == nV) {
break;
}
}
if (!aItLI.More()) {
pList->Append(nV);
}
// save initial tolerance for the vertex
if (!aMVTol.IsBound(nV)) {
aTolV = BRep_Tool::Tolerance(aV);
aMVTol.Bind(nV, aTolV);

View File

@ -678,51 +678,6 @@ void BOPAlgo_PaveFiller::MakePCurves()
//======================================================
}
//=======================================================================
// function: RefineFaceInfoOn
// purpose:
//=======================================================================
void BOPAlgo_PaveFiller::RefineFaceInfoOn()
{
Standard_Integer aNbPBP;
//
myErrorStatus=0;
//
BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
aNbPBP=aPBP.Extent();
if(!aNbPBP) {
return;
}
//
Standard_Boolean bV1, bV2;
Standard_Integer i, nV1, nV2, aNbPB;
Handle(BOPDS_PaveBlock) aPB;
//
for (i=0; i<aNbPBP; ++i) {
BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
//
aNbPB=aLPB.Extent();
if (aNbPB==1) {
aPB=aLPB.First();
aPB->Indices(nV1, nV2);
bV1=myDS->IsNewShape(nV1);
bV2=myDS->IsNewShape(nV2);
//
if (!(bV1 || bV2)) {
if (!myDS->IsCommonBlock(aPB)) {
// the PB seems to be untouced
aLPB.Clear();
Standard_Integer nE = aPB->OriginalEdge();
if (nE >= 0) {
myDS->ChangeShapeInfo(nE).SetReference(-1);
}
continue;
}
}//if (!(bV1 || bV2)) {
}//if (aNbPB==1) {
}//for (i=0; i<aNbPBP; ++i) {
myDS->RefineFaceInfoOn();
}
//=======================================================================
//function : UpdateVertices
//purpose : update tolerances of vertices comparing extremities of
// 3d and 2d curves

View File

@ -222,7 +222,7 @@ void BOPAlgo_PaveFiller::ProcessDE()
aPB->SetEdge(nSp);
}
else {
//aPB->SetEdge(nDE);
myDS->ChangeShapeInfo(nDE).SetReference(-1);
aLPB.Clear();
break;
}

View File

@ -2105,3 +2105,47 @@ void BOPDS_DS::InitPaveBlocksForVertex(const Standard_Integer theNV)
}
}
}
//=======================================================================
//function : ReleasePaveBlocks
//purpose :
//=======================================================================
void BOPDS_DS::ReleasePaveBlocks()
{
// It is necessary to remove the reference to PaveBlocks for the untouched
// edges to avoid creation of the same images for them.
// Pave blocks for this reference should be cleared.
// This will allow to differ the small edges, for which it is
// impossible to even build a pave block from the normal edges for which the
// pave block have been created, but stayed untouched.
// The small edge, for which no pave blocks have been created,
// should be avoided in the result, thus the reference to empty list
// of pave blocks will stay to mark the edge as Deleted.
BOPDS_VectorOfListOfPaveBlock& aPBP = ChangePaveBlocksPool();
Standard_Integer aNbPBP = aPBP.Extent();
if (!aNbPBP) {
return;
}
//
for (Standard_Integer i = 0; i < aNbPBP; ++i) {
BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
if (aLPB.Extent() == 1) {
const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
if (!IsCommonBlock(aPB)) {
Standard_Integer nV1, nV2;
aPB->Indices(nV1, nV2);
if (!IsNewShape(nV1) && !IsNewShape(nV2)) {
// Both vertices are original, thus the PB is untouched.
// Remove reference for the original edge
Standard_Integer nE = aPB->OriginalEdge();
if (nE >= 0) {
ChangeShapeInfo(nE).SetReference(-1);
}
// Clear contents of the list
aLPB.Clear();
}
}
}
}
}

View File

@ -460,6 +460,9 @@ Standard_EXPORT virtual ~BOPDS_DS();
Standard_EXPORT void InitPaveBlocksForVertex(const Standard_Integer theNV);
//! Clears information about PaveBlocks for the untouched edges
Standard_EXPORT void ReleasePaveBlocks();
protected:
@ -478,7 +481,7 @@ protected:
Standard_EXPORT Standard_Boolean CheckCoincidence (const Handle(BOPDS_PaveBlock)& thePB1,
const Handle(BOPDS_PaveBlock)& thePB2,
const Standard_Real theFuzz);
//! Computes bouding box <theBox> for the solid with DS-index <theIndex>
Standard_EXPORT void BuildBndBoxSolid (const Standard_Integer theIndex, Bnd_Box& theBox);

View File

@ -0,0 +1,15 @@
puts "========"
puts "OCC28683"
puts "========"
puts ""
####################################################################################
## Wrong result of CUT operation
####################################################################################
restore [locate_data_file bug28683_shapes.brep] b
explode b
bcut result b_1 b_2
donly result
checkshape result
checkprops result -s 1.82492
checknbshapes result -vertex 6 -edge 6 -wire 1 -face 1