1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0027448: BOPTools_AlgoTools::IsMicroEdge does not correspond to shape validity criteria

1. IntTools_ShrunkRange::Perform
The algorithm of building shrunk range on the edge has been redesigned to make this range as big as possible.
By new definition it has to have the length not less than Precision::Confusion().
Although, the possibility of splitting of the edge has been taken into account. If it is impossible to put
vertex on edge in such a way that the tolerance spheres of the edge's vertices do not intersect the tolerance
sphere of the putting vertex the edge cannot be split. This possibility is saved in the new field
IntTools_ShrunkRange::myIsSplittable. It can be checked by the corresponding method IntTools_ShrunkRange::IsSplittable().
It returns TRUE if the shrunk range is computed successfully and it has the length more than the value of sum of two tolerance
values of the edge (for putting vertex, as its tolerance should not be less than the tolerance value of edge) and
two Precision::Confusion() values (to make two new edges valid by Shape validity criteria).

IntTools_ShrunkRange::myErrorStatus and IntTools_ShrunkRange::ErrorStatus() have been replaced by
the IntTools_ShrunkRange::myIsDone and IntTools_ShrunkRange::IsDone(). IntTools_ShrunkRange::IsDone() returns TRUE
if the shrunk range has been computed and it has length more than Precision::Confusion().

All computations of the parameters are performed using the GCPnts_AbscissaPoint, but if AbscissaPoint is unable to
compute the parameters the Resolution of the curve is used.

2. Boolean Operations algorithm now partially works with the edges that cannot be split or does not have the ShrunkData
at all (previously such edges have been considered as micro and just ignored). If by the result of some intersection such
edges should be split, i.e. the intersection vertex should be created, the algorithm just ignores them and no vertex is created.
But if such edges coincide with other shapes (other edges or faces) the algorithm uses them for creation of common blocks.
The information of the possibility for the edges to be split is saved in its PaveBlocks, in the new BOPDS_PaveBlock::myIsSplittable field.
It can be retrieved by the BOPDS_PaveBlock::IsSplittable() or BOPDS_PaveBlock::ShrunkData(), but these methods
make sense only after filling of the shrunk data for the pave block.

BOPTools_AlgoTools::IsMicroEdge() has an additional parameter that defines whether it is necessary to take into account
the possibility for the edge to be split or not. By default it is set to TRUE, i.e. by default the edge will be considered as micro
even if the shrunk range is computed, but it is too short for the edge to be split.

3. BOPAlgo_PaveFiller::PerformEF
To avoid creation of too close intersection vertices the intersection ranges of the edges participating in Edge/Face
intersections are reduced taking into account the common ranges computed during Edge/Edge intersections.
Thus, the Edge/Face intersection vertex is not created if it gets into a common range of the Edge/Edge intersection
between that edge and one of the face's edges. The tolerance value of Edge/Edge intersection vertex is increased
to reach the Edge/Face intersection.

4. Unification of the vertices of the section edges considered as micro edges.
If by the result of some Face/Face intersection the section edge is considered as micro edge,
the vertices of this edge will be united and the edge itself will be removed.

5. Test cases for the issues.

6. Adjusting test cases for issue CR27448.
This commit is contained in:
emv
2016-05-04 16:42:55 +03:00
committed by bugmaster
parent 1aee6c8210
commit 01b5b3df55
24 changed files with 527 additions and 491 deletions

View File

