1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00
occt/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
msv 0d0481c787 0026738: Make Boolean operations safely treating arguments when running with fuzzy option
When fuzzy option is in force prevent increasing tolerance of input shapes. Instead pass increased by fuzzy value the tolerances of sub-shapes everywhere where it is needed by intersection algorithms.

The following changes in API have been made:

- The methods SetFuzzyValue and FuzzyValue have been moved from the classes BOPAlgo_ArgumentAnalyzer, BOPAlgo_Builder, and BOPAlgo_PaveFiller to the base class BOPAlgo_Algo.
- The public method BOPDS_DS::VerticesOnIn has been renamed to SubShapesOnIn, and the new output parameter theCommonPB has been added.
- In BOPTools_AlgoTools, a new argument "theFuzzyValue" has been added in the methods ComputeVV and AreFacesSameDomain.
- In IntTools_Context, a new argument "theFuzzyValue" has been added in the methods ComputeVE and ComputeVF.
- The methods SetFuzzyValue and FuzzyValue have been added in the classes IntTools_EdgeEdge, IntTools_FaceFace.
- In the class IntTools_EdgeFace, the methods SetTolE, SetTolF, TolE, TolF have been removed, and the methods SetFuzzyValue, FuzzyValue have been added.
- The new argument "theTol" has been added in the method IntTools_WLineTool::DecompositionOfWLine.

Some improvements in algorithms have been made during fighting with regressions:

- Correct initialization of pave blocks for degenerated edges.
- In BOPAlgo_PaveFiller::MakeBlocks(), filter out paves on intersection curve that were put on the curve accidentally due to wide range of E-F intersection vertex.
- In the method IntTools_Tools::ComputeTolerance the margin added to the computed tolerance has been increased up to 0.001%.
- The method BOPAlgo_PaveFiller::PutPaveOnCurve has been corrected in order to use the original vertex tolerance instead of the value increased during putting it on other curves.
- The new method BOPDS_PaveBlock::RemoveExtPave has been added.
- The vertex tolerance computation in BOPTools_AlgoTools::CorrectCurveOnSurface has been improved, taking into account intersection segments between p-curves (to avoid regression on "bugs modalg_6 bug22794").
- Improve IsExistingPaveBlock to make more stable catching of coincidence of common block with section curve (against regression "bugs modalg_4 bug697_2" on Linux).

Test case for the bug has been added.

The following test cases have been updated as improvements:
boolean gdml_private ZH2 ZI7 ZJ7
boolean volumemaker C4

The test case bugs/modalg_4/pro19653 has been corrected to make it stable. See comment inside the script for details.

The test case bugs/modalg_6/bug25880 has been corrected to suppress wrong bfuse commands.

The test bugs/modalg_6/bug26954_3 has been corrected to compare the result with more precise reference value.

The "faulty" TODO in boolean/volumemaker/A8 has been made actual for Linux as well.

//Eliminate compilation error on Linux.
2016-11-08 16:42:44 +03:00

814 lines
25 KiB
C++

