1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +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

@@ -35,6 +35,7 @@
#include <Geom2dAdaptor_Curve.hxx>
#include <ProjLib.hxx>
//======================================================================
// function: SequenceOfLine
//======================================================================
@@ -125,7 +126,7 @@ void IntPatch_Intersection::SetTolerances(const Standard_Real TolArc,
if(myTolArc>0.5) myTolArc=0.5;
if(myTolTang>0.5) myTolTang=0.5;
if(myFleche<1.0e-3) myFleche=1e-3;
if(myUVMaxStep<1.0e-3) myUVMaxStep=1e-3;
//if(myUVMaxStep<1.0e-3) myUVMaxStep=1e-3;
if(myFleche>10) myFleche=10;
if(myUVMaxStep>0.5) myUVMaxStep=0.5;
}
@@ -1023,7 +1024,6 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_Surface)& theS1,
myFleche = 0.01;
if(myUVMaxStep <= Precision::PConfusion())
myUVMaxStep = 0.01;
done = Standard_False;
spnt.Clear();
slin.Clear();
@@ -1254,15 +1254,16 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_Surface)& t
const GeomAbs_SurfaceType typs2)
{
IntPatch_PrmPrmIntersection interpp;
//
if(!theD1->DomainIsInfinite() && !theD2->DomainIsInfinite())
{
Standard_Boolean ClearFlag = Standard_True;
if(!ListOfPnts.IsEmpty())
{
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts);
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche, myUVMaxStep, ListOfPnts);
ClearFlag = Standard_False;
}
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche, myUVMaxStep,ClearFlag);
}
else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
{
@@ -1275,7 +1276,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_Surface)& t
const Standard_Real AP = Max(MU, MV);
Handle(Adaptor3d_Surface) SS;
FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche, myUVMaxStep);
}
else
{
@@ -1285,7 +1286,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_Surface)& t
const Standard_Real AP = Max(MU, MV);
Handle(Adaptor3d_Surface) SS;
FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche,myUVMaxStep);
interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche, myUVMaxStep);
}
}//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
else
@@ -1324,7 +1325,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_Surface)& t
Handle(Adaptor3d_Surface) nS1 = theS1;
Handle(Adaptor3d_Surface) nS2 = theS2;
FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche, myUVMaxStep);
}// 'NON - COLLINEAR LINES'
}// both domains are infinite
@@ -1791,3 +1792,134 @@ void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
#endif
}
//=======================================================================
//function : CheckSingularPoints
//purpose :
//=======================================================================
Standard_Boolean IntPatch_Intersection::CheckSingularPoints(
const Handle(Adaptor3d_Surface)& theS1,
const Handle(Adaptor3d_TopolTool)& theD1,
const Handle(Adaptor3d_Surface)& theS2,
Standard_Real& theDist)
{
theDist = Precision::Infinite();
Standard_Boolean isSingular = Standard_False;
if (theS1 == theS2)
{
return isSingular;
}
//
const Standard_Integer aNbBndPnts = 5;
const Standard_Real aTol = Precision::Confusion();
Standard_Integer i;
theD1->Init();
Standard_Boolean isU = Standard_True;
for (; theD1->More(); theD1->Next())
{
Handle(Adaptor2d_Curve2d) aBnd = theD1->Value();
Standard_Real pinf = aBnd->FirstParameter(), psup = aBnd->LastParameter();
if (Precision::IsNegativeInfinite(pinf) || Precision::IsPositiveInfinite(psup))
{
continue;
}
Standard_Real t, dt = (psup - pinf) / (aNbBndPnts - 1);
gp_Pnt2d aP1;
gp_Vec2d aDir;
aBnd->D1((pinf + psup) / 2., aP1, aDir);
if (Abs(aDir.X()) > Abs(aDir.Y()))
isU = Standard_True;
else
isU = Standard_False;
gp_Pnt aPP1;
gp_Vec aDU, aDV;
Standard_Real aD1NormMax = 0.;
gp_XYZ aPmid(0., 0., 0.);
Standard_Integer aNb = 0;
for (t = pinf; t <= psup; t += dt)
{
aP1 = aBnd->Value(t);
theS1->D1(aP1.X(), aP1.Y(), aPP1, aDU, aDV);
if (isU)
aD1NormMax = Max(aD1NormMax, aDU.Magnitude());
else
aD1NormMax = Max(aD1NormMax, aDV.Magnitude());
aPmid += aPP1.XYZ();
aNb++;
if (aD1NormMax > aTol)
break;
}
if (aD1NormMax <= aTol)
{
//Singular point aPP1;
aPmid /= aNb;
aPP1.SetXYZ(aPmid);
Standard_Real aTolU = Precision::PConfusion(), aTolV = Precision::PConfusion();
Extrema_ExtPS aProj(aPP1, *theS2.get(), aTolU, aTolV, Extrema_ExtFlag_MIN);
if (aProj.IsDone())
{
Standard_Integer aNbExt = aProj.NbExt();
for (i = 1; i <= aNbExt; ++i)
{
theDist = Min(theDist, aProj.SquareDistance(i));
}
}
}
}
if (!Precision::IsInfinite(theDist))
{
theDist = Sqrt(theDist);
isSingular = Standard_True;
}
return isSingular;
}
//=======================================================================
//function : DefineUVMaxStep
//purpose :
//=======================================================================
Standard_Real IntPatch_Intersection::DefineUVMaxStep(
const Handle(Adaptor3d_Surface)& theS1,
const Handle(Adaptor3d_TopolTool)& theD1,
const Handle(Adaptor3d_Surface)& theS2,
const Handle(Adaptor3d_TopolTool)& theD2)
{
Standard_Real anUVMaxStep = 0.001;
Standard_Real aDistToSing1 = Precision::Infinite();
Standard_Real aDistToSing2 = Precision::Infinite();
const Standard_Real aTolMin = Precision::Confusion(), aTolMax = 1.e-5;
if (theS1 != theS2)
{
Standard_Boolean isSing1 = CheckSingularPoints(theS1, theD1, theS2, aDistToSing1);
if (isSing1)
{
if (aDistToSing1 > aTolMin && aDistToSing1 < aTolMax)
{
anUVMaxStep = 0.0001;
}
else
{
isSing1 = Standard_False;
}
}
if (!isSing1)
{
Standard_Boolean isSing2 = CheckSingularPoints(theS2, theD2, theS1, aDistToSing2);
if (isSing2)
{
if (aDistToSing2 > aTolMin && aDistToSing2 < aTolMax)
{
anUVMaxStep = 0.0001;
}
}
}
}
return anUVMaxStep;
}