@@ -33,6 +33,7 @@
#include <Standard_Integer.hxx>
#include <BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks.hxx>
#include <Standard_Boolean.hxx>
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPCol_MapOfInteger.hxx>
#include <BOPCol_DataMapOfIntegerReal.hxx>
#include <BOPCol_ListOfInteger.hxx>
@@ -51,9 +52,10 @@ class BOPDS_DS;
class BOPAlgo_SectionAttribute;
class BOPDS_PaveBlock;
class BOPDS_CommonBlock;
class TopoDS_Vertex;
class gp_Pnt;
class BOPDS_Curve;
class TopoDS_Vertex;
class TopoDS_Edge;
class TopoDS_Face;
@@ -107,6 +109,12 @@ public:
protected:
typedef NCollection_DataMap
<Handle(BOPDS_PaveBlock),
Bnd_Box,
TColStd_MapTransientHasher> BOPAlgo_DataMapOfPaveBlockBndBox;
//! Sets non-destructive mode automatically if an argument
//! contains a locked sub-shape (see TopoDS_Shape::Locked()).
Standard_EXPORT void SetNonDestructive();
@@ -197,7 +205,12 @@ protected:
//! Treatment of section edges.
Standard_EXPORT Standard_Integer PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB, BOPCol_DataMapOfShapeInteger& theMVI, BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges, BOPCol_DataMapOfIntegerInteger& theDMI, const BOPCol_BaseAllocator& theAllocator);
Standard_EXPORT Standard_Integer PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
BOPCol_DataMapOfShapeInteger& theMVI,
BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
BOPCol_DataMapOfIntegerInteger& theDMI,
const BOPCol_IndexedMapOfShape& theMicroEdges,
const BOPCol_BaseAllocator& theAllocator);
Standard_EXPORT void FindPaveBlocks (const Standard_Integer theV, const Standard_Integer theF, BOPDS_ListOfPaveBlock& theLPB);
@@ -322,6 +335,34 @@ protected:
Standard_EXPORT void CorrectToleranceOfSE();
//! Reduce the intersection range using the common ranges of
//! Edge/Edge interferences to avoid creation of close
//! intersection vertices
Standard_EXPORT void ReduceIntersectionRange(const Standard_Integer theV1,
const Standard_Integer theV2,
const Standard_Integer theE,
const Standard_Integer theF,
Standard_Real& theTS1,
Standard_Real& theTS2);
//! Gets the bounding box for the given Pave Block.
//! If Pave Block has shrunk data it will be used to get the box,
//! and the Shrunk Range (<theSFirst>, <theSLast>).
//! Otherwise the box will be computed using BndLib_Add3dCurve method,
//! and the Shrunk Range will be equal to the PB's range.
//! To avoid re-computation of the bounding box for the same Pave Block
//! it will be saved in the map <thePBBox>.
//! Returns FALSE in case the PB's range is less than the
//! Precision::PConfusion(), otherwise returns TRUE.
Standard_EXPORT Standard_Boolean GetPBBox(const TopoDS_Edge& theE,
const Handle(BOPDS_PaveBlock)& thePB,
BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox,
Standard_Real& theFirst,
Standard_Real& theLast,
Standard_Real& theSFirst,
Standard_Real& theSLast,
Bnd_Box& theBox);
BOPCol_ListOfShape myArguments;
BOPDS_PDS myDS;
BOPDS_PIterator myIterator;

View File

