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

0026426: Draft angle algorithm modifies input argument + the result of the operation have very large tolerance values

Test-case for issue #26426
This commit is contained in:
ifv
2015-07-17 09:43:21 +03:00
committed by bugmaster
parent e438ef2550
commit 345d30560e
10 changed files with 867 additions and 620 deletions

View File

@@ -54,13 +54,91 @@
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <BRepLib.hxx>
//
static Standard_Real EvalTol(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 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())
{
return 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;
}
}
dmax = 1.2 * Sqrt(dmax);
return dmax;
}
else
{
return 0.;
}
}
}
//=======================================================================
//function : Draft_Modification
//purpose :
//=======================================================================
Draft_Modification::Draft_Modification (const TopoDS_Shape& S) :
myComp(Standard_False),myShape(S)
myComp(Standard_False),myShape(S)
{
TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
}
@@ -103,10 +181,10 @@ void Draft_Modification::Init(const TopoDS_Shape& S)
//=======================================================================
Standard_Boolean Draft_Modification::Add(const TopoDS_Face& F,
const gp_Dir& Direction,
const Standard_Real Angle,
const gp_Pln& NeutralPlane,
const Standard_Boolean Flag)
const gp_Dir& Direction,
const Standard_Real Angle,
const gp_Pln& NeutralPlane,
const Standard_Boolean Flag)
{
if (!badShape.IsNull()) {
Standard_ConstructionError::Raise();
@@ -141,7 +219,7 @@ void Draft_Modification::Remove(const TopoDS_Face& F)
if (myFMap.FindFromKey(theF).RootFace().IsSame(curFace)) {
conneF.Append(theF);
if (theF.IsSame(badShape)) {
badShape.Nullify();
badShape.Nullify();
}
}
}
@@ -167,7 +245,7 @@ void Draft_Modification::Remove(const TopoDS_Face& F)
{
const TopoDS_Edge& theE = myEMap.FindKey(i);
if (myEMap.FindFromKey(theE).RootFace().IsSame(curFace))
conneF.Append(theE);
conneF.Append(theE);
}
ltod.Initialize(conneF);
while (ltod.More()) {
@@ -244,7 +322,7 @@ const TopTools_ListOfShape & Draft_Modification::ConnectedFaces(const TopoDS_Fac
}
return conneF;
}
@@ -270,7 +348,7 @@ const TopTools_ListOfShape & Draft_Modification::ModifiedFaces()
}
return conneF;
}
@@ -281,11 +359,11 @@ const TopTools_ListOfShape & Draft_Modification::ModifiedFaces()
//=======================================================================
Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
Handle(Geom_Surface)& S,
TopLoc_Location& L,
Standard_Real& Tol,
Standard_Boolean& RevWires,
Standard_Boolean& RevFace)
Handle(Geom_Surface)& S,
TopLoc_Location& L,
Standard_Real& Tol,
Standard_Boolean& RevWires,
Standard_Boolean& RevFace)
{
if (!IsDone()) {Standard_DomainError::Raise();}
@@ -305,7 +383,7 @@ Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
return Standard_True;
}
//=======================================================================
//function : NewCurve
@@ -313,19 +391,19 @@ Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
//=======================================================================
Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E,
Handle(Geom_Curve)& C,
TopLoc_Location& L,
Standard_Real& Tol)
Handle(Geom_Curve)& C,
TopLoc_Location& L,
Standard_Real& Tol)
{
if (!IsDone()) {Standard_DomainError::Raise();}
if (!myEMap.Contains(E))
return Standard_False;
const Draft_EdgeInfo& Einf= myEMap.FindFromKey(E);
if (!myEMap.FindFromKey(E).NewGeometry())
return Standard_False;
Tol = Einf.Tolerance();
Tol = Max(Tol, BRep_Tool::Tolerance(E));
L.Identity();
@@ -342,8 +420,8 @@ Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E,
//=======================================================================
Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V,
gp_Pnt& P,
Standard_Real& Tol)
gp_Pnt& P,
Standard_Real& Tol)
{
if (!IsDone()) {Standard_DomainError::Raise();};
@@ -363,24 +441,26 @@ Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V,
//=======================================================================
Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
const TopoDS_Face& F,
const TopoDS_Edge& NewE,
const TopoDS_Face&,
Handle(Geom2d_Curve)& C,
Standard_Real& Tol)
const TopoDS_Face& F,
const TopoDS_Edge& NewE,
const TopoDS_Face&,
Handle(Geom2d_Curve)& C,
Standard_Real& Tol)
{
if (!IsDone()) {Standard_DomainError::Raise();};
if (!myEMap.Contains(E)) {
return Standard_False;
}
Standard_Real Fp,Lp;
BRep_Tool::Range(NewE,Fp,Lp);
Handle(Geom_Surface) SB = myFMap.FindFromKey(F).Geometry();
Tol = BRep_Tool::Tolerance(E);
const Draft_EdgeInfo& Einf = myEMap.FindFromKey(E);
if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
C = Einf.FirstPC();
@@ -389,21 +469,19 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
C = Einf.SecondPC();
}
else {
if (!myEMap.FindFromKey(E).NewGeometry()) {
Standard_Real Fpi,Lpi;
BRep_Tool::Range(E,Fpi,Lpi);
if (Fpi <= Fp && Fp <= Lpi && Fpi <= Lp && Lp <= Lpi) {
return Standard_False;
return Standard_False;
}
}
Tol = BRep_Tool::Tolerance(E);
// if (!BRep_Tool::IsClosed(E,F)) {
BRep_Tool::Range(NewE,Fp,Lp);
Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap.FindFromKey(E).Geometry(),
Fp,Lp);
Fp,Lp);
Fp = TC->FirstParameter();
Lp = TC->LastParameter();
BRep_Builder B;
@@ -426,9 +504,9 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
}
JeRecadre = JeRecadre ||
(typs == STANDARD_TYPE(Geom_CylindricalSurface)) ||
(typs == STANDARD_TYPE(Geom_SphericalSurface)) ||
(typs == STANDARD_TYPE(Geom_ConicalSurface));
(typs == STANDARD_TYPE(Geom_CylindricalSurface)) ||
(typs == STANDARD_TYPE(Geom_SphericalSurface)) ||
(typs == STANDARD_TYPE(Geom_ConicalSurface));
if ( JeRecadre) {
Standard_Boolean bTranslate;
@@ -459,6 +537,15 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
C->Translate(aV2DT);
}
}
//
Handle(Geom_Curve) aC3d = BRep_Tool::Curve(NewE, Fp, Lp);
Standard_Real newtol = EvalTol(aC3d, C, SB, Fp, Lp);
if(newtol > Tol)
{
Tol = newtol;
BRep_Builder B;
B.UpdateEdge(NewE, newtol);
}
return Standard_True;
}
@@ -469,9 +556,9 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
//=======================================================================
Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
const TopoDS_Edge& E,
Standard_Real& P,
Standard_Real& Tol)
const TopoDS_Edge& E,
Standard_Real& P,
Standard_Real& Tol)
{
if (!IsDone()) {Standard_DomainError::Raise();};
@@ -502,24 +589,24 @@ Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
Standard_Real FirstPar = GC->FirstParameter(), LastPar = GC->LastParameter();
Standard_Real pconf = Precision::PConfusion();
if (Abs( paramf - LastPar ) <= pconf)
{
paramf = FirstPar;
FV.Orientation(E.Orientation());
if (V.IsEqual( FV ))
P = paramf;
}
{
paramf = FirstPar;
FV.Orientation(E.Orientation());
if (V.IsEqual( FV ))
P = paramf;
}
FV.Orientation(E.Orientation());
if (!V.IsEqual(FV) && P <= paramf) {
if (GC->IsPeriodic()) {
P += GC->Period();
P += GC->Period();
}
else {
P = GC->LastParameter();
P = GC->LastParameter();
}
}
}
Tol = Max (BRep_Tool::Tolerance(V), BRep_Tool::Tolerance(E));
return Standard_True;
}
@@ -532,13 +619,13 @@ Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
//=======================================================================
GeomAbs_Shape Draft_Modification::Continuity(const TopoDS_Edge& E,
const TopoDS_Face& F1,
const TopoDS_Face& F2,
const TopoDS_Edge&,
const TopoDS_Face&,
const TopoDS_Face&)
const TopoDS_Face& F1,
const TopoDS_Face& F2,
const TopoDS_Edge&,
const TopoDS_Face&,
const TopoDS_Face&)
{
return BRep_Tool::Continuity(E,F1,F2);
}

View File

@@ -1508,6 +1508,7 @@ void Draft_Modification::Perform ()
for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
const TopoDS_Edge& Edg = Vinf.Edge();
Standard_Real initpar = Vinf.Parameter(Edg);
//const Draft_EdgeInfo& Einf = myEMap(Edg);
Draft_EdgeInfo& Einf = myEMap.ChangeFromKey(Edg);
//Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
@@ -1520,7 +1521,19 @@ void Draft_Modification::Perform ()
Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
}
else
{
if(Abs(initpar - param) > Precision::PConfusion())
{
Standard_Real f, l;
TopLoc_Location Loc;
const Handle(Geom_Curve)& aC = BRep_Tool::Curve(Edg, Loc, f, l);
if(aC->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
{
Einf.SetNewGeometry(Standard_True);
}
}
Vinf.ChangeParameter(Edg) = param;
}
}
}
}