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