@@ -198,7 +198,12 @@ void BOPAlgo_PaveFiller::PerformVE()
}
//
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
if (aLPB.IsEmpty() || !aLPB.First()->HasShrunkData()) {
if (aLPB.IsEmpty()) {
continue;
}
//
const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
if (!aPB->IsSplittable()) {
// this is a micro edge, ignore it
continue;
}
@@ -231,13 +236,14 @@ void BOPAlgo_PaveFiller::PerformVE()
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
Bnd_Box aBox;
Standard_Boolean bIsPBSplittable;
aPB->Range(aT1, aT2);
aPB->ShrunkData(aTS1, aTS2, aBox);
aPB->ShrunkData(aTS1, aTS2, aBox, bIsPBSplittable);
IntTools_Range aPaveR[2] = { IntTools_Range(aT1, aTS1), IntTools_Range(aTS2, aT2) };
Standard_Real aTol = Precision::Confusion();
Standard_Boolean isOnPave = Standard_False;
for (Standard_Integer i = 0; i < 2; i++) {
if (IntTools_Tools::IsOnPave1(aT, aPaveR[i], aTol)) {
if (!bIsPBSplittable || IntTools_Tools::IsOnPave1(aT, aPaveR[i], aTol)) {
Standard_Integer nV1 = (i == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
if (!myDS->HasInterf(nV, nV1)) {
BOPCol_ListOfInteger aLI;

View File

@@ -40,7 +40,7 @@
#include <BOPDS_PaveBlock.hxx>
#include <BOPDS_VectorOfInterfEE.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <BRep_Tool.hxx>
#include <BRepBndLib.hxx>
#include <BRepTools.hxx>
@@ -281,8 +281,8 @@ void BOPAlgo_PaveFiller::PerformEE()
return;
}
//
Standard_Boolean bJustAdd, bExpressCompute;
Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbFdgeEdge;
Standard_Boolean bJustAdd, bExpressCompute, bIsPBSplittable1, bIsPBSplittable2;
Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbEdgeEdge;
Standard_Integer nV11, nV12, nV21, nV22;
Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22;
TopAbs_ShapeEnum aType;
@@ -296,6 +296,7 @@ void BOPAlgo_PaveFiller::PerformEE()
//-----------------------------------------------------scope f
BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator);
BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
//
BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
aEEs.SetIncrement(iSize);
@@ -316,7 +317,7 @@ void BOPAlgo_PaveFiller::PerformEE()
}
//
const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape()));
const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));
const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));
//
BOPDS_ListOfPaveBlock& aLPB1=myDS->ChangePaveBlocks(nE1);
BOPDS_ListOfPaveBlock& aLPB2=myDS->ChangePaveBlocks(nE2);
@@ -326,10 +327,10 @@ void BOPAlgo_PaveFiller::PerformEE()
Bnd_Box aBB1;
//
Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue();
if (!aPB1->HasShrunkData()) {
//
if (!GetPBBox(aE1, aPB1, aDMPBBox, aT11, aT12, aTS11, aTS12, aBB1)) {
continue;
}
aPB1->ShrunkData(aTS11, aTS12, aBB1);
//
aPB1->Indices(nV11, nV12);
//
@@ -338,18 +339,15 @@ void BOPAlgo_PaveFiller::PerformEE()
Bnd_Box aBB2;
//
Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue();
if (!aPB2->HasShrunkData()) {
//
if (!GetPBBox(aE2, aPB2, aDMPBBox, aT21, aT22, aTS21, aTS22, aBB2)) {
continue;
}
aPB2->ShrunkData(aTS21, aTS22, aBB2);
//
if (aBB1.IsOut(aBB2)) {
continue;
}
//
aPB1->Range(aT11, aT12);
aPB2->Range(aT21, aT22);
//
aPB2->Indices(nV21, nV22);
//
bExpressCompute=((nV11==nV21 && nV12==nV22) ||
@@ -369,12 +367,12 @@ void BOPAlgo_PaveFiller::PerformEE()
}//for (; aIt1.More(); aIt1.Next()) {
}//for (; myIterator->More(); myIterator->Next()) {
//
aNbFdgeEdge=aVEdgeEdge.Extent();
aNbEdgeEdge=aVEdgeEdge.Extent();
//======================================================
BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
//======================================================
//
for (k=0; k < aNbFdgeEdge; ++k) {
for (k = 0; k < aNbEdgeEdge; ++k) {
Bnd_Box aBB1, aBB2;
//
BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k);
@@ -386,12 +384,26 @@ void BOPAlgo_PaveFiller::PerformEE()
Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1();
nE1=aPB1->OriginalEdge();
aPB1->Range(aT11, aT12);
aPB1->ShrunkData(aTS11, aTS12, aBB1);
if (!aPB1->HasShrunkData()) {
aTS11 = aT11;
aTS12 = aT12;
bIsPBSplittable1 = Standard_False;
}
else {
aPB1->ShrunkData(aTS11, aTS12, aBB1, bIsPBSplittable1);
}
//
Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2();
nE2=aPB2->OriginalEdge();
aPB2->Range(aT21, aT22);
aPB2->ShrunkData(aTS21, aTS22, aBB2);
if (!aPB2->HasShrunkData()) {
aTS21 = aT21;
aTS22 = aT22;
bIsPBSplittable2 = Standard_False;
}
else {
aPB2->ShrunkData(aTS21, aTS22, aBB2, bIsPBSplittable2);
}
//
//--------------------------------------------
IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12),
@@ -420,6 +432,10 @@ void BOPAlgo_PaveFiller::PerformEE()
aType=aCPart.Type();
switch (aType) {
case TopAbs_VERTEX: {
if (!bIsPBSplittable1 || !bIsPBSplittable2) {
continue;
}
//
Standard_Boolean bIsOnPave[4], bFlag;
Standard_Integer nV[4], j;
Standard_Real aT1, aT2, aTol;
@@ -849,7 +865,7 @@ void BOPAlgo_PaveFiller::TreatNewVertices
//=======================================================================
void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
{
Standard_Integer nE, nV1, nV2, iErr;
Standard_Integer nE, nV1, nV2;
Standard_Real aT1, aT2, aTS1, aTS2;
IntTools_ShrunkRange aSR;
//
@@ -873,17 +889,16 @@ void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
aSR.SetData(aE, aT1, aT2, aV1, aV2);
//
aSR.Perform();
iErr=aSR.ErrorStatus();
if (iErr) {
if (!aSR.IsDone()) {
myWarningStatus = 1;
//myErrorStatus=40;
return;
}
//
aSR.ShrunkRange(aTS1, aTS2);
const Bnd_Box& aBox=aSR.BndBox();
Standard_Boolean bIsSplittable = aSR.IsSplittable();
//
thePB->SetShrunkData(aTS1, aTS2, aBox);
thePB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
}
//=======================================================================
//function : ForceInterfVE
@@ -952,3 +967,46 @@ void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
aMPBToUpdate.Add(aPB);
}
}
//=======================================================================
//function : GetPBBox
//purpose :
//=======================================================================
Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
const Handle(BOPDS_PaveBlock)& thePB,
BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox,
Standard_Real& theFirst,
Standard_Real& theLast,
Standard_Real& theSFirst,
Standard_Real& theSLast,
Bnd_Box& theBox)
{
thePB->Range(theFirst, theLast);
// check the validity of PB's range
Standard_Boolean bValid = theLast - theFirst > Precision::PConfusion();
if (!bValid) {
return bValid;
}
//
// check shrunk data
if (thePB->HasShrunkData()) {
Standard_Boolean bIsSplittable;
thePB->ShrunkData(theSFirst, theSLast, theBox, bIsSplittable);
return bValid;
}
//
theSFirst = theFirst;
theSLast = theLast;
// check the map
if (thePBBox.IsBound(thePB)) {
theBox = thePBBox.Find(thePB);
}
else {
// build bounding box
BRepAdaptor_Curve aBAC(theE);
Standard_Real aTol = BRep_Tool::Tolerance(theE) + Precision::Confusion();
BndLib_Add3dCurve::Add(aBAC, theSFirst, theSLast, aTol, theBox);
thePBBox.Bind(thePB, theBox);
}
return bValid;
}

View File

@@ -37,6 +37,7 @@
#include <BOPDS_Pave.hxx>
#include <BOPDS_PaveBlock.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
@@ -146,7 +147,7 @@ void BOPAlgo_PaveFiller::PerformEF()
return;
}
//
Standard_Boolean bJustAdd, bV[2];
Standard_Boolean bJustAdd, bV[2], bIsPBSplittable;
Standard_Boolean bV1, bV2, bExpressCompute;
Standard_Integer nV1, nV2;
Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
@@ -163,6 +164,7 @@ void BOPAlgo_PaveFiller::PerformEF()
BOPCol_MapOfInteger aMIEFC(100, aAllocator);
BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
//
aDiscretize=35;
aDeflection=0.01;
@@ -204,13 +206,11 @@ void BOPAlgo_PaveFiller::PerformEF()
continue;
}
//
if (!aPB->HasShrunkData()) {
Bnd_Box aBBE;
if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) {
continue;
}
//
Bnd_Box aBBE;
aPB->ShrunkData(aTS1, aTS2, aBBE);
//
if (aBBF.IsOut (aBBE)) {
continue;
}
@@ -238,7 +238,6 @@ void BOPAlgo_PaveFiller::PerformEF()
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
aEdgeFace.SetNewSR(anewSR);
//
aPB->Range(aT1, aT2);
IntTools_Range aPBRange(aT1, aT2);
aSR = aPBRange;
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
@@ -271,6 +270,17 @@ void BOPAlgo_PaveFiller::PerformEF()
//
aPB->Range(aT1, aT2);
aPB->Indices(nV[0], nV[1]);
bIsPBSplittable = aPB->IsSplittable();
//
Standard_Real aTS1, aTS2;
anewSR.Range(aTS1, aTS2);
//
// extend vertices ranges using Edge/Edge intersections
// between the edge aE and the edges of the face aF.
// thereby the edge's intersection range is reduced
ReduceIntersectionRange(nV[0], nV[1], nE, nF, aTS1, aTS2);
//
IntTools_Range aR1(aT1, aTS1), aR2(aTS2, aT2);
//
BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
@@ -292,7 +302,7 @@ void BOPAlgo_PaveFiller::PerformEF()
const IntTools_CommonPrt& aCPart=aCPrts(i);
aType=aCPart.Type();
switch (aType) {
case TopAbs_VERTEX: {
case TopAbs_VERTEX: {
Standard_Boolean bIsOnPave[2];
Standard_Integer j;
Standard_Real aT, aTolToDecide;
@@ -304,8 +314,6 @@ void BOPAlgo_PaveFiller::PerformEF()
const IntTools_Range& aR=aCPart.Range1();
aTolToDecide=5.e-8;
//
IntTools_Range aR1(aT1,anewSR.First()),aR2(anewSR.Last(), aT2);
//
bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide);
bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide);
//
@@ -328,6 +336,11 @@ void BOPAlgo_PaveFiller::PerformEF()
break;
}
}
//
if (!bIsPBSplittable) {
continue;
}
//
for (j=0; j<2; ++j) {
if (bIsOnPave[j]) {
bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
@@ -342,15 +355,14 @@ void BOPAlgo_PaveFiller::PerformEF()
gp_Pnt aP1 = BRep_Tool::Pnt(aV);
gp_Pnt aP2 = aCur->Value(aT);
//
aDistPP=aP1.Distance(aP2);
//
aTolPC=Precision::PConfusion();
aTolV=BRep_Tool::Tolerance(aV);
if (aDistPP > (aTolV+aTolPC)) {
aTolVnew=Max(aTolE, aDistPP);
UpdateVertex(nV[j], aTolVnew);
}
}
}
else {
bIsOnPave[j] = ForceInterfVF(nV[j], nF);
@@ -723,3 +735,77 @@ Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
}
return bRet;
}
//=======================================================================
//function : ReduceIntersectionRange
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
const Standard_Integer theV2,
const Standard_Integer theE,
const Standard_Integer theF,
Standard_Real& theTS1,
Standard_Real& theTS2)
{
if (!myDS->IsNewShape(theV1) &&
!myDS->IsNewShape(theV2)) {
return;
}
//
BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
Standard_Integer aNbEEs = aEEs.Extent();
if (!aNbEEs) {
return;
}
//
Standard_Integer i, nV, nE1, nE2;
Standard_Real aTR1, aTR2;
//
// get face's edges to check that E/E contains the edge from the face
BOPCol_MapOfInteger aMFE;
const BOPCol_ListOfInteger& aLI = myDS->ShapeInfo(theF).SubShapes();
BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
for (; aItLI.More(); aItLI.Next()) {
nE1 = aItLI.Value();
if (myDS->ShapeInfo(nE1).ShapeType() == TopAbs_EDGE) {
aMFE.Add(nE1);
}
}
//
for (i = 0; i < aNbEEs; ++i) {
BOPDS_InterfEE& aEE = aEEs(i);
if (!aEE.HasIndexNew()) {
continue;
}
//
// check the vertex
nV = aEE.IndexNew();
if (nV != theV1 && nV != theV2) {
continue;
}
//
// check that the intersection is between the edge
// and one of the face's edge
aEE.Indices(nE1, nE2);
if (((theE != nE1) && (theE != nE2)) ||
(!aMFE.Contains(nE1) && !aMFE.Contains(nE2))) {
continue;
}
//
// update the intersection range
const IntTools_CommonPrt& aCPart = aEE.CommonPart();
const IntTools_Range& aCRange =
(theE == nE1) ? aCPart.Range1() : aCPart.Ranges2().First();
aCRange.Range(aTR1, aTR2);
//
if (nV == theV1) {
if (theTS1 < aTR2) {
theTS1 = aTR2;
}
}
else {
if (theTS2 > aTR1) {
theTS2 = aTR1;
}
}
}
}