// Created by: Peter KURNEV
// Copyright (c) 2010-2014 OPEN CASCADE SAS
// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Precision.hxx>
#include <Bnd_Box.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_SectionAttribute.hxx>
#include <BOPAlgo_Tools.hxx>
#include <BOPCol_MapOfInteger.hxx>
#include <BOPCol_NCVector.hxx>
#include <BOPCol_Parallel.hxx>
#include <BOPCol_DataMapOfShapeReal.hxx>
#include <BOPDS_CommonBlock.hxx>
#include <BOPDS_CoupleOfPaveBlocks.hxx>
#include <BOPDS_Curve.hxx>
#include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
#include <BOPDS_DS.hxx>
#include <BOPDS_Interf.hxx>
#include <BOPDS_Iterator.hxx>
#include <BOPDS_MapOfPaveBlock.hxx>
#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>
#include <BRepBndLib.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <gp_Pnt.hxx>
#include <IntTools_CommonPrt.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_EdgeFace.hxx>
#include <IntTools_Range.hxx>
#include <IntTools_SequenceOfCommonPrts.hxx>
#include <IntTools_Tools.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
//=======================================================================
//class : BOPAlgo_EdgeFace
//purpose :
//=======================================================================
class BOPAlgo_EdgeFace :
public IntTools_EdgeFace,
public BOPAlgo_Algo {
public:
DEFINE_STANDARD_ALLOC
BOPAlgo_EdgeFace() :
IntTools_EdgeFace(),
BOPAlgo_Algo(),
myIE(-1), myIF(-1) {
};
//
virtual ~BOPAlgo_EdgeFace(){
};
//
void SetIndices(const Standard_Integer nE,
const Standard_Integer nF) {
myIE=nE;
myIF=nF;
}
//
void Indices(Standard_Integer& nE,
Standard_Integer& nF) {
nE=myIE;
nF=myIF;
}
//
void SetNewSR(const IntTools_Range& aR){
myNewSR=aR;
}
//
IntTools_Range& NewSR(){
return myNewSR;
}
//
void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
myPB=aPB;
}
//
Handle(BOPDS_PaveBlock)& PaveBlock() {
return myPB;
}
//
void SetFuzzyValue(const Standard_Real theFuzz) {
IntTools_EdgeFace::SetFuzzyValue(theFuzz);
}
//
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
IntTools_EdgeFace::Perform();
}
//
protected:
Standard_Integer myIE;
Standard_Integer myIF;
IntTools_Range myNewSR;
Handle(BOPDS_PaveBlock) myPB;
};
//
//=======================================================================
typedef BOPCol_NCVector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace;
//
typedef BOPCol_ContextFunctor
<BOPAlgo_EdgeFace,
BOPAlgo_VectorOfEdgeFace,
Handle(IntTools_Context),
IntTools_Context> BOPAlgo_EdgeFaceFunctor;
//
typedef BOPCol_ContextCnt
<BOPAlgo_EdgeFaceFunctor,
BOPAlgo_VectorOfEdgeFace,
Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
//
//=======================================================================
//function : PerformEF
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::PerformEF()
{
Standard_Integer iSize;
//
myErrorStatus=0;
//
FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
//
myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
iSize=myIterator->ExpectedLength();
if (!iSize) {
return;
}
//
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];
Standard_Integer aNbEdgeFace, k;
Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
Handle(NCollection_BaseAllocator) aAllocator;
TopAbs_ShapeEnum aType;
BOPDS_ListIteratorOfListOfPaveBlock aIt;
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
//-----------------------------------------------------scope f
//
aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
//
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;
//
BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
aEFs.SetIncrement(iSize);
//
for (; myIterator->More(); myIterator->Next()) {
myIterator->Value(nE, nF, bJustAdd);
if(bJustAdd) {
continue;
}
//
const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
if (aSIE.HasFlag()){//degenerated
continue;
}
//
const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box();
//
BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
//
const BOPCol_MapOfInteger& aMVIn=aFI.VerticesIn();
const BOPCol_MapOfInteger& aMVOn=aFI.VerticesOn();
//
aTolE=BRep_Tool::Tolerance(aE);
aTolF=BRep_Tool::Tolerance(aF);
//
BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
aIt.Initialize(aLPB);
for (; aIt.More(); aIt.Next()) {
Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
//
const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
if (aMPBF.Contains(aPBR)) {
continue;
}
//
Bnd_Box aBBE;
if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) {
continue;
}
//
if (aBBF.IsOut (aBBE)) {
continue;
}
//
aPBR->Indices(nV1, nV2);
bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1);
bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2);
bExpressCompute=bV1 && bV2;
//
BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Append1();
//
aEdgeFace.SetIndices(nE, nF);
aEdgeFace.SetPaveBlock(aPB);
//
aEdgeFace.SetEdge (aE);
aEdgeFace.SetFace (aF);
aEdgeFace.SetFuzzyValue(myFuzzyValue);
aEdgeFace.SetDiscretize (aDiscretize);
aEdgeFace.SetDeflection (aDeflection);
aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
//
IntTools_Range aSR(aTS1, aTS2);
IntTools_Range anewSR=aSR;
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
aEdgeFace.SetNewSR(anewSR);
//
IntTools_Range aPBRange(aT1, aT2);
aSR = aPBRange;
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
aEdgeFace.SetRange (aPBRange);
aEdgeFace.SetProgressIndicator(myProgressIndicator);
//
}//for (; aIt.More(); aIt.Next()) {
}//for (; myIterator->More(); myIterator->Next()) {
//
aNbEdgeFace=aVEdgeFace.Extent();
//=================================================================
BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
//=================================================================
//
for (k=0; k < aNbEdgeFace; ++k) {
BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
if (!aEdgeFace.IsDone()) {
continue;
}
//~~~
aEdgeFace.Indices(nE, nF);
//
const TopoDS_Edge& aE=aEdgeFace.Edge();
const TopoDS_Face& aF=aEdgeFace.Face();
//
aTolE=BRep_Tool::Tolerance(aE);
aTolF=BRep_Tool::Tolerance(aF);
const IntTools_Range& anewSR=aEdgeFace.NewSR();
Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
//
aPB->Range(aT1, aT2);
aPB->Indices(nV[0], nV[1]);
bIsPBSplittable = aPB->IsSplittable();
//
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 BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
//~~~
const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
aNbCPrts = aCPrts.Length();
//
Standard_Boolean bLinePlane = Standard_False;
if (aNbCPrts) {
BRepAdaptor_Curve aBAC(aE);
BRepAdaptor_Surface aBAS(aF, Standard_False);
//
bLinePlane = (aBAC.GetType() == GeomAbs_Line &&
aBAS.GetType() == GeomAbs_Plane);
}
for (i=1; i<=aNbCPrts; ++i) {
const IntTools_CommonPrt& aCPart=aCPrts(i);
aType=aCPart.Type();
switch (aType) {
case TopAbs_VERTEX: {
Standard_Boolean bIsOnPave[2];
Standard_Integer j;
Standard_Real aT, aTolToDecide;
TopoDS_Vertex aVnew;
//
IntTools_Tools::VertexParameter(aCPart, aT);
BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
//
const IntTools_Range& aR=aCPart.Range1();
aTolToDecide=5.e-8;
//
bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide);
bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide);
//
if ((bIsOnPave[0] && bIsOnPave[1]) ||
(bLinePlane && (bIsOnPave[0] || bIsOnPave[1]))) {
bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
if (bV[0] && bV[1]) {
IntTools_CommonPrt aCP = aCPart;
aCP.SetType(TopAbs_EDGE);
BOPDS_InterfEF& aEF=aEFs.Append1();
iX=aEFs.Extent()-1;
aEF.SetIndices(nE, nF);
aEF.SetCommonPart(aCP);
myDS->AddInterf(nE, nF);
//
aMIEFC.Add(nF);
//
BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
break;
}
}
//
if (!bIsPBSplittable) {
continue;
}
//
for (j=0; j<2; ++j) {
if (bIsOnPave[j]) {
bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
if (bV[j]) {
const TopoDS_Vertex& aV=
(*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
//
Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
//
const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
//
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);
}
}
}
//
if (!bIsOnPave[0] && !bIsOnPave[1]) {
if (CheckFacePaves(aVnew, aMIFOn)) {
continue;
}
//
Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
BRep_Builder().UpdateVertex(aVnew, aTolVnew);
if (bLinePlane) {
// increase tolerance for Line/Plane intersection, but do not update
// the vertex till its intersection with some other shape
IntTools_Range aCR = aCPart.Range1();
aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
}
//
const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
//
if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
continue;
}
//
aMIEFC.Add(nF);
// 1
BOPDS_InterfEF& aEF=aEFs.Append1();
iX=aEFs.Extent()-1;
aEF.SetIndices(nE, nF);
aEF.SetCommonPart(aCPart);
// 2
myDS->AddInterf(nE, nF);
// 3
BOPDS_CoupleOfPaveBlocks aCPB;
//
aCPB.SetPaveBlocks(aPB, aPB);
aCPB.SetIndexInterf(iX);
aCPB.SetTolerance(aTolVnew);
aMVCPB.Add(aVnew, aCPB);
}
}
break;
case TopAbs_EDGE: {
aMIEFC.Add(nF);
//
// 1
BOPDS_InterfEF& aEF=aEFs.Append1();
iX=aEFs.Extent()-1;
aEF.SetIndices(nE, nF);
//
bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
if (!bV[0] || !bV[1]) {
myDS->AddInterf(nE, nF);
break;
}
aEF.SetCommonPart(aCPart);
// 2
myDS->AddInterf(nE, nF);
// 3
BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
}
break;
default:
break;
}//switch (aType) {
}//for (i=1; i<=aNbCPrts; ++i) {
}// for (k=0; k < aNbEdgeEdge; ++k) {
//
//=========================================
// post treatment
//=========================================
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
PerformVerticesEF(aMVCPB, aAllocator);
//
// Update FaceInfoIn for all faces having EF common parts
BOPCol_MapIteratorOfMapOfInteger aItMI;
aItMI.Initialize(aMIEFC);
for (; aItMI.More(); aItMI.Next()) {
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();
aMPBLI.Clear();
////aAllocator.Nullify();
}
//=======================================================================
//function : PerformVerticesEF
//purpose :
//=======================================================================
Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
(BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
const Handle(NCollection_BaseAllocator)& theAllocator)
{
Standard_Integer aNbV, iRet;
//
iRet=0;
aNbV=theMVCPB.Extent();
if (!aNbV) {
return iRet;
}
//
Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
Standard_Real aT, dummy;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPDS_PDS aPDS;
BOPDS_ShapeInfo aSI;
BOPDS_Pave aPave;
//
BOPCol_ListOfShape aLS(theAllocator);
BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
BOPAlgo_PaveFiller aPF(theAllocator);
BOPCol_DataMapOfShapeReal aMVIniTol;
//
aSI.SetShapeType(TopAbs_VERTEX);
BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
//
// 1 prepare arguments
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV = TopoDS::Vertex(theMVCPB.FindKey(i));
aLS.Append(aV);
// if an enlarged tolerance is associated with the vertex then update it
// remembering its initial tolerance
Standard_Real aTolEnlarged = theMVCPB.FindFromIndex(i).Tolerance();
Standard_Real aIniTol = BRep_Tool::Tolerance(aV);
if (aTolEnlarged > aIniTol) {
aMVIniTol.Bind(aV, aIniTol);
BRep_Builder().UpdateVertex(aV, aTolEnlarged);
}
}
//
// 2 Fuse vertices
aPF.SetIsPrimary(Standard_False);
aPF.SetNonDestructive(myNonDestructive);
aPF.SetArguments(aLS);
aPF.Perform();
iErr=aPF.ErrorStatus();
if (iErr) {
iRet=1;
return iRet;
}
aPDS=aPF.PDS();
//
// Recompute common vertex for each SD group containing enlarged vertex;
// for that first fill in the map of SD vertex -> its counterparts
BOPCol_IndexedDataMapOfShapeListOfShape aImages;
aItLS.Initialize(aLS);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aVx = aItLS.Value();
nVx = aPDS->Index(aVx);
//
const TopoDS_Shape& aV = (aPDS->HasShapeSD(nVx, nVSD) ? aPDS->Shape(nVSD) : aVx);
BOPCol_ListOfShape* pLst = aImages.ChangeSeek(aV);
if (!pLst) {
pLst = &aImages.ChangeFromIndex(aImages.Add(aV, BOPCol_ListOfShape()));
}
pLst->Append(aVx);
}
// 3 Add new vertices to theDS;
for (i = 1; i <= aImages.Extent(); i++) {
TopoDS_Vertex aV = TopoDS::Vertex(aImages.FindKey(i));
const BOPCol_ListOfShape& aLVSD = aImages.FindFromIndex(i);
Standard_Boolean isReset = Standard_False;
BOPCol_ListIteratorOfListOfShape it(aLVSD);
for (; it.More(); it.Next()) {
const TopoDS_Vertex& aVx = TopoDS::Vertex(it.Value());
const Standard_Real* pTolIni = aMVIniTol.Seek(aVx);
if (pTolIni) {
// reset enlarged vertex tolerance to the initial value
reinterpret_cast<BRep_TVertex*>(aVx.TShape().operator->())->Tolerance(*pTolIni);
isReset = Standard_True;
}
}
TopoDS_Vertex aVnew = aV;
if (isReset && aLVSD.Extent() > 1) {
// make new vertex again
BOPTools_AlgoTools::MakeVertex(aLVSD, aVnew);
}
// index of new vertex in theDS -> iV
aSI.SetShape(aVnew);
iV = myDS->Append(aSI);
//
BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV);
Bnd_Box& aBox = aSIDS.ChangeBox();
BRepBndLib::Add(aVnew, aBox);
aBox.SetGap(aBox.GetGap() + Precision::Confusion());
//
aMVI.Bind(aV, iV);
}
//
// 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
aItLS.Initialize(aLS);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aVx=aItLS.Value();
nVx=aPDS->Index(aVx);
//
const TopoDS_Shape& aV = (aPDS->HasShapeSD(nVx, nVSD) ? aPDS->Shape(nVSD) : aVx);
iV = aMVI.Find(aV);
//
BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
aCPB.SetIndex(iV);
// update EF interference
iX=aCPB.IndexInterf();
BOPDS_InterfEF& aEF=aEFs(iX);
aEF.SetIndexNew(iV);
// map aMPBLI
const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
if (aMPBLI.Contains(aPB)) {
BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
aLI.Append(iV);
}
else {
BOPCol_ListOfInteger aLI(theAllocator);
aLI.Append(iV);
aMPBLI.Add(aPB, aLI);
}
}
//
// 5
// 5.1 Compute Extra Paves and
// 5.2. Add Extra Paves to the PaveBlocks
aNbPBLI=aMPBLI.Extent();
for (i=1; i<=aNbPBLI; ++i) {
Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
nE=aPB->OriginalEdge();
const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
//
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
nVx=aItLI.Value();
const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
//
iFlag=myContext->ComputeVE (aVx, aE, aT, dummy, myFuzzyValue);
if (!iFlag) {
aPave.SetIndex(nVx);
aPave.SetParameter(aT);
aPB->AppendExtPave(aPave);
}
}
}
// 6 Split PaveBlocks
for (i=1; i<=aNbPBLI; ++i) {
Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
nE=aPB->OriginalEdge();
// 3
if (!myDS->IsCommonBlock(aPB)) {
myDS->UpdatePaveBlock(aPB);
}
else {
const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
myDS->UpdateCommonBlock(aCB, myFuzzyValue);
}
}//for (; aItMPBLI.More(); aItMPBLI.Next()) {
//
return iRet;
}
//=======================================================================
// function: CheckFacePaves
// purpose:
//=======================================================================
Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
(const Standard_Integer nVx,
const BOPCol_MapOfInteger& aMIFOn,
const BOPCol_MapOfInteger& aMIFIn)
{
Standard_Boolean bRet;
Standard_Integer nV;
BOPCol_MapIteratorOfMapOfInteger aIt;
//
bRet=Standard_False;
//
aIt.Initialize(aMIFOn);
for (; aIt.More(); aIt.Next()) {
nV=aIt.Value();
if (nV==nVx) {
bRet=!bRet;
return bRet;
}
}
aIt.Initialize(aMIFIn);
for (; aIt.More(); aIt.Next()) {
nV=aIt.Value();
if (nV==nVx) {
bRet=!bRet;
return bRet;
}
}
//
return bRet;
}
//=======================================================================
// function: CheckFacePaves
// purpose:
//=======================================================================
Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves
(const TopoDS_Vertex& aVnew,
const BOPCol_MapOfInteger& aMIF)
{
Standard_Boolean bRet;
Standard_Integer nV, iFlag;
BOPCol_MapIteratorOfMapOfInteger aIt;
//
bRet=Standard_True;
//
aIt.Initialize(aMIF);
for (; aIt.More(); aIt.Next()) {
nV=aIt.Value();
const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
if (!iFlag) {
return bRet;
}
}
//
return !bRet;
}
//=======================================================================
//function : ForceInterfVF
//purpose :
//=======================================================================
Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
(const Standard_Integer nV,
const Standard_Integer nF)
{
Standard_Boolean bRet;
Standard_Integer iFlag, nVx;
Standard_Real U, V, aTolVNew;
//
bRet = Standard_False;
const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
const TopoDS_Face& aF = *(TopoDS_Face*) &myDS->Shape(nF);
//
iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue);
if (iFlag == 0 || iFlag == -2) {
bRet=!bRet;
//
BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
aVFs.SetIncrement(10);
// 1
BOPDS_InterfVF& aVF=aVFs.Append1();
//
aVF.SetIndices(nV, nF);
aVF.SetUV(U, V);
// 2
myDS->AddInterf(nV, nF);
//
// 3 update vertex V/F if necessary
nVx=UpdateVertex(nV, aTolVNew);
// 4
if (myDS->IsNewShape(nVx)) {
aVF.SetIndexNew(nVx);
}
//
BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
aMVIn.Add(nVx);
}
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;
}
}
}
}