mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0026418: Unjustified limitation on tolerance of a input shape in BRepOffset_MakeOffset
Performance improvements and regression elimination. Handling of degenerated case added. Update of test-case offset faces_type_a A2 according to the new behavior Test-case for issue #26418
This commit is contained in:
parent
a1c05aa5ec
commit
a07a041696
@ -657,8 +657,6 @@ static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
|
|||||||
Standard_Real TolV = BRep_Tool::Tolerance(V);
|
Standard_Real TolV = BRep_Tool::Tolerance(V);
|
||||||
if (TolV > Tol) Tol = TolV;
|
if (TolV > Tol) Tol = TolV;
|
||||||
}
|
}
|
||||||
//Patch
|
|
||||||
Tol *= 5.;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -688,10 +686,9 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
|
|||||||
// Preanalyse.
|
// Preanalyse.
|
||||||
// ------------
|
// ------------
|
||||||
EvalMax(myShape,myTol);
|
EvalMax(myShape,myTol);
|
||||||
if (myTol > Abs(myOffset*0.5)) {
|
// There are possible second variant: analytical continuation of arcsin.
|
||||||
Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Tol > Offset");
|
Standard_Real TolAngleCoeff = Min(myTol/Abs(myOffset*0.5), 1.0);
|
||||||
}
|
Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
|
||||||
Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
|
|
||||||
myAnalyse.Perform(myShape,TolAngle);
|
myAnalyse.Perform(myShape,TolAngle);
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
// Construction of Offset from preanalysis.
|
// Construction of Offset from preanalysis.
|
||||||
|
@ -1151,14 +1151,15 @@ static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
static TopoDS_Edge Glue(const TopoDS_Edge& E1,
|
static TopoDS_Edge Glue(const TopoDS_Edge& E1,
|
||||||
const TopoDS_Edge& E2,
|
const TopoDS_Edge& E2,
|
||||||
const TopoDS_Vertex& Vfirst,
|
const TopoDS_Vertex& Vfirst,
|
||||||
const TopoDS_Vertex& Vlast,
|
const TopoDS_Vertex& Vlast,
|
||||||
const Standard_Boolean After,
|
const Standard_Boolean After,
|
||||||
const TopoDS_Face& F1,
|
const TopoDS_Face& F1,
|
||||||
const Standard_Boolean addPCurve1,
|
const Standard_Boolean addPCurve1,
|
||||||
const TopoDS_Face& F2,
|
const TopoDS_Face& F2,
|
||||||
const Standard_Boolean addPCurve2)
|
const Standard_Boolean addPCurve2,
|
||||||
|
const Standard_Real theGlueTol)
|
||||||
{
|
{
|
||||||
Standard_Real Tol = 1.e-7;
|
Standard_Real Tol = 1.e-7;
|
||||||
GeomAbs_Shape Continuity = GeomAbs_C1;
|
GeomAbs_Shape Continuity = GeomAbs_C1;
|
||||||
@ -1196,7 +1197,7 @@ static TopoDS_Edge Glue(const TopoDS_Edge& E1,
|
|||||||
Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
|
Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
|
||||||
Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
|
Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
|
||||||
GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
|
GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
|
||||||
Concat.Add( TC2, Precision::Confusion(), After );
|
Concat.Add( TC2, theGlueTol, After );
|
||||||
newCurve = Concat.BSplineCurve();
|
newCurve = Concat.BSplineCurve();
|
||||||
if (newCurve->Continuity() < GeomAbs_C1)
|
if (newCurve->Continuity() < GeomAbs_C1)
|
||||||
{
|
{
|
||||||
@ -1484,6 +1485,7 @@ static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
|
|||||||
const TopTools_SequenceOfShape& EdgesForConcat)
|
const TopTools_SequenceOfShape& EdgesForConcat)
|
||||||
{
|
{
|
||||||
TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
|
TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
|
||||||
|
Standard_Real aGlueTol = Precision::Confusion();
|
||||||
for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
||||||
{
|
{
|
||||||
TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
|
TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
|
||||||
@ -1508,6 +1510,7 @@ static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
|
|||||||
{
|
{
|
||||||
TopoDS_Vertex CV, V11, V12, V21, V22;
|
TopoDS_Vertex CV, V11, V12, V21, V22;
|
||||||
TopExp::CommonVertex( CurEdge, anEdge, CV );
|
TopExp::CommonVertex( CurEdge, anEdge, CV );
|
||||||
|
aGlueTol = BRep_Tool::Tolerance(CV);
|
||||||
TopExp::Vertices( CurEdge, V11, V12 );
|
TopExp::Vertices( CurEdge, V11, V12 );
|
||||||
TopExp::Vertices( anEdge, V21, V22 );
|
TopExp::Vertices( anEdge, V21, V22 );
|
||||||
if (V11.IsSame(CV) && V21.IsSame(CV))
|
if (V11.IsSame(CV) && V21.IsSame(CV))
|
||||||
@ -1532,9 +1535,8 @@ static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
|
|||||||
}
|
}
|
||||||
} //end of else (open wire)
|
} //end of else (open wire)
|
||||||
|
|
||||||
TopoDS_Edge NewEdge = Glue(CurEdge, anEdge,
|
TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
|
||||||
Vfirst, Vlast, After,
|
F1, addPCurve1, F2, addPCurve2, aGlueTol);
|
||||||
F1, addPCurve1, F2, addPCurve2);
|
|
||||||
CurEdge = NewEdge;
|
CurEdge = NewEdge;
|
||||||
} //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
} //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
||||||
|
|
||||||
|
@ -1768,7 +1768,19 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
|
|||||||
if (NStatus == CSLib_Defined)
|
if (NStatus == CSLib_Defined)
|
||||||
P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
|
P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (NStatus == CSLib_InfinityOfSolutions &&
|
||||||
|
D1U.SquareMagnitude() + D1V.SquareMagnitude() > MagTol * MagTol)
|
||||||
|
{
|
||||||
|
// Use non-null derivative as normal direction in degenerated case.
|
||||||
|
gp_Vec aNorm = D1U.SquareMagnitude() > MagTol * MagTol ? D1U : D1V;
|
||||||
|
aNorm.Normalize();
|
||||||
|
|
||||||
|
P.SetXYZ(P.XYZ() + offsetValue * signe * aNorm.XYZ());
|
||||||
|
return;
|
||||||
|
}
|
||||||
Geom_UndefinedValue::Raise();
|
Geom_UndefinedValue::Raise();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1777,21 +1789,70 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
|
|||||||
//function :
|
//function :
|
||||||
//purpose : private
|
//purpose : private
|
||||||
//=======================================================================/
|
//=======================================================================/
|
||||||
void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
|
void Geom_OffsetSurface::SetD1(const Standard_Real U,
|
||||||
Pnt& P,
|
const Standard_Real V,
|
||||||
Vec& D1U, Vec& D1V,
|
Pnt& P,
|
||||||
const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const
|
Vec& D1U, Vec& D1V, // First derivative
|
||||||
|
const Vec& D2UU, const Vec& D2VV, const Vec& D2UV ) const // Second derivative
|
||||||
{
|
{
|
||||||
|
|
||||||
Standard_Real MagTol=0.000000001;
|
Standard_Real MagTol=0.000000001;
|
||||||
|
|
||||||
|
// Check offset side.
|
||||||
|
Handle(Geom_BSplineSurface) L;
|
||||||
|
Standard_Boolean AlongU = Standard_False,
|
||||||
|
AlongV = Standard_False;
|
||||||
|
Standard_Boolean IsOpposite=Standard_False;
|
||||||
|
AlongU = UOsculatingSurface(U,V,IsOpposite,L);
|
||||||
|
AlongV = VOsculatingSurface(U,V,IsOpposite,L);
|
||||||
|
Standard_Real signe = 1.0;
|
||||||
|
if ((AlongV || AlongU) && IsOpposite)
|
||||||
|
signe = -1.0;
|
||||||
|
|
||||||
Dir Normal;
|
Dir Normal;
|
||||||
CSLib_NormalStatus NStatus;
|
CSLib_NormalStatus NStatus;
|
||||||
CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
|
CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
|
||||||
Standard_Integer MaxOrder;
|
Standard_Integer MaxOrder;
|
||||||
if (NStatus == CSLib_Defined)
|
if (NStatus == CSLib_Defined)
|
||||||
|
{
|
||||||
MaxOrder=0;
|
MaxOrder=0;
|
||||||
|
|
||||||
|
if (!AlongV && !AlongU)
|
||||||
|
{
|
||||||
|
// AlongU or AlongV leads to more complex D1 computation
|
||||||
|
// Try to compute D0 and D1 much simpler
|
||||||
|
P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ());
|
||||||
|
|
||||||
|
gp_Vec aN0(Normal.XYZ()), aN1U, aN1V;
|
||||||
|
Standard_Real aScale = (D1U^D1V).Dot(aN0);
|
||||||
|
aN1U.SetX(D2UU.Y() * D1V.Z() + D1U.Y() * D2UV.Z()
|
||||||
|
- D2UU.Z() * D1V.Y() - D1U.Z() * D2UV.Y());
|
||||||
|
aN1U.SetY((D2UU.X() * D1V.Z() + D1U.X() * D2UV.Z()
|
||||||
|
- D2UU.Z() * D1V.X() - D1U.Z() * D2UV.X() ) * -1.0);
|
||||||
|
aN1U.SetZ(D2UU.X() * D1V.Y() + D1U.X() * D2UV.Y()
|
||||||
|
- D2UU.Y() * D1V.X() - D1U.Y() * D2UV.X());
|
||||||
|
Standard_Real aScaleU = aN1U.Dot(aN0);
|
||||||
|
aN1U.Subtract(aScaleU * aN0);
|
||||||
|
aN1U /= aScale;
|
||||||
|
|
||||||
|
aN1V.SetX(D2UV.Y() * D1V.Z() + D2VV.Z() * D1U.Y()
|
||||||
|
- D2UV.Z() * D1V.Y() - D2VV.Y() * D1U.Z());
|
||||||
|
aN1V.SetY((D2UV.X() * D1V.Z() + D2VV.Z() * D1U.X()
|
||||||
|
- D2UV.Z() * D1V.X() - D2VV.X() * D1U.Z()) * -1.0);
|
||||||
|
aN1V.SetZ(D2UV.X() * D1V.Y() + D2VV.Y() * D1U.X()
|
||||||
|
- D2UV.Y() * D1V.X() - D2VV.X() * D1U.Y());
|
||||||
|
Standard_Real aScaleV = aN1V.Dot(aN0);
|
||||||
|
aN1V.Subtract(aScaleV * aN0);
|
||||||
|
aN1V /= aScale;
|
||||||
|
|
||||||
|
D1U += offsetValue * signe * aN1U;
|
||||||
|
D1V += offsetValue * signe * aN1V;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MaxOrder=3;
|
MaxOrder=3;
|
||||||
|
|
||||||
Standard_Integer OrderU,OrderV;
|
Standard_Integer OrderU,OrderV;
|
||||||
TColgp_Array2OfVec DerNUV(0,MaxOrder+1,0,MaxOrder+1);
|
TColgp_Array2OfVec DerNUV(0,MaxOrder+1,0,MaxOrder+1);
|
||||||
TColgp_Array2OfVec DerSurf(0,MaxOrder+2,0,MaxOrder+2);
|
TColgp_Array2OfVec DerSurf(0,MaxOrder+2,0,MaxOrder+2);
|
||||||
@ -1799,17 +1860,9 @@ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
|
|||||||
Bounds(Umin,Umax,Vmin,Vmax);
|
Bounds(Umin,Umax,Vmin,Vmax);
|
||||||
DerSurf.SetValue(1, 0, D1U);
|
DerSurf.SetValue(1, 0, D1U);
|
||||||
DerSurf.SetValue(0, 1, D1V);
|
DerSurf.SetValue(0, 1, D1V);
|
||||||
DerSurf.SetValue(1, 1, d2uv);
|
DerSurf.SetValue(1, 1, D2UV);
|
||||||
DerSurf.SetValue(2, 0, d2u);
|
DerSurf.SetValue(2, 0, D2UU);
|
||||||
DerSurf.SetValue(0, 2, d2v);
|
DerSurf.SetValue(0, 2, D2VV);
|
||||||
Handle(Geom_BSplineSurface) L;
|
|
||||||
Standard_Boolean AlongU = Standard_False,
|
|
||||||
AlongV = Standard_False;
|
|
||||||
Standard_Boolean IsOpposite=Standard_False;
|
|
||||||
Standard_Real signe = 1.;
|
|
||||||
AlongU = UOsculatingSurface(U,V,IsOpposite,L);
|
|
||||||
AlongV = VOsculatingSurface(U,V,IsOpposite,L);
|
|
||||||
if ((AlongV || AlongU) && IsOpposite) signe = -1;
|
|
||||||
derivatives(MaxOrder,2,U,V,basisSurf,1,1,AlongU,AlongV,L,DerNUV,DerSurf);
|
derivatives(MaxOrder,2,U,V,basisSurf,1,1,AlongU,AlongV,L,DerNUV,DerSurf);
|
||||||
|
|
||||||
CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
|
CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
|
||||||
@ -1821,7 +1874,6 @@ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
|
|||||||
+ offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
|
+ offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
|
||||||
D1V = DerSurf(0,1)
|
D1V = DerSurf(0,1)
|
||||||
+ offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
|
+ offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
12
tests/bugs/modalg_6/bug26418_1
Normal file
12
tests/bugs/modalg_6/bug26418_1
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC26418"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
#################################################################################
|
||||||
|
# Unjustified limitation on tolerance of a input shape in BRepOffset_MakeOffset
|
||||||
|
#################################################################################
|
||||||
|
|
||||||
|
offsetparameter 1e-7 a i
|
||||||
|
restore [locate_data_file OCC26418-extracted_Plate103contour.brep] sh
|
||||||
|
offsetload sh 10
|
||||||
|
offsetperform r
|
12
tests/bugs/modalg_6/bug26418_2
Normal file
12
tests/bugs/modalg_6/bug26418_2
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC26418"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
#################################################################################
|
||||||
|
# Unjustified limitation on tolerance of a input shape in BRepOffset_MakeOffset
|
||||||
|
#################################################################################
|
||||||
|
|
||||||
|
offsetparameter 1e-7 a i
|
||||||
|
restore [locate_data_file OCC26418-extracted_Plate103contour.brep] sh
|
||||||
|
offsetload sh 16
|
||||||
|
offsetperform r
|
12
tests/bugs/modalg_6/bug26418_3
Normal file
12
tests/bugs/modalg_6/bug26418_3
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC26418"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
#################################################################################
|
||||||
|
# Unjustified limitation on tolerance of a input shape in BRepOffset_MakeOffset
|
||||||
|
#################################################################################
|
||||||
|
|
||||||
|
offsetparameter 1e-7 a i
|
||||||
|
restore [locate_data_file OCC26418-extracted_Plate310contour.brep] sh
|
||||||
|
offsetload sh 10
|
||||||
|
offsetperform r
|
12
tests/bugs/modalg_6/bug26418_4
Normal file
12
tests/bugs/modalg_6/bug26418_4
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC26418"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
#################################################################################
|
||||||
|
# Unjustified limitation on tolerance of a input shape in BRepOffset_MakeOffset
|
||||||
|
#################################################################################
|
||||||
|
|
||||||
|
offsetparameter 1e-7 a i
|
||||||
|
restore [locate_data_file OCC26418-extracted_Plate310contour.brep] sh
|
||||||
|
offsetload sh 15
|
||||||
|
offsetperform r
|
@ -1,10 +1,7 @@
|
|||||||
puts "TODO OCC23068 ALL: An exception was caught"
|
|
||||||
puts "TODO OCC23068 ALL: \\*\\* Exception \\*\\*"
|
|
||||||
puts "TODO OCC23068 ALL: TEST INCOMPLETE"
|
|
||||||
#old file fritesb
|
#old file fritesb
|
||||||
|
|
||||||
restore [locate_data_file fritehaut] s
|
restore [locate_data_file fritehaut] s
|
||||||
OFFSETSHAPE -.004 {s_3} $calcul $type
|
OFFSETSHAPE -.004 {s_3} $calcul $type
|
||||||
|
|
||||||
|
|
||||||
set volume 0
|
set volume 0.000514386
|
||||||
|
Loading…
x
Reference in New Issue
Block a user