View File

@@ -382,7 +382,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
BOPCol_MapOfInteger aMVOnIn(100, aAllocator), aMF(100, aAllocator),
aMVStick(100,aAllocator), aMVEF(100, aAllocator),
aMI(100, aAllocator);
aMI(100, aAllocator), aMVBounds(100, aAllocator);
BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator);
BOPDS_ListOfPaveBlock aLPB(aAllocator);
@@ -393,6 +393,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
BOPCol_DataMapOfIntegerInteger aDMI(100, aAllocator);
BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
//
for (i=0; i<aNbFF; ++i) {
//
@@ -479,6 +480,10 @@ void BOPAlgo_PaveFiller::MakeBlocks()
//
if (!aLBV.IsEmpty()) {
aDMBV.Bind(j, aLBV);
BOPCol_ListIteratorOfListOfInteger aItI(aLBV);
for (; aItI.More(); aItI.Next()) {
aMVBounds.Add(aItI.Value());
}
}
}
}//for (j=0; j<aNbC; ++j) {
@@ -521,6 +526,27 @@ void BOPAlgo_PaveFiller::MakeBlocks()
continue;
}
//
const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
//
// Make Edge
BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
//
// check for micro edge
if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
// If the section edge is a micro edge, i.e. the whole edge is
// covered by the tolerance spheres of its vertices, it will be
// passed into post treatment process to fuse its vertices.
// The edge itself will not be kept.
if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
aMicroEdges.Add(aES);
// keep vertices for post treatment
aMVI.Bind(aV1, nV1);
aMVI.Bind(aV2, nV2);
}
continue;
}
//
Standard_Real aTolNew;
bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBOut, aTolNew);
if (bExist) {
@@ -553,20 +579,11 @@ void BOPAlgo_PaveFiller::MakeBlocks()
continue;
}
//
// Make Edge
const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
//
BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1,
aV2, aT2, aTolR3D, aES);
// Make p-curves
BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
mySectionAttribute.PCurveOnS1(),
mySectionAttribute.PCurveOnS2());
//
if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext)) {
continue;
}
//
// Append the Pave Block to the Curve j
aLPBC.Append(aPB);
//
@@ -602,7 +619,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
}//for (i=0; i<aNbFF; ++i) {
//
// post treatment
myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMI, aAllocator);
myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMI, aMicroEdges, aAllocator);
if (myErrorStatus) {
return;
}
@@ -632,6 +649,7 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
BOPCol_DataMapOfShapeInteger& aMVI,
BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
BOPCol_DataMapOfIntegerInteger& aDMI,
const BOPCol_IndexedMapOfShape& theMicroEdges,
const Handle(NCollection_BaseAllocator)& theAllocator)
{
Standard_Integer iRet, aNbS;
@@ -661,11 +679,11 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
//
BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
//
Standard_Integer aNbME = theMicroEdges.Extent();
// 0
if (aNbS==1) {
if (aNbS==1 && (aNbME == 0)) {
const TopoDS_Shape& aS=theMSCPB.FindKey(1);
const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
//
aType=aS.ShapeType();
if (aType==TopAbs_VERTEX) {
@@ -704,6 +722,37 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
aLS.Append(aS);
}
//
// The section edges considered as a micro should be
// specially treated - their vertices should be united and
// the edge itself should be removed. Thus, we add only
// its vertices into operation.
//
BRep_Builder aBB;
for (k = 1; k <= aNbME; ++k) {
const TopoDS_Edge& aE = TopoDS::Edge(theMicroEdges(k));
//
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aE, aV1, aV2);
//
aLS.Append(aV1);
aLS.Append(aV2);
//
// make sure these vertices will be united
const gp_Pnt& aP1 = BRep_Tool::Pnt(aV1);
const gp_Pnt& aP2 = BRep_Tool::Pnt(aV2);
//
Standard_Real aDist = aP1.Distance(aP2);
Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1);
Standard_Real aTolV2 = BRep_Tool::Tolerance(aV2);
//
aDist -= (aTolV1 + aTolV2);
if (aDist > 0.) {
aDist /= 2.;
aBB.UpdateVertex(aV1, aTolV1 + aDist);
aBB.UpdateVertex(aV2, aTolV2 + aDist);
}
}
//
// 2 Fuse shapes
aPF.SetProgressIndicator(myProgressIndicator);
aPF.SetRunParallel(myRunParallel);
@@ -724,6 +773,8 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
aType=aSIx.ShapeType();
//
if (aType==TopAbs_VERTEX) {
Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
//
if (aPDS->HasShapeSD(nSx, nVSD)) {
aV=aPDS->Shape(nVSD);
}
@@ -741,14 +792,23 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
else {
iV=aMVI.Find(aV);
}
//
if (!bIntersectionPoint) {
// save SD connection
nSx = aMVI.Find(aSx);
aDMI.Bind(nSx, iV);
myDS->AddShapeSD(nSx, iV);
}
else {
// update FF interference
const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
iX=aCPB.IndexInterf();
iP=aCPB.Index();
BOPDS_InterfFF& aFF=aFFs(iX);
BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
BOPDS_Point& aNP=aVNP(iP);
aNP.SetIndex(iV);
const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
iX=aCPB.IndexInterf();
iP=aCPB.Index();
BOPDS_InterfFF& aFF=aFFs(iX);
BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
BOPDS_Point& aNP=aVNP(iP);
aNP.SetIndex(iV);
}
}//if (aType==TopAbs_VERTEX) {
//
else if (aType==TopAbs_EDGE) {
@@ -1935,28 +1995,16 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
const Standard_Integer nF1,
const Standard_Integer nF2)
{
if (!aLPB.Extent()) {
return;
}
//
Standard_Integer nE;
Standard_Boolean bCB;
Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
Handle(BOPDS_CommonBlock) aCB;
BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
//
// 1. Remove micro edges from aLPB
aIt.Initialize(aLPB);
for (; aIt.More();) {
aPB = aIt.Value();
const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
if (BOPTools_AlgoTools::IsMicroEdge(aE, myContext)) {
aLPB.Remove(aIt);
continue;
}
aIt.Next();
}
//
if (!aLPB.Extent()) {
return;
}
//
BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
//
@@ -1965,7 +2013,7 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
//
// 2. Remove old pave blocks
// 1. Remove old pave blocks
const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
bCB = !aCB1.IsNull();
BOPDS_ListOfPaveBlock aLPB1;
@@ -1991,7 +2039,7 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
}
}
//
// 3. Update pave blocks
// 2. Update pave blocks
if (bCB) {
//create new common blocks
BOPDS_ListOfPaveBlock aLPBNew;
@@ -2043,7 +2091,7 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
return;
}
//
// 4. Check new pave blocks for coincidence
// 3. Check new pave blocks for coincidence
// with the opposite face.
// In case of coincidence create common blocks
Standard_Integer nF;
@@ -2541,21 +2589,22 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
// 1. iterate on all sections F-F
Standard_Integer aNb = aFFs.Extent(), i;
for (i = 0; i < aNb; ++i) {
const BOPDS_InterfFF& aFF = aFFs(i);
BOPDS_InterfFF& aFF = aFFs(i);
Standard_Real aTolR3D = aFF.TolR3D();
Standard_Real aTolReal = aFF.TolReal();
Standard_Boolean bToReduce = aTolReal < aTolR3D;
// tolerance of intersection has been increased, so process this intersection
const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
Standard_Integer aNbC = aVNC.Extent(), k;
for (k = 0; k < aNbC; ++k) {
const BOPDS_Curve& aNC = aVNC(k);
const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
BOPDS_Curve& aNC = aVNC(k);
BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
for (; aItLPB.More(); aItLPB.Next()) {
for (; aItLPB.More(); ) {
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
Standard_Integer nE;
if (!aPB->HasEdge(nE)) {
aLPB.Remove(aItLPB);
continue;
}
//
@@ -2582,6 +2631,7 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
aMVIToReduce.Add(nV);
}
}
aItLPB.Next();
}
}
}

