1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0032701: Modeling Algorithms - 2d curve has bending near the degenerated edge of the face

ApproxInt_Approx, ApproxInt_KnotTools, BRepApprox_Approx,
GeomInt_IntSS, IntTools_FaceFace:
  Analysis of curvature is added for adjusting ParametrizationType

IntPatch_Intersection.cxx - adding methods for estimation of UV max step depending on used surfaces

GeomInt_IntSS.cxx, IntTools_FaceFace.cxx - using methods for max step estimation

Approx_SameParameter.cxx - adding control against big values.

BOPAlgo_PaveFiller_6.cxx - adjusting position of faces before intersection
This commit is contained in:
ifv
2021-12-02 17:02:17 +03:00
committed by smoskvin
parent 5614b1369a
commit 9eee5ab7e4
22 changed files with 776 additions and 135 deletions

View File

@@ -278,6 +278,35 @@ void BOPAlgo_PaveFiller::PerformFF(const Message_ProgressRange& theRange)
// Post-processing options
Standard_Boolean bSplitCurve = Standard_False;
//
// Collect all pairs of Edge/Edge interferences to check if
// some faces have to be moved to obtain more precise intersection
NCollection_DataMap<BOPDS_Pair, TColStd_ListOfInteger, BOPDS_PairMapHasher> aEEMap;
const BOPDS_VectorOfInterfEE& aVEEs = myDS->InterfEE();
for (Standard_Integer iEE = 0; iEE < aVEEs.Size(); ++iEE)
{
const BOPDS_Interf& aEE = aVEEs(iEE);
if (!aEE.HasIndexNew())
{
continue;
}
Standard_Integer nE1, nE2;
aEE.Indices(nE1, nE2);
const Standard_Integer nVN = aEE.IndexNew();
BOPDS_Pair aPair(nE1, nE2);
TColStd_ListOfInteger* pPoints = aEEMap.ChangeSeek(aPair);
if (pPoints)
{
pPoints->Append(nVN);
}
else
{
pPoints = aEEMap.Bound(BOPDS_Pair(nE1, nE2), TColStd_ListOfInteger());
pPoints->Append(nVN);
}
}
// Prepare the pairs of faces for intersection
BOPAlgo_VectorOfFaceFace aVFaceFace;
myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
@@ -306,15 +335,87 @@ void BOPAlgo_PaveFiller::PerformFF(const Message_ProgressRange& theRange)
continue;
}
}
// Check if there is an intersection between edges of the faces.
// If there is an intersection, check if there is a shift between the edges
// (intersection point is on some distance from the edges), and move one of
// the faces to the point of exact edges intersection. This should allow
// obtaining more precise intersection curves between the faces
// (at least the curves should reach the boundary).
// Note, that currently this check considers only closed edges (seam edges).
TopoDS_Face aFShifted1 = aF1, aFShifted2 = aF2;
// Keep shift value to use it as the tolerance for intersection curves
Standard_Real aShiftValue = 0.;
if (aBAS1.GetType() != GeomAbs_Plane ||
aBAS2.GetType() != GeomAbs_Plane) {
Standard_Boolean isFound = Standard_False;
for (TopExp_Explorer aExp1(aF1, TopAbs_EDGE); !isFound && aExp1.More(); aExp1.Next())
{
const TopoDS_Edge& aE1 = TopoDS::Edge(aExp1.Current());
const Standard_Integer nE1 = myDS->Index(aE1);
for (TopExp_Explorer aExp2(aF2, TopAbs_EDGE); !isFound && aExp2.More(); aExp2.Next())
{
const TopoDS_Edge& aE2 = TopoDS::Edge(aExp2.Current());
const Standard_Integer nE2 = myDS->Index(aE2);
Standard_Boolean bIsClosed1 = BRep_Tool::IsClosed(aE1, aF1);
Standard_Boolean bIsClosed2 = BRep_Tool::IsClosed(aE2, aF2);
if (!bIsClosed1 && !bIsClosed2)
{
continue;
}
const TColStd_ListOfInteger* pPoints = aEEMap.Seek(BOPDS_Pair(nE1, nE2));
if (!pPoints)
{
continue;
}
for (TColStd_ListOfInteger::Iterator itEEP(*pPoints); itEEP.More(); itEEP.Next())
{
const Standard_Integer& nVN = itEEP.Value();
const TopoDS_Vertex& aVN = TopoDS::Vertex(myDS->Shape(nVN));
const gp_Pnt& aPnt = BRep_Tool::Pnt(aVN);
// Compute points exactly on the edges
GeomAPI_ProjectPointOnCurve& aProjPC1 = myContext->ProjPC(aE1);
GeomAPI_ProjectPointOnCurve& aProjPC2 = myContext->ProjPC(aE2);
aProjPC1.Perform(aPnt);
aProjPC2.Perform(aPnt);
if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
{
continue;
}
gp_Pnt aP1 = aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aPnt;
gp_Pnt aP2 = aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aPnt;
Standard_Real aShiftDist = aP1.Distance(aP2);
if (aShiftDist > BRep_Tool::Tolerance(aVN))
{
// Move one of the faces to the point of exact intersection of edges
gp_Trsf aTrsf;
aTrsf.SetTranslation(bIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1));
TopLoc_Location aLoc(aTrsf);
(bIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc);
aShiftValue = aShiftDist;
isFound = Standard_True;
}
}
}
}
}
//
BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Appended();
//
aFaceFace.SetRunParallel (myRunParallel);
aFaceFace.SetIndices(nF1, nF2);
aFaceFace.SetFaces(aF1, aF2);
aFaceFace.SetFaces(aFShifted1, aFShifted2);
aFaceFace.SetBoxes (myDS->ShapeInfo (nF1).Box(), myDS->ShapeInfo (nF2).Box());
// compute minimal tolerance for the curves
Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
// Note: in case of faces with closed edges it should not be less than value of the shift
Standard_Real aTolFF = Max(aShiftValue, ToleranceFF(aBAS1, aBAS2));
aFaceFace.SetTolFF(aTolFF);
//
IntSurf_ListOfPntOn2S aListOfPnts;