mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +03:00
0033247: Modeling Algorithm - BOP report small edges problem and produce empty result
Build shifted pcurve for ellipse and circle cases.
This commit is contained in:
parent
a638dd6224
commit
686926c0a9
@ -93,6 +93,15 @@ public:
|
||||
//! converts RLine to Geom(2d)_Curve.
|
||||
Standard_EXPORT static void TreatRLine (const Handle(IntPatch_RLine)& theRL, const Handle(GeomAdaptor_Surface)& theHS1, const Handle(GeomAdaptor_Surface)& theHS2, Handle(Geom_Curve)& theC3d, Handle(Geom2d_Curve)& theC2d1, Handle(Geom2d_Curve)& theC2d2, Standard_Real& theTolReached);
|
||||
|
||||
//! creates 2D-curve on given surface from given 3D-curve
|
||||
Standard_EXPORT static void BuildPCurves (const Standard_Real theFirst, const Standard_Real theLast,
|
||||
const Standard_Real theUmin, const Standard_Real theUmax,
|
||||
const Standard_Real theVmin, const Standard_Real theVmax,
|
||||
Standard_Real& theTol,
|
||||
const Handle(Geom_Surface)& theSurface,
|
||||
const Handle(Geom_Curve)& theCurve,
|
||||
Handle(Geom2d_Curve)& theCurve2d);
|
||||
|
||||
//! creates 2D-curve on given surface from given 3D-curve
|
||||
Standard_EXPORT static void BuildPCurves (const Standard_Real f, const Standard_Real l, Standard_Real& Tol, const Handle(Geom_Surface)& S, const Handle(Geom_Curve)& C, Handle(Geom2d_Curve)& C2d);
|
||||
|
||||
|
@ -1074,94 +1074,92 @@ void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
|
||||
//function : BuildPCurves
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void GeomInt_IntSS::BuildPCurves (Standard_Real f,
|
||||
Standard_Real l,
|
||||
Standard_Real& Tol,
|
||||
const Handle (Geom_Surface)& S,
|
||||
const Handle (Geom_Curve)& C,
|
||||
Handle (Geom2d_Curve)& C2d)
|
||||
void GeomInt_IntSS::BuildPCurves (const Standard_Real theFirst, const Standard_Real theLast,
|
||||
const Standard_Real theUmin, const Standard_Real theUmax,
|
||||
const Standard_Real theVmin, const Standard_Real theVmax,
|
||||
Standard_Real& theTol,
|
||||
const Handle(Geom_Surface)& theSurface,
|
||||
const Handle(Geom_Curve)& theCurve,
|
||||
Handle(Geom2d_Curve)& theCurve2d)
|
||||
{
|
||||
if (!C2d.IsNull()) {
|
||||
if (!theCurve2d.IsNull() || theSurface.IsNull()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
Standard_Real umin,umax,vmin,vmax;
|
||||
//
|
||||
S->Bounds(umin, umax, vmin, vmax);
|
||||
// in class ProjLib_Function the range of parameters is shrank by 1.e-09
|
||||
if((l - f) > 2.e-09) {
|
||||
C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
|
||||
if (C2d.IsNull()) {
|
||||
if ((theLast - theFirst) > 2.e-09) {
|
||||
theCurve2d = GeomProjLib::Curve2d(theCurve, theFirst, theLast, theSurface, theUmin, theUmax, theVmin, theVmax, theTol);
|
||||
if (theCurve2d.IsNull()) {
|
||||
// proj. a circle that goes through the pole on a sphere to the sphere
|
||||
Tol += Precision::Confusion();
|
||||
C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
|
||||
theTol += Precision::Confusion();
|
||||
theCurve2d = GeomProjLib::Curve2d(theCurve, theFirst, theLast, theSurface, theTol);
|
||||
}
|
||||
const Handle(Standard_Type)& aType = C2d->DynamicType();
|
||||
if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve))
|
||||
{
|
||||
const Handle(Standard_Type)& aType = theCurve2d->DynamicType();
|
||||
if (aType == STANDARD_TYPE(Geom2d_BSplineCurve))
|
||||
{
|
||||
//Check first, last knots to avoid problems with trimming
|
||||
//First, last knots can differ from f, l because of numerical error
|
||||
//of projection and approximation
|
||||
//The same checking as in Geom2d_TrimmedCurve
|
||||
if((C2d->FirstParameter() - f > Precision::PConfusion()) ||
|
||||
(l - C2d->LastParameter() > Precision::PConfusion()))
|
||||
if ((theCurve2d->FirstParameter() - theFirst > Precision::PConfusion()) ||
|
||||
(theLast - theCurve2d->LastParameter() > Precision::PConfusion()))
|
||||
{
|
||||
Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
|
||||
Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
|
||||
TColStd_Array1OfReal aKnots(1, aBspl->NbKnots());
|
||||
aBspl->Knots(aKnots);
|
||||
BSplCLib::Reparametrize(f, l, aKnots);
|
||||
BSplCLib::Reparametrize(theFirst, theLast, aKnots);
|
||||
aBspl->SetKnots(aKnots);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((l - f) > Epsilon(Abs(f)))
|
||||
if ((theLast - theFirst) > Epsilon(Abs(theFirst)))
|
||||
{
|
||||
//The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
|
||||
//On this small range C2d can be considered as segment
|
||||
//of line.
|
||||
|
||||
Standard_Real aU=0., aV=0.;
|
||||
Standard_Real aU = 0., aV = 0.;
|
||||
GeomAdaptor_Surface anAS;
|
||||
anAS.Load(S);
|
||||
anAS.Load(theSurface);
|
||||
Extrema_ExtPS anExtr;
|
||||
const gp_Pnt aP3d1 = C->Value(f);
|
||||
const gp_Pnt aP3d2 = C->Value(l);
|
||||
const gp_Pnt aP3d1 = theCurve->Value(theFirst);
|
||||
const gp_Pnt aP3d2 = theCurve->Value(theLast);
|
||||
|
||||
anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
|
||||
anExtr.Initialize(anAS, umin, umax, vmin, vmax,
|
||||
Precision::Confusion(), Precision::Confusion());
|
||||
anExtr.Initialize(anAS, theUmin, theUmax, theVmin, theVmax,
|
||||
Precision::Confusion(), Precision::Confusion());
|
||||
anExtr.Perform(aP3d1);
|
||||
|
||||
if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
|
||||
if (ParametersOfNearestPointOnSurface(anExtr, aU, aV))
|
||||
{
|
||||
const gp_Pnt2d aP2d1(aU, aV);
|
||||
|
||||
anExtr.Perform(aP3d2);
|
||||
|
||||
if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
|
||||
if (ParametersOfNearestPointOnSurface(anExtr, aU, aV))
|
||||
{
|
||||
const gp_Pnt2d aP2d2(aU, aV);
|
||||
|
||||
if(aP2d1.Distance(aP2d2) > gp::Resolution())
|
||||
if (aP2d1.Distance(aP2d2) > gp::Resolution())
|
||||
{
|
||||
TColgp_Array1OfPnt2d poles(1,2);
|
||||
TColStd_Array1OfReal knots(1,2);
|
||||
TColStd_Array1OfInteger mults(1,2);
|
||||
TColgp_Array1OfPnt2d poles(1, 2);
|
||||
TColStd_Array1OfReal knots(1, 2);
|
||||
TColStd_Array1OfInteger mults(1, 2);
|
||||
poles(1) = aP2d1;
|
||||
poles(2) = aP2d2;
|
||||
knots(1) = f;
|
||||
knots(2) = l;
|
||||
knots(1) = theFirst;
|
||||
knots(2) = theLast;
|
||||
mults(1) = mults(2) = 2;
|
||||
|
||||
C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
|
||||
theCurve2d = new Geom2d_BSplineCurve(poles, knots, mults, 1);
|
||||
|
||||
//Check same parameter in middle point .begin
|
||||
const gp_Pnt PMid(C->Value(0.5*(f+l)));
|
||||
const gp_Pnt PMid(theCurve->Value(0.5*(theFirst + theLast)));
|
||||
const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
|
||||
const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
|
||||
const Standard_Real aDist = PMid.Distance(aPC);
|
||||
Tol = Max(aDist, Tol);
|
||||
theTol = Max(aDist, theTol);
|
||||
//Check same parameter in middle point .end
|
||||
}
|
||||
}
|
||||
@ -1169,27 +1167,51 @@ void GeomInt_IntSS::BuildPCurves (Standard_Real f,
|
||||
}
|
||||
}
|
||||
//
|
||||
if (S->IsUPeriodic() && !C2d.IsNull()) {
|
||||
if (theSurface->IsUPeriodic() && !theCurve2d.IsNull()) {
|
||||
// Recadre dans le domaine UV de la face
|
||||
Standard_Real aTm, U0, aEps, period, du, U0x;
|
||||
Standard_Boolean bAdjust;
|
||||
//
|
||||
aEps = Precision::PConfusion();
|
||||
period = S->UPeriod();
|
||||
period = theSurface->UPeriod();
|
||||
//
|
||||
aTm = .5*(f + l);
|
||||
gp_Pnt2d pm = C2d->Value(aTm);
|
||||
aTm = .5 * (theFirst + theLast);
|
||||
gp_Pnt2d pm = theCurve2d->Value(aTm);
|
||||
U0 = pm.X();
|
||||
//
|
||||
bAdjust =
|
||||
GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
|
||||
bAdjust =
|
||||
GeomInt::AdjustPeriodic(U0, theUmin, theUmax, period, U0x, du, aEps);
|
||||
if (bAdjust) {
|
||||
gp_Vec2d T1(du, 0.);
|
||||
C2d->Translate(T1);
|
||||
theCurve2d->Translate(T1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : BuildPCurves
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void GeomInt_IntSS::BuildPCurves (const Standard_Real f,
|
||||
const Standard_Real l,
|
||||
Standard_Real& Tol,
|
||||
const Handle (Geom_Surface)& S,
|
||||
const Handle (Geom_Curve)& C,
|
||||
Handle (Geom2d_Curve)& C2d)
|
||||
{
|
||||
if (!C2d.IsNull() || S.IsNull()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
Standard_Real umin,umax,vmin,vmax;
|
||||
//
|
||||
S->Bounds(umin, umax, vmin, vmax);
|
||||
|
||||
BuildPCurves(f, l, umin, umax, vmin, vmax, Tol, S, C, C2d);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TrimILineOnSurfBoundaries
|
||||
//purpose : This function finds intersection points of given curves with
|
||||
|
@ -990,15 +990,19 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
|
||||
if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
|
||||
if(myApprox1) {
|
||||
Handle (Geom2d_Curve) C2d;
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
|
||||
myHS1->Surface(), newc, C2d);
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm,
|
||||
myHS1->FirstUParameter(), myHS1->LastUParameter(),
|
||||
myHS1->FirstVParameter(), myHS1->LastVParameter(),
|
||||
Tolpc, myHS1->Surface(), newc, C2d);
|
||||
aCurve.SetFirstCurve2d(C2d);
|
||||
}
|
||||
|
||||
if(myApprox2) {
|
||||
Handle (Geom2d_Curve) C2d;
|
||||
GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
|
||||
myHS2->Surface(),newc,C2d);
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm,
|
||||
myHS2->FirstUParameter(), myHS2->LastUParameter(),
|
||||
myHS2->FirstVParameter(), myHS2->LastVParameter(),
|
||||
Tolpc, myHS2->Surface(), newc, C2d);
|
||||
aCurve.SetSecondCurve2d(C2d);
|
||||
}
|
||||
}
|
||||
@ -1059,15 +1063,19 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
|
||||
|
||||
if(myApprox1) {
|
||||
Handle (Geom2d_Curve) C2d;
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
|
||||
myHS1->Surface(), newc, C2d);
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm,
|
||||
myHS1->FirstUParameter(), myHS1->LastUParameter(),
|
||||
myHS1->FirstVParameter(), myHS1->LastVParameter(),
|
||||
Tolpc, myHS1->Surface(), newc, C2d);
|
||||
aCurve.SetFirstCurve2d(C2d);
|
||||
}
|
||||
|
||||
if(myApprox2) {
|
||||
Handle (Geom2d_Curve) C2d;
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
|
||||
myHS2->Surface(), newc, C2d);
|
||||
GeomInt_IntSS::BuildPCurves(fprm, lprm,
|
||||
myHS2->FirstUParameter(), myHS2->LastUParameter(),
|
||||
myHS2->FirstVParameter(), myHS2->LastVParameter(),
|
||||
Tolpc, myHS2->Surface(), newc, C2d);
|
||||
aCurve.SetSecondCurve2d(C2d);
|
||||
}
|
||||
}// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
|
||||
|
13
tests/bugs/modalg_8/bug33247
Normal file
13
tests/bugs/modalg_8/bug33247
Normal file
@ -0,0 +1,13 @@
|
||||
puts "============"
|
||||
puts "0033247: Modeling Algorithms - BOP report small edges problem and produce empty result"
|
||||
puts "============"
|
||||
puts ""
|
||||
|
||||
restore [locate_data_file bug33247_object.brep] a
|
||||
restore [locate_data_file bug33247_tool.brep] b
|
||||
bcommon r a b
|
||||
|
||||
checknbshapes r -vertex 98 -edge 131 -wire 35 -face 26
|
||||
checkprops r -s 157.39
|
||||
|
||||
checkview -display r -2d -path ${imagedir}/${test_image}.png
|
Loading…
x
Reference in New Issue
Block a user