View File

@@ -133,7 +133,21 @@ public:
//! Mode for more accurate dumps.
Standard_EXPORT void Dump (const Standard_Integer Mode, const Handle(Adaptor3d_Surface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_Surface)& S2, const Handle(Adaptor3d_TopolTool)& D2) const;
//! Checks if surface theS1 has degenerated boundary (dS/du or dS/dv = 0) and
//! calculates minimal distance between corresponding singular points and surface theS2
//! If singular point exists the method returns "true" and stores minimal distance in theDist.
Standard_EXPORT static Standard_Boolean CheckSingularPoints(
const Handle(Adaptor3d_Surface)& theS1,
const Handle(Adaptor3d_TopolTool)& theD1,
const Handle(Adaptor3d_Surface)& theS2,
Standard_Real& theDist);
//! Calculates recommended value for myUVMaxStep depending on surfaces and their domains
Standard_EXPORT static Standard_Real DefineUVMaxStep(
const Handle(Adaptor3d_Surface)& theS1,
const Handle(Adaptor3d_TopolTool)& theD1,
const Handle(Adaptor3d_Surface)& theS2,
const Handle(Adaptor3d_TopolTool)& theD2);
protected:

View File

@@ -2386,6 +2386,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_Surface)& Surf
//Try to extend the intersection line to the boundary,
//if it is possibly
PW.PutToBoundary(Surf1, Surf2);
//
if (PW.NbPoints() < 3)
continue;
const Standard_Integer aMinNbPoints = 40;
if(PW.NbPoints() < aMinNbPoints)

View File

@@ -649,8 +649,11 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
IntCS.ParameterOnSurface(U2,V2);
gp_Pnt anOldPnt, aNewPnt;
OtherSurf->D0(U,V, anOldPnt);
OtherSurf->D0(U2,V2, aNewPnt);
if (anOldPnt.SquareDistance(aNewPnt) < Precision::SquareConfusion())
OtherSurf->D0(U2,V2, aNewPnt);
//if (anOldPnt.SquareDistance(aNewPnt) < Precision::SquareConfusion())
Standard_Real aTolConf = Max(Precision::Confusion(), edgeTol);
if (anOldPnt.SquareDistance(aNewPnt) < aTolConf * aTolConf)
{
U2 = U;
V2 = V;