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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user