1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0024890: Result of uniform scaling is invalid

Test case for issue CR24890
This commit is contained in:
ifv
2015-10-29 15:39:20 +03:00
committed by bugmaster
parent ec7ed71c18
commit 2651bfde07
10 changed files with 377 additions and 108 deletions

View File

@@ -62,7 +62,7 @@
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <errno.h>
//=======================================================================
//function : UVBounds
@@ -948,5 +948,92 @@ Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
return nbocc == 2;
}
//=======================================================================
//function : EvalAndUpdateTol
//purpose :
//=======================================================================
Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
const Handle(Geom_Curve)& C3d,
const Handle(Geom2d_Curve) C2d,
const Handle(Geom_Surface)& S,
const Standard_Real f,
const Standard_Real l)
{
Standard_Real newtol = 0.;
Standard_Real first = f, last = l;
//Set first, last to avoid ErrosStatus = 2 because of
//too strong checking of limits in class CheckCurveOnSurface
//
if(!C3d->IsPeriodic())
{
first = Max(first, C3d->FirstParameter());
last = Min(last, C3d->LastParameter());
}
if(!C2d->IsPeriodic())
{
first = Max(first, C2d->FirstParameter());
last = Min(last, C2d->LastParameter());
}
GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
CT.Perform(C2d);
if(CT.IsDone())
{
newtol = CT.MaxDistance();
}
else
{
if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
(C3d->IsPeriodic() || C2d->IsPeriodic())))
{
//Try to estimate by sample points
Standard_Integer nbint = 22;
Standard_Real dt = (last - first) / nbint;
dt = Max(dt, Precision::Confusion());
Standard_Real d, dmax = 0.;
gp_Pnt2d aP2d;
gp_Pnt aPC, aPS;
Standard_Integer cnt = 0;
Standard_Real t = first;
for(; t <= last; t += dt)
{
cnt++;
C2d->D0(t, aP2d);
C3d->D0(t, aPC);
S->D0(aP2d.X(), aP2d.Y(), aPS);
d = aPS.SquareDistance(aPC);
if(d > dmax)
{
dmax = d;
}
}
if(cnt < nbint + 1)
{
t = last;
C2d->D0(t, aP2d);
C3d->D0(t, aPC);
S->D0(aP2d.X(), aP2d.Y(), aPS);
d = aPS.SquareDistance(aPC);
if(d > dmax)
{
dmax = d;
}
}
newtol = 1.2 * Sqrt(dmax);
}
}
Standard_Real Tol = BRep_Tool::Tolerance(theE);
if(newtol > Tol)
{
Tol = newtol;
BRep_Builder B;
B.UpdateEdge(theE, Tol);
}
return Tol;
}

View File

@@ -52,6 +52,9 @@ class BRepTools_Substitution;
class BRepTools_Quilt;
class BRepTools_ShapeSet;
class BRepTools_ReShape;
class Geom_Curve;
class Geom2d_Curve;
class Geom_Surface;
//! The BRepTools package provides utilities for BRep
@@ -201,6 +204,18 @@ public:
//! <B> is used to build the shape.
Standard_EXPORT static Standard_Boolean Read (TopoDS_Shape& Sh, const Standard_CString File, const BRep_Builder& B, const Handle(Message_ProgressIndicator)& PR = NULL);
//! Evals real tolerance of edge <theE>.
//! <theC3d>, <theC2d>, <theS>, <theF>, <theL> are
//! correspondently 3d curve of edge, 2d curve on surface <theS> and
//! rang of edge
//! If calculated tolerance is more then current edge tolerance, edge is updated.
//! Method returns actual tolerance of edge
Standard_EXPORT static Standard_Real EvalAndUpdateTol(const TopoDS_Edge& theE,
const Handle(Geom_Curve)& theC3d,
const Handle(Geom2d_Curve) theC2d,
const Handle(Geom_Surface)& theS,
const Standard_Real theF,
const Standard_Real theL);

View File

@@ -67,7 +67,8 @@
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <BRep_Builder.hxx>
//
static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
const Standard_Real newU1,
const Standard_Real newU2)
@@ -415,6 +416,12 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
if(isConvert2d) {
Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
return Standard_False;
@@ -457,9 +464,21 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
ProjLib_ComputeApprox ProjOnCurve(G3dAHC,GAHS,Tol);
if(ProjOnCurve.BSpline().IsNull()) {
Curve2d = Geom2dConvert::CurveToBSplineCurve(ProjOnCurve.Bezier());
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
Curve2d = ProjOnCurve.BSpline();
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
@@ -470,10 +489,22 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
if(ProjOnCurve.IsDone()) {
Curve2d = ProjOnCurve.BSpline();
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
else {
Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
}
@@ -506,6 +537,19 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
if(C3d.IsNull()) {
if(isConvert2d) {
Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
Handle(Geom_Surface) S;
if(newF.IsNull())
S = BRep_Tool::Surface(F);
else
S = BRep_Tool::Surface(newF);
//
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
return Standard_False;
@@ -525,6 +569,12 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
if(isConvert2d) {
Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
return Standard_False;
@@ -566,10 +616,22 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
if(ProjOnCurve.IsDone()) {
Curve2d = ProjOnCurve.BSpline();
mylcu.Append(ProjOnCurve.Curve2d());
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
return Standard_True;
}
else {
Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
if(newTol > Tol)
{
Tol = newTol;
myUpdatedEdges.Append(newE);
}
mylcu.Append(C2dBis);
return Standard_True;
}
@@ -643,3 +705,12 @@ GeomAbs_Shape BRepTools_NurbsConvertModification::Continuity
}
//=======================================================================
//function : GetUpdatedEdges
//purpose :
//=======================================================================
const TopTools_ListOfShape&
BRepTools_NurbsConvertModification::GetUpdatedEdges() const
{
return myUpdatedEdges;
}

View File

@@ -102,6 +102,7 @@ public:
//! (resp. <F2>).
Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2, const TopoDS_Edge& NewE, const TopoDS_Face& NewF1, const TopoDS_Face& NewF2);
Standard_EXPORT const TopTools_ListOfShape& GetUpdatedEdges() const;
@@ -118,6 +119,7 @@ private:
TopTools_ListOfShape myled;
TColStd_ListOfTransient mylcu;
TColStd_IndexedDataMapOfTransientTransient myMap;
TopTools_ListOfShape myUpdatedEdges;
};