1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0028486: Fuse of several solids fails due to presence of common zones between faces

1. Exception in intersection of two analytical faces has been fixed by adding a simple check on number of vertices
in the resulting analytical curve;

2. Projection of the Circle on the Cone now checks if the Circle's normal direction is parallel to the Cone direction.
If it is not, the different, more advanced, algorithm will be used for projection - ProjLib_ComputeApprox;

3. Intersection of the Edge with the Face (IntTools_EdgeFace algorithm) in QuickCoincidenceCheck mode has been fixed to
avoid the checking of the type of the intersection result if the coincidence check gives the positive result;

4. All common IN edges of the intersecting faces has been added for intersection with section edges to avoid self-intersection in the result;

5. Post treatment of the section edges in Boolean operations has been improved with the new stage which treats the possible
common zones, not detected by the intersection algorithm, between faces by intersecting each section edge with all faces,
not participated in its creation, and in case of coincidence putting it as IN edge into FaceInfo structure of the face.
The new function has been implemented for that - BOPAlgo_PaveFiller::PutSEInOtherFaces().

6. Checking for the SameDomain splits of faces in Boolean Operations has been modified to process the pairs of faces in
which both the section curves and common zones are present.

7. Adjustment of the test case boolean gdml_private ZH3 as improvement.

8. Test cases for the issue.

9. Test cases for the parent issue - 0026789.
This commit is contained in:
emv 2017-02-21 11:39:29 +03:00 committed by bugmaster
parent e99816df7f
commit 32e849ebc9
14 changed files with 342 additions and 30 deletions

View File

@ -475,7 +475,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
void BOPAlgo_Builder::FillSameDomainFaces()
{
Standard_Boolean bFlag;
Standard_Integer i, j, k, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
Standard_Integer i, j, k, aNbFFs, nF1, nF2, aNbS;
Handle(NCollection_BaseAllocator) aAllocator;
BOPCol_ListIteratorOfListOfShape aItF;
BOPCol_MapOfShape aMFence;
@ -495,30 +495,6 @@ void BOPAlgo_Builder::FillSameDomainFaces()
const BOPDS_InterfFF& aFF=aFFs(i);
aFF.Indices(nF1, nF2);
//
const BOPDS_VectorOfCurve& aCurves=aFF.Curves();
aNbCurves=aCurves.Extent();
if (aNbCurves) {
//
bFlag=Standard_False;
for (j=0; j<aNbCurves; ++j) {
const BOPDS_Curve& aNC=aCurves.Value(j);
bFlag=aNC.HasEdge();
if (bFlag) {
break;
}
}
if (bFlag) {
continue;
}
//continue;
}
//
const BOPDS_VectorOfPoint& aPoints=aFF.Points();
aNbPoints=aPoints.Extent();
if (aNbPoints) {
continue;
}
//
if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
continue;
}

View File

@ -398,6 +398,14 @@ protected:
Standard_Real& theSLast,
Bnd_Box& theBox);
//! Treatment of the possible common zones, not detected by the
//! Face/Face intersection algorithm, by intersection of each section edge
//! with all faces not participated in creation of that section edge.
//! If the intersection says that the section edge is lying on the face
//! it will be added into FaceInfo structure of the face as IN edge
//! and will be used for splitting.
Standard_EXPORT void PutSEInOtherFaces();
BOPCol_ListOfShape myArguments;
BOPDS_PDS myDS;
BOPDS_PIterator myIterator;

View File

