#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>
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;
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();
//! 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);
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;
}
//
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;
}
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;
#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>
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;
//-----------------------------------------------------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);
}
//
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);
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);
//
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) ||
}//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);
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),
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;
//=======================================================================
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;
//
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
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;
+}
#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>
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];
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;
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;
}
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);
//
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();
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;
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);
//
break;
}
}
+ //
+ if (!bIsPBSplittable) {
+ continue;
+ }
+ //
for (j=0; j<2; ++j) {
if (bIsOnPave[j]) {
bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
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);
}
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;
+ }
+ }
+ }
+}
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);
BOPCol_DataMapOfIntegerInteger aDMI(100, aAllocator);
BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
+ BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
//
for (i=0; i<aNbFF; ++i) {
//
//
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) {
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) {
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);
//
}//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;
}
BOPCol_DataMapOfShapeInteger& aMVI,
BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
BOPCol_DataMapOfIntegerInteger& aDMI,
+ const BOPCol_IndexedMapOfShape& theMicroEdges,
const Handle(NCollection_BaseAllocator)& theAllocator)
{
Standard_Integer iRet, aNbS;
//
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) {
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);
aType=aSIx.ShapeType();
//
if (aType==TopAbs_VERTEX) {
+ Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
+ //
if (aPDS->HasShapeSD(nSx, nVSD)) {
aV=aPDS->Shape(nVSD);
}
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) {
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);
//
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;
}
}
//
- // 3. Update pave blocks
+ // 2. Update pave blocks
if (bCB) {
//create new common blocks
BOPDS_ListOfPaveBlock aLPBNew;
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;
// 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;
}
//
aMVIToReduce.Add(nV);
}
}
+ aItLPB.Next();
}
}
}
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()) {
class BOPAlgo_ShrunkRange : public IntTools_ShrunkRange {
public:
BOPAlgo_ShrunkRange()
- : IntTools_ShrunkRange(),
- myWarningStatus(0) {
+ : IntTools_ShrunkRange() {
}
//
virtual ~BOPAlgo_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;
};
//
}
//
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;
//
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);
}
}
myOriginalEdge=-1;
myTS1=-99.;
myTS2=myTS1;
+ myIsSplittable=Standard_False;
}
//=======================================================================
//function :
myOriginalEdge=-1;
myTS1=-99.;
myTS2=myTS1;
+ myIsSplittable=Standard_False;
}
//=======================================================================
//=======================================================================
void BOPDS_PaveBlock::SetShrunkData(const Standard_Real theT1,
const Standard_Real theT2,
- const Bnd_Box& theBox)
+ const Bnd_Box& theBox,
+ const Standard_Boolean theIsSplittable)
{
myTS1=theT1;
myTS2=theT2;
myShrunkBox=theBox;
+ myIsSplittable=theIsSplittable;
}
//=======================================================================
//function : ShrunkData
//=======================================================================
void BOPDS_PaveBlock::ShrunkData(Standard_Real& theT1,
Standard_Real& theT2,
- Bnd_Box& theBox)const
+ Bnd_Box& theBox,
+ Standard_Boolean& theIsSplittable) const
{
theT1=myTS1;
theT2=myTS2;
theBox=myShrunkBox;
+ theIsSplittable=myIsSplittable;
}
//=======================================================================
//function : Dump
//! Sets the shrunk data for the pave block
//! <theTS1>, <theTS2> - shrunk range
//! <theBox> - the bounding box
+ //! <theIsSplittable> - defines whether the edge can be split
Standard_EXPORT void SetShrunkData (const Standard_Real theTS1,
const Standard_Real theTS2,
- const Bnd_Box& theBox);
+ const Bnd_Box& theBox,
+ const Standard_Boolean theIsSplittable);
//! Selector
//! Returns the shrunk data for the pave block
//! <theTS1>, <theTS2> - shrunk range
//! <theBox> - the bounding box
+ //! <theIsSplittable> - defines whether the edge can be split
Standard_EXPORT void ShrunkData (Standard_Real& theTS1,
Standard_Real& theTS2,
- Bnd_Box& theBox) const;
+ Bnd_Box& theBox,
+ Standard_Boolean& theIsSplittable) const;
//! Query
Standard_EXPORT void Dump() const;
+ //! Query
+ //! Returns FALSE if the pave block has a too short
+ //! shrunk range and cannot be split, otherwise returns TRUE
+ Standard_Boolean IsSplittable() const
+ {
+ return myIsSplittable;
+ }
Standard_Real myTS2;
Bnd_Box myShrunkBox;
BOPCol_MapOfInteger myMFence;
-
+ Standard_Boolean myIsSplittable;
private:
//=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
(const TopoDS_Edge& aE,
- const Handle(IntTools_Context)& aCtx)
+ const Handle(IntTools_Context)& aCtx,
+ const Standard_Boolean bCheckSplittable)
{
Standard_Boolean bRet;
- Standard_Integer iErr;
Standard_Real aT1, aT2, aTmp;
Handle(Geom_Curve) aC3D;
TopoDS_Vertex aV1, aV2;
aSR.SetContext(aCtx);
aSR.SetData(aE, aT1, aT2, aV1, aV2);
aSR.Perform();
- iErr=aSR.ErrorStatus();
- bRet = !(iErr==0);
+ bRet = !aSR.IsDone();
+ if (!bRet && bCheckSplittable) {
+ bRet = !aSR.IsSplittable();
+ }
//
return bRet;
}
Standard_EXPORT static Standard_Boolean IsBlockInOnFace (const IntTools_Range& aShR, const TopoDS_Face& aF, const TopoDS_Edge& aE, Handle(IntTools_Context)& aContext);
- //! Checks if it is possible to compute shrunk range for the edge <aE>.
- Standard_EXPORT static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge, const Handle(IntTools_Context)& theContext);
+ //! Checks if it is possible to compute shrunk range for the edge <aE>
+ //! Flag <theCheckSplittable> defines whether to take into account
+ //! the possiblity to split the edge or not.
+ Standard_EXPORT static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge,
+ const Handle(IntTools_Context)& theContext,
+ const Standard_Boolean theCheckSplittable = Standard_True);
//! Corrects tolerance values of the sub-shapes of the shape <theS> if needed.
#include <BndLib_Add3dCurve.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-#include <ElCLib.hxx>
-#include <Geom_Curve.hxx>
-#include <gp.hxx>
-#include <gp_Circ.hxx>
-#include <gp_Lin.hxx>
-#include <IntTools_Context.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
#include <IntTools_ShrunkRange.hxx>
#include <Precision.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Vertex.hxx>
//=======================================================================
//function :
myT2=myT1;
myTS1=myT1;
myTS2=myT1;
- myErrorStatus=1;
+ myIsDone=Standard_False;
+ myIsSplittable=Standard_False;
}
//=======================================================================
//function : ~
myV2=aV2;
myT1=aT1;
myT2=aT2;
- myErrorStatus=1;
+ myIsDone=Standard_False;
+ myIsSplittable=Standard_False;
}
//=======================================================================
//function : SetContext
{
return myBndBox;
}
-//=======================================================================
-//function : ErrorStatus
-//purpose :
-//=======================================================================
-Standard_Integer IntTools_ShrunkRange::ErrorStatus() const
-{
- return myErrorStatus;
-}
-
//=======================================================================
//function : SetShrunkRange
//purpose :
myTS2=aT2;
//
BRepAdaptor_Curve aBAC(myEdge);
- BndLib_Add3dCurve::Add (aBAC, aT1, aT2, 0., myBndBox);
+ BndLib_Add3dCurve::Add(aBAC, aT1, aT2, 0., myBndBox);
}
//=======================================================================
//=======================================================================
void IntTools_ShrunkRange::Perform()
{
- Standard_Real aCF, aCL, aTolE, aTolV1;
- Standard_Real aTolV2, t1, t11, t1C, t2, t12, t2C, dummy;
- Standard_Real aCoeff1, aCoeff2, aTol1, aTol2, dt1, dt2, aR, anEps;
- Standard_Integer pri;
- Standard_Boolean bInf1, bInf2, bAppr;
- GeomAbs_CurveType aCurveType;
- Handle(Geom_Curve) aC;
+ myIsDone = Standard_False;
+ myIsSplittable = Standard_False;
+ //
+ // default tolerance - Precision::Confusion()
+ Standard_Real aDTol = Precision::Confusion();
+ // default parametric tolerance - Precision::PConfusion()
+ Standard_Real aPDTol = Precision::PConfusion();
+ //
+ if (myT2 - myT1 < aPDTol) {
+ return;
+ }
//
- myErrorStatus=0;
- myTS1=-99;
- myTS2=myTS1;
- anEps = 1.e-8;
+ Standard_Real aTolE, aTolV1, aTolV2;
+ aTolE = BRep_Tool::Tolerance(myEdge);
+ aTolV1 = BRep_Tool::Tolerance(myV1);
+ aTolV2 = BRep_Tool::Tolerance(myV2);
//
- aTolE =BRep_Tool::Tolerance(myEdge);
- aTolV1=BRep_Tool::Tolerance(myV1);
- aTolV2=BRep_Tool::Tolerance(myV2);
- //for edges with the tolerance value
- //more than the tolerance value of vertices
if (aTolV1 < aTolE) {
aTolV1 = aTolE;
}
aTolV2 = aTolE;
}
//
- t1=myT1;
- t2=myT2;
+ // to have correspondence with intersection precision
+ // the tolerances of vertices are increased on Precision::Confusion()
+ aTolV1 += aDTol;
+ aTolV2 += aDTol;
//
BRepAdaptor_Curve aBAC(myEdge);
- aCurveType=aBAC.GetType();
- //
- aC=BRep_Tool::Curve(myEdge, aCF, aCL);
- BRep_Tool::Range(myEdge, aCF, aCL);
- //
- if (t1 < aCF || t2 > aCL) {
- myErrorStatus=2;
- return;
+ // parametric tolerance for the edge
+ // to be used in AbscissaPoint computations
+ Standard_Real aPTolE = aBAC.Resolution(aTolE);
+ // for the edges with big tolerance use
+ // min parametric tolerance - 1% of its range
+ Standard_Real aPTolEMin = (myT2 - myT1) / 100.;
+ if (aPTolE > aPTolEMin) {
+ aPTolE = aPTolEMin;
}
//
- bAppr = !(fabs(t2 - t1) > 100);
- if (fabs(t2 - t1) < anEps) {
- myErrorStatus=7;
+ // compute the shrunk range - part of the edge not covered
+ // by the tolerance spheres of its vertices
+ GCPnts_AbscissaPoint aPC1(aBAC, aTolV1, myT1, aPTolE);
+ // if Abscissa is unable to compute the parameter
+ // use the resolution of the curve
+ myTS1 = aPC1.IsDone() ? aPC1.Parameter() : (myT1 + aBAC.Resolution(aTolV1));
+ if (myT2 - myTS1 < aPDTol) {
+ // micro edge
return;
}
//
- if (t1 > t2) {
- myErrorStatus=3;
+ GCPnts_AbscissaPoint aPC2(aBAC, -aTolV2, myT2, aPTolE);
+ myTS2 = aPC2.IsDone() ? aPC2.Parameter() : (myT2 - aBAC.Resolution(aTolV2));
+ if (myTS2 - myT1 < aPDTol) {
+ // micro edge
return;
}
//
- aTol1 = Max(aTolV1, aTolE);
- aTol2 = Max(aTolV2, aTolE);
- //
- aCoeff1 = (aTolE>0.05) ? 1. : 2.;
- aCoeff2 = aCoeff1;
- if (aCoeff1 == 2.) {
- aCoeff1=(aTol1>0.05) ? 1.5 : 2.;
- aCoeff2=(aTol2>0.05) ? 1.5 : 2.;
- }
- // xf
- if (aCurveType==GeomAbs_Line && (aCoeff1 != 1 || aCoeff2 != 1)) {
- Standard_Real aTV1, aTV2, aEps;
- gp_Pnt aPV1, aPV2, aPC1, aPC2;
- gp_Lin aL;
- //
- aEps=Precision::Confusion();
- aEps=aEps*aEps;//1.e-14;
- aL=aBAC.Line();
- //
- aPV1=BRep_Tool::Pnt(myV1);
- aTV1=ElCLib::Parameter(aL, aPV1);
- //
- aPV2=BRep_Tool::Pnt(myV2);
- aTV2=ElCLib::Parameter(aL, aPV2);
- //
- if (fabs(aTV1-aCF)<aEps) {
- aCoeff1=1.;
- aTol1 += Precision::Confusion();
- }
- if (fabs(aTV2-aCL)<aEps) {
- aCoeff2=1.;
- aTol2 += Precision::Confusion();
- }
- }
- //
- dt1=aCoeff1*aTol1;
- dt2=aCoeff2*aTol2;
- // xt
- //
- if (aCurveType==GeomAbs_Line) {
- Standard_Real dt1x, dt2x;
-
- dt1x = aBAC.Resolution(dt1);
- t11=t1+dt1x;
-
- dt2x = aBAC.Resolution(dt2);
- t12=t2-dt2x;
-
- if (t11>t2 || t12<t1) {
- t1C=t1;
- t2C=t2;
- myTS1=t1C;
- myTS2=t2C;
- //
- // BndBox
- Standard_Real ddx=aTolE;//1.e-12;
- BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
-
- myErrorStatus=6;//0
- return;
- }
+ if ((myTS2 - myTS1) < aPDTol) {
+ // micro edge
+ return;
}
//
- if (aCurveType==GeomAbs_Circle) {
- gp_Circ aCrc=aBAC.Circle();
- aR=aCrc.Radius();
- t1C=t1+dt1/aR;
- t2C=t2-dt2/aR;
+ // compute the length of the edge on the shrunk range
+ Standard_Real anEdgeLength =
+ GCPnts_AbscissaPoint::Length(aBAC, myTS1, myTS2, aPTolE);
+ if (anEdgeLength < aDTol) {
+ // micro edge
+ return;
}
- else {
- //
- // Vertex1 => t1C
- gp_Pnt aP1,aP11;
- aC->D0 (t1, aP1);
- //
- bInf1=Precision::IsNegativeInfinite(t1);
- if (bInf1) {
- t1C=t1;
- }
- //
- else {
- Standard_Real d1 = aCoeff1*aTol1;
- // dt1 = aBAC.Resolution(d1);
- //
- gp_Vec aD1vec1;
- gp_Pnt aPoint;
- aBAC.D1(t1, aPoint, aD1vec1);
- Standard_Real ad1length1 = aD1vec1.Magnitude();
- Standard_Boolean bTryOtherPoints = Standard_False;
- dt1 = (t2 - t1) * 0.5;
-
- if(ad1length1 > 1.e-12) {
- dt1 = d1 / ad1length1;
-
- if(dt1 > (t2 - t1)) {
- // bad parametrization, big tolerance or too small range
- bTryOtherPoints = Standard_True;
- }
- }
- else {
- bTryOtherPoints = Standard_True;
- }
-
- if(bTryOtherPoints) {
- Standard_Integer nbsamples = 5;
- Standard_Integer ii = 0;
- Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
- Standard_Boolean bFound = Standard_False;
-
- for(ii = 1; ii <= nbsamples; ii++) {
- Standard_Real aparameter = t1 + (adelta * ii);
- gp_Pnt aPoint2;
- aBAC.D1(aparameter, aPoint2, aD1vec1);
-
- if(aPoint.Distance(aPoint2) < d1)
- dt1 = adelta * ii;
- ad1length1 = aD1vec1.Magnitude();
-
- if(ad1length1 > 1.e-12) {
- dt1 = d1 / ad1length1;
-
- if(dt1 < (t2 - t1)) {
- bFound = Standard_True;
- break;
- }
- }
- }
-
- if(!bFound) {
- if(dt1 > (t2 - t1)) {
- dt1 = aBAC.Resolution(d1);
- if (dt1 > (t2 - t1)) {
- myErrorStatus = 7;
- return;
- }
- }
- }
- }
- //
- if (!bAppr) {
- dt1 *= 10;
- }
- t11=t1+dt1;
- aC->D0 (t11, aP11);
-
- gp_Vec aV11(aP1, aP11);
- // avoid exception if aP1 == aP11
- if (aV11.SquareMagnitude() < gp::Resolution())
- t1C = t1;
- else {
- gp_Dir aD11(aV11);
-
- gp_Pnt aP1L;
- //
- aP1L.SetCoord (aP1.X()+d1*aD11.X(),
- aP1.Y()+d1*aD11.Y(),
- aP1.Z()+d1*aD11.Z());
-
- BRepBuilderAPI_MakeVertex aMV1(aP1L);
- const TopoDS_Vertex& aV1L=aMV1.Vertex();
- //
- pri = myCtx->ComputeVE(aV1L, myEdge, t1C, dummy);
- //
- if (pri==-3) {
- myErrorStatus=4;
- return;
- }
- }
- }
- //
- // Vertex2 => t2C
- gp_Pnt aP2, aP12;
- aC->D0 (t2, aP2);
- //
- bInf2=Precision::IsPositiveInfinite(t2);
- if (bInf2) {
- t2C=t2;
- }
- //
- else {
- Standard_Real d2 = aCoeff2*aTol2;
- // dt2 = aBAC.Resolution(d2);
-
- //
- gp_Vec aD1vec2;
- gp_Pnt aPoint;
- aBAC.D1(t2, aPoint, aD1vec2);
- Standard_Real ad1length2 = aD1vec2.Magnitude();
- Standard_Boolean bTryOtherPoints = Standard_False;
- dt2 = (t2 - t1) * 0.5;
-
- if(ad1length2 > 1.e-12) {
- dt2 = d2 / ad1length2;
-
- if(dt2 > (t2 - t1)) {
- bTryOtherPoints = Standard_True;
- }
- }
- else {
- bTryOtherPoints = Standard_True;
- }
-
- if(bTryOtherPoints) {
- Standard_Integer nbsamples = 5;
- Standard_Integer ii = 0;
- Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
- Standard_Boolean bFound = Standard_False;
-
- for(ii = 1; ii <= nbsamples; ii++) {
- Standard_Real aparameter = t2 - (adelta * ii);
- gp_Pnt aPoint2;
- aBAC.D1(aparameter, aPoint2, aD1vec2);
-
- if(aPoint.Distance(aPoint2) < d2)
- dt2 = adelta * ii;
- ad1length2 = aD1vec2.Magnitude();
-
- if(ad1length2 > 1.e-12) {
- dt2 = d2 / ad1length2;
-
- if(dt2 < (t2 - t1)) {
- bFound = Standard_True;
- break;
- }
- }
- }
-
- if(!bFound) {
- if(dt2 > (t2 - t1)) {
- dt2 = aBAC.Resolution(d2);
- if(dt2 > (t2 - t1)) {
- myErrorStatus = 7;
- return;
- }
- }
- }
- }
- //
- if (!bAppr) {
- dt2 *= 10;
- }
-
- t12=t2-dt2;
- aC->D0 (t12, aP12);
-
- gp_Vec aV12(aP2, aP12);
- // avoid exception if aP1 == aP11
- if (aV12.SquareMagnitude() < gp::Resolution())
- t2C = t2;
- else {
- gp_Dir aD12(aV12);
-
- gp_Pnt aP2L;
- //
- aP2L.SetCoord (aP2.X()+d2*aD12.X(),
- aP2.Y()+d2*aD12.Y(),
- aP2.Z()+d2*aD12.Z());
-
- BRepBuilderAPI_MakeVertex aMV2(aP2L);
- const TopoDS_Vertex& aV2L=aMV2.Vertex();
- //
- pri = myCtx->ComputeVE(aV2L, myEdge, t2C, dummy);
- //
- if (pri==-3) {
- myErrorStatus=5;
- return;
- }
- }
- }
- } // else {
//
- if (t1C>t2){
- t1C=0.5*(t2+t1);
- t2C=t1C+0.1*(t2-t1C);
- }
-
- if (t1C>t2C) {
- t2C=t1C+0.1*(t2-t1C);
- }
+ myIsDone = Standard_True;
//
- if (t2C-t1C < anEps) {
- myErrorStatus = 7;
- return;
+ // check the shrunk range to have the length not less than
+ // 2*aTolE+2*Precision::Confusion()
+ // for the edge to have possibility to be split at least once:
+ // 2*TolE - minimal diameter of tolerance sphere of splitting vertex
+ // 2*Precision::Confusion() - minimal length of the new edges
+ if (anEdgeLength > (2 * aTolE + 2 * aDTol)) {
+ myIsSplittable = Standard_True;
}
//
- myTS1=t1C;
- myTS2=t2C;
- //
- // BndBox
- Standard_Real ddx = aTolE + Precision::Confusion();
- BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
+ // build bounding box for the edge on the shrunk range
+ BndLib_Add3dCurve::Add(aBAC, myTS1, myTS2,
+ aTolE + aDTol, myBndBox);
}
-/////////////////////////////////////////////////////////////////////////
-//
-// myErrorStatus :
-//
-// 1- Nothing has been done
-// 2- The source range is out of the edge's range
-// 3- t1 < t2 for source range
-// 4- Can not project V1L to the Edge;
-// 5- Can not project V2L to the Edge;
-// 6- for obtained shrunk range [t11, t12] -> t11>t2 || t12<t1;
-// 7- too small range.
Standard_EXPORT void Perform();
-
- //! Returns code of computing shrunk range
- //! completion
- //! 0 - means successful completion
- //! 1 - nothing has been done
- //! 2 - initial range is out of edge's range
- //! 3 - first boundary of initial range is more than
- //! last boundary
- //! 4 - projection of first vertex failed
- //! 5 - projection of second vertex failed
- //! 6 - shrunk range can not be computed
- //! shrunk range is setted to initial range
- Standard_EXPORT Standard_Integer ErrorStatus() const;
-
-
-
+ //! Returns TRUE in case the shrunk range is computed
+ Standard_Boolean IsDone() const
+ {
+ return myIsDone;
+ }
+
+ //! Returns FALSE in case the shrunk range is
+ //! too short and the edge cannot be split,
+ //! otherwise returns TRUE
+ Standard_Boolean IsSplittable() const
+ {
+ return myIsSplittable;
+ }
protected:
-
-
TopoDS_Edge myEdge;
TopoDS_Vertex myV1;
TopoDS_Vertex myV2;
Standard_Real myTS2;
Bnd_Box myBndBox;
Handle(IntTools_Context) myCtx;
- Standard_Integer myErrorStatus;
-
+ Standard_Boolean myIsDone;
+ Standard_Boolean myIsSplittable;
private:
-
-
-
-
};
-
-
-
-
-
-
#endif // _IntTools_ShrunkRange_HeaderFile
# Original bug : pro14260
# Date : 21 Sept 98
+puts "TODO OCC27697 ALL: Error : is WRONG because number of "
+
restore [locate_data_file CTO900_pro14260c.rle] c
restore [locate_data_file pro14260d.rle] d
bfuse result c d
checkprops result -s 46305.1
+checknbshapes result -solid 1 -shell 1 -face 35
checkview -display result -2d -otherwise { c d } -s -path ${imagedir}/${test_image}.png
\ No newline at end of file
checkprops result -l 5837.18
checkshape result
-checksection result
+
+set chsec [checksection result]
+puts $chsec
+if {![regexp {nb alone Vertices : 0} $chsec]} {
+ puts "Error: The section is not closed"
+}
+
checkview -display result -2d -path ${imagedir}/${test_image}.png
+
checkprops result -l 5837.18
checkshape result
-checksection result
+
+set chsec [checksection result]
+puts $chsec
+if {![regexp {nb alone Vertices : 0} $chsec]} {
+ puts "Error: The section is not closed"
+}
+
checkview -display result -2d -path ${imagedir}/${test_image}.png
buildsweep r -C -S
+checkprops r -s 314717
+checkprops r -v 3.12204e+006
+checknbshapes r -vertex 22 -edge 31 -wire 11 -face 11 -shell 1 -solid 1
+
top
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
bbop result 0
checkprops result -s 44.5496
+checknbshapes result -vertex 14 -edge 15 -wire 2 -face 2
checkview -display result -2d -path ${imagedir}/${test_image}.png
--- /dev/null
+puts "========"
+puts "0027448: BOPTools_AlgoTools::IsMicroEdge does not correspond to shape validity criteria"
+puts "========"
+puts ""
+
+restore [locate_data_file bug27448_e.brep] e
+set bcheck [bopargcheck e /FTVEIPCS]
+puts $bcheck
+if {[regexp {Faulties, that can not be treated by BOP} $bcheck]} {
+ puts "Error: bopargcheck failed"
+}
--- /dev/null
+puts "========"
+puts "0027448: BOPTools_AlgoTools::IsMicroEdge does not correspond to shape validity criteria"
+puts "Problem with Boolean CUT operation"
+puts "========"
+puts ""
+
+restore [locate_data_file bug27448_gdml_ZF6.brep] b
+explode b
+bcut result b_1 b_2
+checkshape result
+checknbshapes result -solid 1
+checkprops result -s 38.0808
+checkprops result -v 9.95429
--- /dev/null
+puts "========"
+puts "0027519: Inconsistent result of SECTION operation"
+puts "========"
+puts ""
+
+restore [locate_data_file bug27448_b1255.brep] b
+explode b
+bsection result b_1 b_2
+set chsec [checksection result]
+puts $chsec
+if {![regexp {nb alone Vertices : 2} $chsec]} {
+ puts "Error: the section is not closed"
+}
--- /dev/null
+puts "========"
+puts "0027519: Inconsistent result of SECTION operation"
+puts "========"
+puts ""
+
+restore [locate_data_file bug27448_b1255_2.brep] b
+plane p 0 -36.8067 0 0 1 0
+mkface f p
+bsection result b f
+set chsec [checksection result]
+puts $chsec
+if {![regexp {nb alone Vertices : 4} $chsec]} {
+ puts "Error: the section is not closed"
+}
+
+set chsi [bopcheck result]
+puts $chsi
+if {![regexp {This shape seems to be OK.} $chsi]} {
+ puts "Error: the section is self-interfered"
+}
puts "TODO OCC25406 ALL: Error : The volume of result shape is"
puts "TODO OCC25406 Windows: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
+puts "TODO OCC25406 Linux: Error: bsection of the result and s is not equal to zero"
ellipse w1 0 0 0 15 10
mkedge w1 w1 0 pi/2
puts "TODO OCC23068 ALL: Error : The volume of result shape is"
puts "TODO OCC23068 Windows: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero"
+puts "TODO OCC23068 Linux: Error: bsection of the result and s is not equal to zero"
ellipse w1 0 0 0 15 10
mkedge w1 w1 0 pi/2