mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0031662: Modeling Algorithms - Incomplete result of section operation
BOPAlgo_PaveFiller: Add method for forced Edge/Face intersection to look for additional cases of coincidence.
This commit is contained in:
@@ -52,7 +52,8 @@ uses
|
||||
PaveBlock from BOPDS,
|
||||
CommonBlock from BOPDS,
|
||||
Curve from BOPDS,
|
||||
IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS,
|
||||
DataMapOfIntegerMapOfPaveBlock from BOPDS,
|
||||
IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS,
|
||||
MapOfPaveBlock from BOPDS,
|
||||
IndexedMapOfPaveBlock from BOPDS,
|
||||
ListOfPaveBlock from BOPDS,
|
||||
@@ -265,7 +266,8 @@ is
|
||||
thePB:PaveBlock from BOPDS;
|
||||
theNC:Curve from BOPDS;
|
||||
theTolR3D:Real from Standard;
|
||||
theMPB:IndexedMapOfPaveBlock from BOPDS;
|
||||
theMPB:IndexedMapOfPaveBlock from BOPDS;
|
||||
theMPBCommon:MapOfPaveBlock from BOPDS;
|
||||
thePBOut:out PaveBlock from BOPDS)
|
||||
returns Boolean from Standard
|
||||
is protected;
|
||||
@@ -576,6 +578,18 @@ is
|
||||
-- been put on other section edges with greater tolerance, which has caused
|
||||
-- increase of the tolerance value of the vertices.
|
||||
|
||||
ForceInterfEF(me:out)
|
||||
is protected;
|
||||
---Purpose: The method looks for the additional edge/face common blocks
|
||||
-- among pairs of edge/face having the same vertices.
|
||||
|
||||
ForceInterfEF(me:out;
|
||||
theMPB: IndexedMapOfPaveBlock from BOPDS;
|
||||
theAddInterf: Boolean from Standard)
|
||||
is protected;
|
||||
---Purpose: Performs intersection of given pave blocks
|
||||
-- with all faces from arguments.
|
||||
|
||||
|
||||
fields
|
||||
myArguments : ListOfShape from BOPCol is protected;
|
||||
@@ -585,5 +599,6 @@ fields
|
||||
mySectionAttribute : SectionAttribute from BOPAlgo is protected;
|
||||
myFuzzyValue : Real from Standard is protected;
|
||||
myNonDestructive : Boolean from Standard is protected;
|
||||
myIsPrimary : Boolean from Standard is protected;
|
||||
myIsPrimary : Boolean from Standard is protected;
|
||||
myFPBDone : DataMapOfIntegerMapOfPaveBlock from BOPDS is protected;
|
||||
end PaveFiller;
|
||||
|
@@ -50,7 +50,8 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
|
||||
(const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
:
|
||||
BOPAlgo_Algo(theAllocator),
|
||||
myFuzzyValue(0.)
|
||||
myFuzzyValue(0.),
|
||||
myFPBDone(1, theAllocator)
|
||||
{
|
||||
myDS=NULL;
|
||||
myIterator=NULL;
|
||||
@@ -296,6 +297,8 @@ void BOPAlgo_PaveFiller::PerformInternal()
|
||||
return;
|
||||
}
|
||||
UpdatePaveBlocksWithSDVertices();
|
||||
|
||||
ForceInterfEF();
|
||||
//
|
||||
// 22
|
||||
PerformFF();
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <IntTools_SequenceOfCommonPrts.hxx>
|
||||
#include <IntTools_CommonPrt.hxx>
|
||||
//
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_MapOfInteger.hxx>
|
||||
#include <BOPCol_NCVector.hxx>
|
||||
#include <BOPCol_Parallel.hxx>
|
||||
@@ -53,9 +54,16 @@
|
||||
#include <BOPDS_CoupleOfPaveBlocks.hxx>
|
||||
//
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BOPTools_AlgoTools2D.hxx>
|
||||
//
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_EdgeFace
|
||||
//purpose :
|
||||
@@ -236,7 +244,12 @@ void BOPAlgo_PaveFiller::PerformEF()
|
||||
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
|
||||
aEdgeFace.SetRange (aPBRange);
|
||||
aEdgeFace.SetProgressIndicator(myProgressIndicator);
|
||||
//
|
||||
|
||||
// Save the pair to avoid their forced intersection
|
||||
BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF);
|
||||
if (!pMPB)
|
||||
pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock());
|
||||
pMPB->Add(aPB);
|
||||
}//for (; aIt.More(); aIt.Next()) {
|
||||
}//for (; myIterator->More(); myIterator->Next()) {
|
||||
//
|
||||
@@ -658,3 +671,350 @@ Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEF
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEF()
|
||||
{
|
||||
if (!myIsPrimary)
|
||||
return;
|
||||
|
||||
// Now that we have vertices increased and unified, try to find additional
|
||||
// edge/face common blocks among the pairs of edge/face.
|
||||
// Here, we are interested in common blocks only, as all real intersections
|
||||
// should have happened already. Thus, we need to check only those pairs
|
||||
// of edge/face which have the same vertices.
|
||||
|
||||
// Collect all pave blocks
|
||||
BOPDS_IndexedMapOfPaveBlock aMPB;
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer nE = 0; nE < aNbS; ++nE)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE);
|
||||
if (aSI.ShapeType() != TopAbs_EDGE)
|
||||
// Not an edge
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Edge has no pave blocks
|
||||
continue;
|
||||
|
||||
if (aSI.HasFlag())
|
||||
// Degenerated edge
|
||||
continue;
|
||||
|
||||
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
|
||||
const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
|
||||
aMPB.Add(aPBR);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform intersection of collected pave blocks with faces
|
||||
ForceInterfEF(aMPB, Standard_True);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEF
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
|
||||
const Standard_Boolean theAddInterf)
|
||||
{
|
||||
if (theMPB.IsEmpty())
|
||||
return;
|
||||
|
||||
// Fill the tree with bounding boxes of the pave blocks
|
||||
NCollection_UBTree<Standard_Integer, Bnd_Box> aBBTree;
|
||||
NCollection_UBTreeFiller<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc);
|
||||
|
||||
Standard_Integer aNbPB = theMPB.Extent();
|
||||
for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
|
||||
{
|
||||
Handle(BOPDS_PaveBlock) aPB = theMPB(iPB);
|
||||
if (!aPB->HasShrunkData())
|
||||
{
|
||||
FillShrunkData(aPB);
|
||||
if (!aPB->HasShrunkData())
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Real f, l;
|
||||
Bnd_Box aPBBox;
|
||||
aPB->ShrunkData(f, l, aPBBox);
|
||||
|
||||
aTreeFiller.Add(aPBMap.Add(aPB), aPBBox);
|
||||
}
|
||||
|
||||
// Shake the tree
|
||||
aTreeFiller.Fill();
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Find pairs of Face/PaveBlock containing the same vertices
|
||||
// and prepare those pairs for intersection.
|
||||
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
|
||||
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer nF = 0; nF < aNbS; ++nF)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
|
||||
if (aSI.ShapeType() != TopAbs_FACE)
|
||||
// Not a face
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Face has no face info
|
||||
continue;
|
||||
|
||||
const Bnd_Box& aBoxF = aSI.Box();
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
aSelector.SetBox(aBoxF);
|
||||
|
||||
if (!aBBTree.Select(aSelector))
|
||||
continue;
|
||||
|
||||
const TopoDS_Face& aF = TopoDS::Face (aSI.Shape());
|
||||
const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF);
|
||||
// Vertices of the face
|
||||
BOPCol_MapOfInteger aMVF;
|
||||
const BOPCol_MapOfInteger* pMVF[] = { &aFI.VerticesOn(),
|
||||
&aFI.VerticesIn(),
|
||||
&aFI.VerticesSc() };
|
||||
for (Standard_Integer iM = 0; iM < 3; ++iM)
|
||||
{
|
||||
BOPCol_MapIteratorOfMapOfInteger itM(*pMVF[iM]);
|
||||
for (; itM.More(); itM.Next())
|
||||
aMVF.Add(itM.Value());
|
||||
}
|
||||
|
||||
// Pave Blocks of the face
|
||||
const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(),
|
||||
&aFI.PaveBlocksIn(),
|
||||
&aFI.PaveBlocksSc() };
|
||||
for (Standard_Integer iM = 0; iM < 3; ++iM)
|
||||
{
|
||||
const Standard_Integer aNb = pMPBF[iM]->Extent();
|
||||
for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB)
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB);
|
||||
aMVF.Add(aPB->Pave1().Index());
|
||||
aMVF.Add(aPB->Pave2().Index());
|
||||
}
|
||||
}
|
||||
|
||||
// Projection tool
|
||||
GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
|
||||
BRepAdaptor_Surface aSurfAdaptor (aF, Standard_False);
|
||||
|
||||
// Iterate on pave blocks and combine pairs containing
|
||||
// the same vertices
|
||||
const BOPCol_ListOfInteger& aLIPB = aSelector.Indices();
|
||||
BOPCol_ListOfInteger::Iterator itLIPB(aLIPB);
|
||||
for (; itLIPB.More(); itLIPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value());
|
||||
if (pMPBF[0]->Contains(aPB) ||
|
||||
pMPBF[1]->Contains(aPB) ||
|
||||
pMPBF[2]->Contains(aPB))
|
||||
continue;
|
||||
|
||||
// Check if the face contains both vertices of the pave block
|
||||
Standard_Integer nV1, nV2;
|
||||
aPB->Indices(nV1, nV2);
|
||||
if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2))
|
||||
// Face does not contain the vertices
|
||||
continue;
|
||||
|
||||
// Get the edge
|
||||
Standard_Integer nE;
|
||||
if (!aPB->HasEdge(nE))
|
||||
{
|
||||
nE = aPB->OriginalEdge();
|
||||
if (nE < 0)
|
||||
continue;
|
||||
|
||||
// Make sure that the edge and face came from different arguments
|
||||
if (myDS->Rank(nF) == myDS->Rank(nE))
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
|
||||
BRepAdaptor_Curve aBAC(aE);
|
||||
|
||||
// Check directions coincidence at middle point on the edge
|
||||
// and projection of that point on the face.
|
||||
// If the angle between tangent vector to the curve and normal
|
||||
// of the face is not in the range of 65 - 115 degrees, do not use the additional
|
||||
// tolerance, as it may lead to undesired unification of edge with the face.
|
||||
Standard_Boolean bUseAddTol = Standard_True;
|
||||
|
||||
Standard_Real aTS[2];
|
||||
Bnd_Box aPBBox;
|
||||
aPB->ShrunkData(aTS[0], aTS[1], aPBBox);
|
||||
|
||||
// Middle point
|
||||
gp_Pnt aPOnE;
|
||||
// Tangent vector in the middle point
|
||||
gp_Vec aVETgt;
|
||||
aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt);
|
||||
if (aVETgt.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
aProjPS.Perform(aPOnE);
|
||||
if (!aProjPS.NbPoints())
|
||||
continue;
|
||||
|
||||
// Check the distance in the middle point, using the max vertices
|
||||
// tolerance as the criteria.
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
|
||||
continue;
|
||||
|
||||
Standard_Real U, V;
|
||||
aProjPS.LowerDistanceParameters(U, V);
|
||||
if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
|
||||
continue;
|
||||
|
||||
if (aSurfAdaptor.GetType() != GeomAbs_Plane ||
|
||||
aBAC.GetType() != GeomAbs_Line)
|
||||
{
|
||||
gp_Pnt aPOnS = aProjPS.NearestPoint();
|
||||
gp_Vec aVFNorm(aPOnS, aPOnE);
|
||||
if (aVFNorm.SquareMagnitude() > gp::Resolution())
|
||||
{
|
||||
// Angle between vectors should be close to 90 degrees.
|
||||
// We allow deviation of 10 degrees.
|
||||
Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
|
||||
if (Abs(aCos) > 0.17365)
|
||||
bUseAddTol = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute an addition to Fuzzy value
|
||||
Standard_Real aTolAdd = 0.0;
|
||||
if (bUseAddTol)
|
||||
{
|
||||
// Compute the distance from the bounding points of the edge
|
||||
// to the face and use the maximal of these distances as a
|
||||
// fuzzy tolerance for the intersection.
|
||||
// Use the maximal tolerance of the pave block's vertices
|
||||
// as a max criteria for the computed distance.
|
||||
|
||||
for (Standard_Integer iP = 0; iP < 2; ++iP)
|
||||
{
|
||||
gp_Pnt aP = aBAC.Value(aTS[iP]);
|
||||
aProjPS.Perform(aP);
|
||||
if (aProjPS.NbPoints())
|
||||
{
|
||||
Standard_Real aDistEF = aProjPS.LowerDistance();
|
||||
if (aDistEF < aTolCheck && aDistEF > aTolAdd)
|
||||
aTolAdd = aDistEF;
|
||||
}
|
||||
}
|
||||
if (aTolAdd > 0.)
|
||||
{
|
||||
aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF));
|
||||
if (aTolAdd < 0.)
|
||||
aTolAdd = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean bIntersect = aTolAdd > 0;
|
||||
if (!bIntersect)
|
||||
{
|
||||
const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF);
|
||||
bIntersect = !pMPB || !(pMPB->Contains(aPB));
|
||||
}
|
||||
|
||||
if (bIntersect)
|
||||
{
|
||||
// Prepare pair for intersection
|
||||
BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Append1();
|
||||
aEdgeFace.SetIndices(nE, nF);
|
||||
aEdgeFace.SetPaveBlock(aPB);
|
||||
aEdgeFace.SetEdge(aE);
|
||||
aEdgeFace.SetFace(aF);
|
||||
aEdgeFace.SetTolE (BRep_Tool::Tolerance (aE) + aTolAdd / 2.);
|
||||
aEdgeFace.SetTolF (BRep_Tool::Tolerance (aF) + aTolAdd / 2.);
|
||||
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
|
||||
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
|
||||
aEdgeFace.SetProgressIndicator(myProgressIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbEFs = aVEdgeFace.Length();
|
||||
if (!aNbEFs)
|
||||
return;
|
||||
|
||||
aPBMap.Clear();
|
||||
anAlloc->Reset();
|
||||
|
||||
// Perform intersection of the found pairs
|
||||
BOPAlgo_EdgeFaceCnt::Perform (myRunParallel, aVEdgeFace, myContext);
|
||||
|
||||
BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
|
||||
if (theAddInterf && aEFs.IsEmpty())
|
||||
aEFs.SetIncrement(10);
|
||||
|
||||
// Analyze the results of intersection looking for TopAbs_EDGE
|
||||
// intersection type only.
|
||||
|
||||
// Collect all pairs for common block creation
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbEFs; ++i)
|
||||
{
|
||||
BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i);
|
||||
if (!anEdgeFace.IsDone())
|
||||
continue;
|
||||
|
||||
const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts();
|
||||
if (aCParts.Length() != 1)
|
||||
continue;
|
||||
|
||||
const IntTools_CommonPrt& aCP = aCParts(1);
|
||||
if (aCP.Type() != TopAbs_EDGE)
|
||||
continue;
|
||||
|
||||
Standard_Integer nE, nF;
|
||||
anEdgeFace.Indices(nE, nF);
|
||||
if (theAddInterf)
|
||||
{
|
||||
// Add interference
|
||||
BOPDS_InterfEF& aEF = aEFs.Append1();
|
||||
aEF.SetIndices(nE, nF);
|
||||
aEF.SetCommonPart(aCP);
|
||||
myDS->AddInterf(nE, nF);
|
||||
}
|
||||
|
||||
const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock();
|
||||
// Update face information with new IN pave block
|
||||
myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB);
|
||||
if (theAddInterf)
|
||||
// Fill map for common blocks creation
|
||||
BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc);
|
||||
}
|
||||
|
||||
if (aMPBLI.Extent())
|
||||
// Create new common blocks for coinciding pairs
|
||||
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS);
|
||||
}
|
||||
|
@@ -438,7 +438,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
|
||||
aDMBV.Clear();
|
||||
aMVTol.Clear();
|
||||
//
|
||||
myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn);
|
||||
BOPDS_MapOfPaveBlock aMPBCommon;
|
||||
myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
|
||||
myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
|
||||
|
||||
// 1. Treat Points
|
||||
@@ -552,7 +553,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
|
||||
continue;
|
||||
}
|
||||
//
|
||||
bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBOut);
|
||||
bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut);
|
||||
if (bExist) {
|
||||
if (aMPBAdd.Add(aPBOut)) {
|
||||
Standard_Boolean bInBothFaces = Standard_True;
|
||||
@@ -1266,6 +1267,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
|
||||
const BOPDS_Curve& theNC,
|
||||
const Standard_Real theTolR3D,
|
||||
const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
|
||||
const BOPDS_MapOfPaveBlock& /*theMPBCommon*/,
|
||||
Handle(BOPDS_PaveBlock&) aPBOut)
|
||||
{
|
||||
Standard_Boolean bRet;
|
||||
@@ -1276,22 +1278,28 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
|
||||
//
|
||||
bRet=Standard_False;
|
||||
const IntTools_Curve& aIC=theNC.Curve();
|
||||
//Standard_Real aTolCheck = theTolR3D + myFuzzyValue;
|
||||
//
|
||||
thePB->Range(aT1, aT2);
|
||||
thePB->Indices(nV11, nV12);
|
||||
|
||||
const Standard_Real aTolV11 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV11)));
|
||||
const Standard_Real aTolV12 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV12)));
|
||||
const Standard_Real aTolV1 = Max(aTolV11, aTolV12);
|
||||
|
||||
//first point
|
||||
aIC.D0(aT1, aP1);
|
||||
aBoxP1.Add(aP1);
|
||||
aBoxP1.Enlarge(theTolR3D);
|
||||
aBoxP1.Enlarge(aTolV11);
|
||||
//intermediate point
|
||||
aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
|
||||
aIC.D0(aTm, aPm);
|
||||
aBoxPm.Add(aPm);
|
||||
aBoxPm.Enlarge(theTolR3D);
|
||||
//aBoxPm.Enlarge(theTolR3D);
|
||||
//last point
|
||||
aIC.D0(aT2, aP2);
|
||||
aBoxP2.Add(aP2);
|
||||
aBoxP2.Enlarge(theTolR3D);
|
||||
aBoxP2.Enlarge(aTolV12);
|
||||
//
|
||||
aNbPB = theMPBOnIn.Extent();
|
||||
for (i = 1; i <= aNbPB; ++i) {
|
||||
@@ -1300,6 +1308,10 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
|
||||
nSp=aPB->Edge();
|
||||
if (nSp < 0)
|
||||
continue;
|
||||
const Standard_Real aTolV21 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV21)));
|
||||
const Standard_Real aTolV22 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV22)));
|
||||
const Standard_Real aTolV2 = Max(aTolV21, aTolV22);
|
||||
|
||||
const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
|
||||
const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
|
||||
const Bnd_Box& aBoxSp=aSISp.Box();
|
||||
@@ -1309,19 +1321,31 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
|
||||
iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 :
|
||||
(!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
|
||||
if (iFlag1 && iFlag2) {
|
||||
if (aBoxSp.IsOut(aBoxPm) || myContext->ComputePE(aPm,
|
||||
theTolR3D,
|
||||
Standard_Real aRealTol = theTolR3D + myFuzzyValue;
|
||||
Bnd_Box aBoxTmp = aBoxPm;
|
||||
if (myDS->IsCommonBlock(aPB))
|
||||
{
|
||||
aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
|
||||
//if (theMPBCommon.Contains (aPB))
|
||||
// // for an edge, which is a common block with a face,
|
||||
// // increase the chance to coincide with section curve
|
||||
// aRealTol *= 2.;
|
||||
}
|
||||
|
||||
aBoxTmp.Enlarge (aRealTol);
|
||||
if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm,
|
||||
aRealTol,
|
||||
aSp,
|
||||
aTx)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (iFlag1 == 1) {
|
||||
iFlag1 = !myContext->ComputePE(aP1, theTolR3D, aSp, aTx);
|
||||
iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx);
|
||||
}
|
||||
//
|
||||
if (iFlag2 == 1) {
|
||||
iFlag2 = !myContext->ComputePE(aP2, theTolR3D, aSp, aTx);
|
||||
iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx);
|
||||
}
|
||||
//
|
||||
if (iFlag1 && iFlag2) {
|
||||
|
@@ -82,7 +82,8 @@ is
|
||||
imported VectorOfFaceInfo from BOPDS;
|
||||
imported MapOfPave from BOPDS;
|
||||
imported IndexedDataMapOfPaveBlockListOfPaveBlock from BOPDS;
|
||||
imported DataMapOfIntegerListOfPaveBlock from BOPDS;
|
||||
imported DataMapOfIntegerListOfPaveBlock from BOPDS;
|
||||
imported DataMapOfIntegerMapOfPaveBlock from BOPDS;
|
||||
imported IndexedMapOfPaveBlock from BOPDS;
|
||||
imported IndexedDataMapOfPaveBlockListOfInteger from BOPDS;
|
||||
imported IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS;
|
||||
|
@@ -397,7 +397,8 @@ is
|
||||
theF1:Integer from Standard;
|
||||
theF2:Integer from Standard;
|
||||
theMI:out MapOfInteger from BOPCol;
|
||||
aMPB: out IndexedMapOfPaveBlock from BOPDS);
|
||||
theMPB: out IndexedMapOfPaveBlock from BOPDS;
|
||||
theMPBCommon: out MapOfPaveBlock from BOPDS);
|
||||
---Purpose:
|
||||
--- Returns the indices of vertices and pave blocks
|
||||
--- that are On/In for the faces with indices theF1, theF2
|
||||
|
@@ -1535,7 +1535,8 @@ void BOPDS_DS::VerticesOnIn
|
||||
(const Standard_Integer nF1,
|
||||
const Standard_Integer nF2,
|
||||
BOPCol_MapOfInteger& aMI,
|
||||
BOPDS_IndexedMapOfPaveBlock& aMPB)const
|
||||
BOPDS_IndexedMapOfPaveBlock& aMPB,
|
||||
BOPDS_MapOfPaveBlock& theMPBCommon) const
|
||||
{
|
||||
Standard_Integer i, j, nV, nV1, nV2, aNbPB;
|
||||
BOPCol_MapIteratorOfMapOfInteger aIt;
|
||||
@@ -1557,6 +1558,10 @@ void BOPDS_DS::VerticesOnIn
|
||||
aPB->Indices(nV1, nV2);
|
||||
aMI.Add(nV1);
|
||||
aMI.Add(nV2);
|
||||
if (i < 2) {
|
||||
if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB))
|
||||
theMPBCommon.Add(aPB);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
24
src/BOPDS/BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx
Normal file
24
src/BOPDS/BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx
Normal file
@@ -0,0 +1,24 @@
|
||||
// Created by: Eugeny MALTCHIKOV
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef BOPDS_DataMapOfIntegerMapOfPaveBlock_HeaderFile
|
||||
#define BOPDS_DataMapOfIntegerMapOfPaveBlock_HeaderFile
|
||||
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <TColStd_MapTransientHasher.hxx>
|
||||
#include <BOPDS_MapOfPaveBlock.hxx>
|
||||
|
||||
typedef NCollection_DataMap<Standard_Integer, BOPDS_MapOfPaveBlock, TColStd_MapIntegerHasher> BOPDS_DataMapOfIntegerMapOfPaveBlock;
|
||||
|
||||
#endif
|
@@ -32,6 +32,7 @@ BOPDS_DataMapOfShapeCoupleOfPaveBlocks.hxx
|
||||
BOPDS_MapOfPave.hxx
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock.hxx
|
||||
BOPDS_DataMapOfIntegerListOfPaveBlock.hxx
|
||||
BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx
|
||||
BOPDS_IndexedMapOfPaveBlock.hxx
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfInteger.hxx
|
||||
BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks.hxx
|
||||
|
@@ -168,6 +168,17 @@ is
|
||||
aD:out Real from Standard)
|
||||
returns Boolean from Standard;
|
||||
|
||||
UseQuickCoincidenceCheck (me:out;
|
||||
theFlag: Boolean from Standard);
|
||||
---Purpose:
|
||||
--- Enables the option for quick coincidence check for the edge and face.
|
||||
--- Disabled by default.
|
||||
|
||||
IsCoincidenceCheckedQuickly (me)
|
||||
returns Boolean from Standard;
|
||||
---Purpose:
|
||||
--- Returns true if quick coincidence check was enabled.
|
||||
|
||||
-------------------------------------------------------
|
||||
-- Block of protected methods of the algorithm --
|
||||
-------------------------------------------------------
|
||||
@@ -247,7 +258,12 @@ is
|
||||
aCP: CommonPrt from IntTools;
|
||||
aTX:out Real from Standard)
|
||||
returns Boolean from Standard
|
||||
is protected;
|
||||
is protected;
|
||||
|
||||
IsCoincident(me:out)
|
||||
returns Boolean from Standard
|
||||
is protected;
|
||||
---Purpose: Checks if the edge is in the face.
|
||||
|
||||
fields
|
||||
-- Data
|
||||
@@ -287,6 +303,8 @@ fields
|
||||
myPar1 : Real from Standard;
|
||||
myParallel : Boolean from Standard;
|
||||
|
||||
myRange : Range from IntTools;
|
||||
myRange : Range from IntTools;
|
||||
|
||||
myQuickCoincidenceCheck : Boolean from Standard;
|
||||
|
||||
end EdgeFace;
|
||||
|
@@ -264,6 +264,103 @@ const IntTools_Range& IntTools_EdgeFace::Range() const
|
||||
return myRange;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UseQuickCoincidenceCheck
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void IntTools_EdgeFace::UseQuickCoincidenceCheck(const Standard_Boolean bFlag)
|
||||
{
|
||||
myQuickCoincidenceCheck=bFlag;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsCoincidenceCheckedQuickly
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean IntTools_EdgeFace::IsCoincidenceCheckedQuickly() const
|
||||
{
|
||||
return myQuickCoincidenceCheck;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsCoincident
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean IntTools_EdgeFace::IsCoincident()
|
||||
{
|
||||
Standard_Integer i, iCnt;
|
||||
Standard_Real dT, aT, aD, aT1, aT2, aU, aV;
|
||||
|
||||
gp_Pnt aP;
|
||||
TopAbs_State aState;
|
||||
gp_Pnt2d aP2d;
|
||||
//
|
||||
GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
|
||||
|
||||
const Standard_Integer aNbSeg=23;
|
||||
const Standard_Real aTresh=0.5;
|
||||
const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
|
||||
aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
|
||||
const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
|
||||
|
||||
aT1=myRange.First();
|
||||
aT2=myRange.Last();
|
||||
dT=(aT2-aT1)/aNbSeg;
|
||||
//
|
||||
Standard_Boolean isClassified = Standard_False;
|
||||
iCnt=0;
|
||||
for(i=0; i <= aNbSeg; ++i) {
|
||||
aT = aT1+i*dT;
|
||||
aP=myC.Value(aT);
|
||||
//
|
||||
aProjector.Perform(aP);
|
||||
if (!aProjector.IsDone()) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
|
||||
aD=aProjector.LowerDistance();
|
||||
if (aD>myCriteria) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
|
||||
++iCnt;
|
||||
|
||||
//We classify only three points: in the begin, in the
|
||||
//end and in the middle of the edge.
|
||||
//However, exact middle point (when i == (aNbSeg + 1)/2)
|
||||
//can be unprojectable. Therefore, it will not be able to
|
||||
//be classified. Therefore, points with indexes in
|
||||
//[aTreshIdxF, aTreshIdxL] range are made available
|
||||
//for classification.
|
||||
//isClassified == TRUE if MIDDLE point has been choosen and
|
||||
//classified correctly.
|
||||
|
||||
if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
|
||||
continue;
|
||||
|
||||
if(isClassified && (i != aNbSeg))
|
||||
continue;
|
||||
|
||||
aProjector.LowerDistanceParameters(aU, aV);
|
||||
aP2d.SetX(aU);
|
||||
aP2d.SetY(aV);
|
||||
|
||||
IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
|
||||
aState = aClass2d.Perform(aP2d);
|
||||
|
||||
if(aState == TopAbs_OUT)
|
||||
return Standard_False;
|
||||
|
||||
if(i != 0)
|
||||
isClassified = Standard_True;
|
||||
}
|
||||
//
|
||||
const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
|
||||
return (aCoeff > aTresh);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckData
|
||||
//purpose :
|
||||
@@ -1255,6 +1352,16 @@ void IntTools_EdgeFace::Perform()
|
||||
myFClass2d.Init(myFace, 1.e-6);
|
||||
}
|
||||
|
||||
if (myQuickCoincidenceCheck) {
|
||||
if (IsCoincident()) {
|
||||
aCommonPrt.SetType(TopAbs_EDGE);
|
||||
aCommonPrt.SetRange1(myRange.First(), myRange.Last());
|
||||
mySeqOfCommonPrts.Append(aCommonPrt);
|
||||
myIsDone=Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
|
||||
anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
|
||||
//
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Original bug : pro14260
|
||||
# Date : 21 Sept 98
|
||||
puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_"
|
||||
puts "TODO #22911 ALL: Error : The area of the resulting shape is"
|
||||
# puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_"
|
||||
# puts "TODO #22911 ALL: Error : The area of the resulting shape is"
|
||||
|
||||
restore [locate_data_file CTO900_pro14260c.rle] c
|
||||
restore [locate_data_file pro14260d.rle] d
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Original bug : pro10658
|
||||
# Date : 24mar98
|
||||
puts "TODO ALL Error : The area of the resulting shape is"
|
||||
# puts "TODO ALL Error : The area of the resulting shape is"
|
||||
restore [locate_data_file CTO900_pro10658a.rle] a
|
||||
restore [locate_data_file pro10658b.rle] b
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# pro10658
|
||||
puts "TODO ALL Error : The area of the resulting shape is"
|
||||
# puts "TODO ALL Error : The area of the resulting shape is"
|
||||
restore [locate_data_file CTO900_pro10658a.rle] a
|
||||
restore [locate_data_file pro10658b.rle] b
|
||||
|
||||
|
@@ -10,4 +10,4 @@ updatetolerance b 1
|
||||
|
||||
bsection result a b
|
||||
|
||||
set length 135.096
|
||||
set length 130.625
|
||||
|
@@ -8,4 +8,4 @@ restore [locate_data_file ger61235b.brep] object
|
||||
|
||||
bsection result object tool
|
||||
|
||||
set length 11.8242
|
||||
set length 16.4762
|
||||
|
@@ -1,5 +1,5 @@
|
||||
puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
#puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
|
||||
puts "============"
|
||||
puts "OCC697"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
#puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
|
||||
puts "============"
|
||||
puts "OCC697"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
#puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
|
||||
puts "============"
|
||||
puts "OCC697"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
#puts "TODO OCC25829 ALL: Error : The square of result shape is"
|
||||
#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to"
|
||||
|
||||
puts "============"
|
||||
puts "OCC697"
|
||||
|
@@ -13,4 +13,4 @@ bsection result c1 c2
|
||||
|
||||
checkshape result
|
||||
# approximate theoretical length of the result
|
||||
set length 0.00192547
|
||||
set length 0.00200173
|
||||
|
31
tests/bugs/modalg_7/bug31662
Normal file
31
tests/bugs/modalg_7/bug31662
Normal file
@@ -0,0 +1,31 @@
|
||||
puts "============================================================================================="
|
||||
puts "0031662: Modeling Algorithms - Incomplete result of section operation"
|
||||
puts "============================================================================================="
|
||||
puts ""
|
||||
|
||||
restore [locate_data_file bug31662_Surface_0.brep] s0
|
||||
restore [locate_data_file bug31662_Surface_1.brep] s1
|
||||
box bx -4 -7 -1 40 15 10
|
||||
|
||||
bclearobjects
|
||||
bcleartools
|
||||
baddobjects bx
|
||||
baddtools s0 s1
|
||||
bfillds
|
||||
|
||||
bbop r4 4
|
||||
|
||||
checkshape r4
|
||||
checksection r4 -r 0
|
||||
checkprops r4 -l 70.3856
|
||||
|
||||
bbuild rgf
|
||||
|
||||
explode rgf so
|
||||
copy rgf_2 result -ni
|
||||
|
||||
checkshape result
|
||||
checknbshapes result -wire 254 -face 254 -shell 1 -solid 1
|
||||
checkprops result -s 668.352 -v 774.749
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
@@ -1,4 +1,4 @@
|
||||
puts "TODO CR25432 ALL: Error : The square of result shape is"
|
||||
#puts "TODO CR25432 ALL: Error : The square of result shape is"
|
||||
|
||||
puts "================"
|
||||
puts "OCC26"
|
||||
|
Reference in New Issue
Block a user