@ -453,7 +453,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
//
myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
//
Standard_Boolean bHasRealSectionEdge = Standard_False;
// 1. Treat Points
for (j=0; j<aNbP; ++j) {
TopoDS_Vertex aV;
@ -577,7 +578,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
Standard_Real aTolNew;
bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
if (bExist) {
if (aMPBAdd.Add(aPBOut)) {
if (!aMPBAdd.Contains(aPBOut)) {
Standard_Boolean bInBothFaces = Standard_True;
if (!myDS->IsCommonBlock(aPBOut)) {
Standard_Integer nE;
@ -600,6 +601,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
aFI2.PaveBlocksIn().Contains(aPBOut));
}
if (!bInBothFaces) {
aMPBAdd.Add(aPBOut);
PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
}
}
@ -627,6 +629,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
//
aMVTol.UnBind(nV1);
aMVTol.UnBind(nV2);
//
bHasRealSectionEdge = Standard_True;
}
//
aLPBC.RemoveFirst();
@ -655,6 +659,28 @@ void BOPAlgo_PaveFiller::MakeBlocks()
}
//
ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
//
// If the pair of faces has produced any real section edges
// it is necessary to check if these edges do not intersect
// any common IN edges of the faces. For that, all such edges
// are added for Post Treatment along with sections edges.
if (bHasRealSectionEdge) {
const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
//
// For simplicity add all IN edges into the first set of section curves.
// These existing edges will be removed from the set on the post treatment
// stage in the UpdateFaceInfo function.
BOPDS_ListOfPaveBlock& aLPBC = aVC.ChangeValue(0).ChangePaveBlocks();
//
Standard_Integer aNbIn1 = aMPBIn1.Extent();
for (j = 1; j <= aNbIn1; ++j) {
const Handle(BOPDS_PaveBlock)& aPB = aMPBIn1(j);
if (aMPBIn2.Contains(aPB) && aMPBAdd.Add(aPB)) {
PreparePostTreatFF(i, 0, aPB, aMSCPB, aMVI, aLPBC);
}
}
}
}//for (i=0; i<aNbFF; ++i) {
//
// post treatment
@ -670,6 +696,11 @@ void BOPAlgo_PaveFiller::MakeBlocks()
UpdateFaceInfo(aDMExEdges, aDMNewSD);
//Update all pave blocks
UpdatePaveBlocks(aDMNewSD);
//
// Treat possible common zones by trying to put each section edge
// into all faces, not participated in creation of that edge, as IN edge
PutSEInOtherFaces();
//
//-----------------------------------------------------scope t
aMF.Clear();
aMVStick.Clear();
@ -2929,3 +2960,116 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
}
}
}
//=======================================================================
//function : PutSEInOtherFaces
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::PutSEInOtherFaces()
{
// Try to intersect each section edge with the faces
// not participated in its creation
//
// 1. Get all section edges
BOPDS_IndexedMapOfPaveBlock aMPBScAll;
//
BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
Standard_Integer i, j, aNbFF = aFFs.Extent();
//
for (i = 0; i < aNbFF; ++i) {
const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves();
Standard_Integer aNbC = aVNC.Extent();
for (j = 0; j < aNbC; ++j) {
const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks();
BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC);
for (; aItPB.More(); aItPB.Next()) {
aMPBScAll.Add(aItPB.Value());
}
}
}
//
Standard_Integer aNbPBSc = aMPBScAll.Extent();
//
// 2. Loop for all faces and check each section curve
Standard_Integer aNbS = myDS->NbSourceShapes();
for (i = 0; i < aNbS; ++i) {
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_FACE) {
continue;
}
//
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape()));
BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
//
// IN edges to add new ones
BOPDS_IndexedMapOfPaveBlock& aMFPBIn = aFI.ChangePaveBlocksIn();
// Section edges to check the participation of the face
const BOPDS_IndexedMapOfPaveBlock& aMFPBSc = aFI.PaveBlocksSc();
//
// Get vertices of the face to check that vertices of the
// processed section edge belong to the face
BOPCol_MapOfInteger aMFVerts;
// Get vertices from ON, IN and Sc pave blocks of the face
for (j = 0; j < 3; ++j) {
const BOPDS_IndexedMapOfPaveBlock& aMPB =
!j ? aFI.PaveBlocksOn() : (j == 1 ? aMFPBIn : aMFPBSc);
Standard_Integer aNbPB = aMPB.Extent();
for (Standard_Integer k = 1; k <= aNbPB; ++k) {
const Handle(BOPDS_PaveBlock)& aPB = aMPB(k);
aMFVerts.Add(aPB->Pave1().Index());
aMFVerts.Add(aPB->Pave2().Index());
}
}
// Add ON, IN and Sc vertices of the face
for (j = 0; j < 3; ++j) {
const BOPCol_MapOfInteger& aMFV = !j ? aFI.VerticesOn() :
(j == 1 ? aFI.VerticesIn() : aFI.VerticesSc());
BOPCol_MapIteratorOfMapOfInteger aItMI(aMFV);
for (; aItMI.More(); aItMI.Next()) {
aMFVerts.Add(aItMI.Value());
}
}
//
// Check each section edge for possible belonging to the face
for (j = 1; j <= aNbPBSc; ++j) {
const Handle(BOPDS_PaveBlock)& aPB = aMPBScAll(j);
if (aMFPBSc.Contains(aPB)) {
continue;
}
//
// Both vertices of the section edge should belong to the face
if (!aMFVerts.Contains(aPB->Pave1().Index()) ||
!aMFVerts.Contains(aPB->Pave2().Index())) {
continue;
}
//
// Perform intersection
const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
//
IntTools_EdgeFace anEFInt;
anEFInt.SetEdge(aE);
anEFInt.SetFace(aF);
anEFInt.SetFuzzyValue(myFuzzyValue);
anEFInt.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter());
anEFInt.SetContext(myContext);
anEFInt.UseQuickCoincidenceCheck(Standard_True);
anEFInt.Perform();
//
const IntTools_SequenceOfCommonPrts& aCPrts = anEFInt.CommonParts();
if ((aCPrts.Length() == 1) && (aCPrts(1).Type() == TopAbs_EDGE)) {
Handle(BOPDS_CommonBlock) aCB;
if (myDS->IsCommonBlock(aPB)) {
aCB = myDS->CommonBlock(aPB);
}
else {
aCB = new BOPDS_CommonBlock;
aCB->AddPaveBlock(aPB);
}
//
aCB->AddFace(i);
//
aMFPBIn.Add(aPB);
}
}
}
}

