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