mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56: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);
|
||||
if (TolV > Tol) Tol = TolV;
|
||||
}
|
||||
//Patch
|
||||
Tol *= 5.;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -688,10 +686,9 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
|
||||
// Preanalyse.
|
||||
// ------------
|
||||
EvalMax(myShape,myTol);
|
||||
if (myTol > Abs(myOffset*0.5)) {
|
||||
Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Tol > Offset");
|
||||
}
|
||||
Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
|
||||
// There are possible second variant: analytical continuation of arcsin.
|
||||
Standard_Real TolAngleCoeff = Min(myTol/Abs(myOffset*0.5), 1.0);
|
||||
Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
|
||||
myAnalyse.Perform(myShape,TolAngle);
|
||||
//---------------------------------------------------
|
||||
// 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,
|
||||
const TopoDS_Edge& E2,
|
||||
const TopoDS_Vertex& Vfirst,
|
||||
const TopoDS_Vertex& Vlast,
|
||||
const Standard_Boolean After,
|
||||
const TopoDS_Face& F1,
|
||||
const Standard_Boolean addPCurve1,
|
||||
const TopoDS_Face& F2,
|
||||
const Standard_Boolean addPCurve2)
|
||||
const TopoDS_Edge& E2,
|
||||
const TopoDS_Vertex& Vfirst,
|
||||
const TopoDS_Vertex& Vlast,
|
||||
const Standard_Boolean After,
|
||||
const TopoDS_Face& F1,
|
||||
const Standard_Boolean addPCurve1,
|
||||
const TopoDS_Face& F2,
|
||||
const Standard_Boolean addPCurve2,
|
||||
const Standard_Real theGlueTol)
|
||||
{
|
||||
Standard_Real Tol = 1.e-7;
|
||||
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) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
|
||||
GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
|
||||
Concat.Add( TC2, Precision::Confusion(), After );
|
||||
Concat.Add( TC2, theGlueTol, After );
|
||||
newCurve = Concat.BSplineCurve();
|
||||
if (newCurve->Continuity() < GeomAbs_C1)
|
||||
{
|
||||
@ -1484,6 +1485,7 @@ static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
|
||||
const TopTools_SequenceOfShape& EdgesForConcat)
|
||||
{
|
||||
TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
|
||||
Standard_Real aGlueTol = Precision::Confusion();
|
||||
for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); 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;
|
||||
TopExp::CommonVertex( CurEdge, anEdge, CV );
|
||||
aGlueTol = BRep_Tool::Tolerance(CV);
|
||||
TopExp::Vertices( CurEdge, V11, V12 );
|
||||
TopExp::Vertices( anEdge, V21, V22 );
|
||||
if (V11.IsSame(CV) && V21.IsSame(CV))
|
||||
@ -1532,9 +1535,8 @@ static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
|
||||
}
|
||||
} //end of else (open wire)
|
||||
|
||||
TopoDS_Edge NewEdge = Glue(CurEdge, anEdge,
|
||||
Vfirst, Vlast, After,
|
||||
F1, addPCurve1, F2, addPCurve2);
|
||||
TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
|
||||
F1, addPCurve1, F2, addPCurve2, aGlueTol);
|
||||
CurEdge = NewEdge;
|
||||
} //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
||||
|
||||
|
@ -1767,8 +1767,20 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
|
||||
CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV);
|
||||
if (NStatus == CSLib_Defined)
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1777,21 +1789,70 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V,
|
||||
//function :
|
||||
//purpose : private
|
||||
//=======================================================================/
|
||||
void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V,
|
||||
Pnt& P,
|
||||
Vec& D1U, Vec& D1V,
|
||||
const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const
|
||||
void Geom_OffsetSurface::SetD1(const Standard_Real U,
|
||||
const Standard_Real V,
|
||||
Pnt& P,
|
||||
Vec& D1U, Vec& D1V, // First derivative
|
||||
const Vec& D2UU, const Vec& D2VV, const Vec& D2UV ) const // Second derivative
|
||||
{
|
||||
|
||||
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;
|
||||
CSLib_NormalStatus NStatus;
|
||||
CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal);
|
||||
Standard_Integer MaxOrder;
|
||||
if (NStatus == CSLib_Defined)
|
||||
{
|
||||
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
|
||||
MaxOrder=3;
|
||||
|
||||
Standard_Integer OrderU,OrderV;
|
||||
TColgp_Array2OfVec DerNUV(0,MaxOrder+1,0,MaxOrder+1);
|
||||
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);
|
||||
DerSurf.SetValue(1, 0, D1U);
|
||||
DerSurf.SetValue(0, 1, D1V);
|
||||
DerSurf.SetValue(1, 1, d2uv);
|
||||
DerSurf.SetValue(2, 0, d2u);
|
||||
DerSurf.SetValue(0, 2, d2v);
|
||||
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;
|
||||
DerSurf.SetValue(1, 1, D2UV);
|
||||
DerSurf.SetValue(2, 0, D2UU);
|
||||
DerSurf.SetValue(0, 2, D2VV);
|
||||
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);
|
||||
@ -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);
|
||||
D1V = DerSurf(0,1)
|
||||
+ 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
|
||||
|
||||
restore [locate_data_file fritehaut] s
|
||||
OFFSETSHAPE -.004 {s_3} $calcul $type
|
||||
|
||||
|
||||
set volume 0
|
||||
set volume 0.000514386
|
||||
|
Loading…
x
Reference in New Issue
Block a user