View File

@ -280,6 +280,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
IntPatch_SequenceOfLine& theLines) const
{
const Standard_Integer aNbVert = theALine->NbVertex();
if (!aNbVert) {
return;
}
const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;

View File

@ -659,7 +659,6 @@ void IntTools_EdgeFace::Perform()
if (IsCoincident()) {
aCommonPrt.SetType(TopAbs_EDGE);
aCommonPrt.SetRange1(myRange.First(), myRange.Last());
MakeType (aCommonPrt);
mySeqOfCommonPrts.Append(aCommonPrt);
myIsDone=Standard_True;
return;

View File

@ -143,7 +143,12 @@ void ProjLib_Cone::Project(const gp_Circ& C)
gp_Ax3 ConePos = myCone.Position();
gp_Ax3 CircPos = C.Position();
//
if (!ConePos.Direction().IsParallel(CircPos.Direction(), Precision::Angular())) {
isDone = Standard_False;
return;
}
//
gp_Dir ZCone = ConePos.XDirection().Crossed(ConePos.YDirection());
gp_Dir ZCir = CircPos.XDirection().Crossed(CircPos.YDirection());

View File

@ -1,3 +1,2 @@
puts "TODO OCC26018 ALL: Faulty shapes in variables faulty_1 to faulty_"
source [locate_data_file 51679_tkz_montecristo_sbr.prt.1.gdml.tcl]

View File

@ -0,0 +1,29 @@
puts "TODO 0026789 ALL: Error : The area of result shape is"
puts "TODO 0026789 ALL: Error : The volume of result shape is"
puts "TODO 0026789 ALL: Error : is WRONG because number of SOLID entities in shape"
puts "TODO 0026789 ALL: Error : is WRONG because number of SHELL entities in shape"
puts "TODO 0026789 ALL: Faulty shapes in variables faulty_"
puts "========"
puts "OCC26789"
puts "========"
puts ""
#################################################
# Fuse of several solids fails
#################################################
restore [locate_data_file bug26789_All-Spikes.brep] a
explode a
# fusing all solids
bclearobjects
bcleartools
baddobjects a_1
baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9
bfillds
bbop result 1
checkshape result
checknbshapes result -solid 1 -shell 2
checkprops result -s 3583.27 -v 11455.2
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,25 @@
puts "========"
puts "OCC26789"
puts "========"
puts ""
#################################################
# Fuse of several solids fails
#################################################
restore [locate_data_file bug26789_All-Spikes.brep] a
# reducing tolerance of the shape
settolerance a 1.e-7
explode a
# fusing all solids
bclearobjects
bcleartools
baddobjects a_1
baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9
bfillds
bbop result 1
checkshape result
checknbshapes result -solid 1 -shell 2
checkprops result -s 3583.27 -v 11455.2
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,25 @@
puts "========"
puts "OCC26789"
puts "========"
puts ""
#################################################
# Fuse of several solids fails
#################################################
restore [locate_data_file bug26789_All-Spikes.brep] a
explode a
# fusing all solids one by one
bfuse result a_1 a_2
bfuse result result a_3
bfuse result result a_4
bfuse result result a_5
bfuse result result a_6
bfuse result result a_7
bfuse result result a_8
bfuse result result a_9
checkshape result
checknbshapes result -solid 1 -shell 2
checkprops result -s 3583.27 -v 11455.2
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,23 @@
puts "========"
puts "OCC28486"
puts "========"
puts ""
#################################################
# Fuse of several solids fails due to presence of common zones between faces
#################################################
restore [locate_data_file bug26789_All-Spikes.brep] a
explode a
# fusing first, third and fourth solids
bclearobjects
bcleartools
baddobjects a_1
baddtools a_3 a_4
bfillds
bbop result 1
checkshape result
checknbshapes result -solid 1 -shell 1
checkprops result -s 2237.86 -v 5444.61
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,23 @@
puts "========"
puts "OCC28486"
puts "========"
puts ""
#################################################
# Fuse of several solids fails due to presence of common zones between faces
#################################################
restore [locate_data_file bug26789_All-Spikes.brep] a
explode a
# fusing third, fourth and seventh solids
bclearobjects
bcleartools
baddobjects a_3
baddtools a_4 a_7
bfillds
bbop result 1
checkshape result
checknbshapes result -solid 1 -shell 1
checkprops result -s 2237.86 -v 5444.61
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,23 @@
puts "========"
puts "OCC28486"
puts "========"
puts ""
#################################################
# Fuse of several solids fails due to presence of common zones between faces
#################################################
restore [locate_data_file bug26789_All-Spikes.brep] a
explode a
# fusing all solids except seventh and eighth
bclearobjects
bcleartools
baddobjects a_1
baddtools a_2 a_3 a_4 a_5 a_6 a_9
bfillds
bbop result 1
checkshape result
checknbshapes result -solid 1 -shell 2
checkprops result -s 3273.89 -v 9907.1
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -0,0 +1,30 @@
puts "========"
puts "OCC28486"
puts "========"
puts ""
#################################################
# Fuse of several solids fails due to presence of common zones between faces
#################################################
plane p 0 0 0 0 0 1
mkface f1 p -10 10 -10 10
copy f1 f2
trotate f2 0 0 0 1 0 0 20
line l 0 0 0 0 1 0
mkedge e l -8 8
trotate e 0 0 0 1 0 0 10
settolerance e 1.5
donly f1 f2 e
bclearobjects
bcleartools
baddobjects f1 f2
baddtools e
bfillds
bbuild result
checkshape result
checknbshapes result -face 4 -wire 8
checkprops result -s 800
checkview -display result -2d -path ${imagedir}/${test_image}.png