View File

@@ -280,6 +280,9 @@ void BOPAlgo_PaveFiller::ProcessDE()
for (; aItLPB.More(); aItLPB.Next()) {
const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
nE=aPB->Edge();
if (nE < 0) {
continue;
}
const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
if (aC2D.IsNull()) {

View File

@@ -40,8 +40,7 @@
class BOPAlgo_ShrunkRange : public IntTools_ShrunkRange {
public:
BOPAlgo_ShrunkRange()
: IntTools_ShrunkRange(),
myWarningStatus(0) {
: IntTools_ShrunkRange() {
}
//
virtual ~BOPAlgo_ShrunkRange() {
@@ -56,21 +55,10 @@ class BOPAlgo_ShrunkRange : public IntTools_ShrunkRange {
}
//
virtual void Perform() {
//
myWarningStatus=0;
//
IntTools_ShrunkRange::Perform();
if (myErrorStatus) {
myWarningStatus=1;
}
}
//
Standard_Integer WarningStatus() const {
return myWarningStatus;
}
//
protected:
Standard_Integer myWarningStatus;
Handle(BOPDS_PaveBlock) myPB;
};
//
@@ -108,7 +96,7 @@ void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
}
//
Standard_Boolean bJustAdd;
Standard_Integer i, nS[2], nE, nV1, nV2, aNbVSD, k, iWrn;
Standard_Integer i, nS[2], nE, nV1, nV2, aNbVSD, k;
Standard_Real aT1, aT2, aTS1, aTS2;
BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
BOPCol_MapOfInteger aMI;
@@ -167,15 +155,15 @@ void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
//
for (k=0; k < aNbVSD; ++k) {
BOPAlgo_ShrunkRange& aSD=aVSD(k);
iWrn=aSD.WarningStatus();
if (iWrn==1) {
if (!aSD.IsDone()) {
continue;
}
//
Handle(BOPDS_PaveBlock)& aPB=aSD.PaveBlock();
aSD.ShrunkRange(aTS1, aTS2);
const Bnd_Box& aBox=aSD.BndBox();
Standard_Boolean bIsSplittable = aSD.IsSplittable();
//
aPB->SetShrunkData(aTS1, aTS2, aBox);
aPB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
}
}