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

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

Test-case for issue 
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

@ -251,6 +251,23 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shap
return myGenerated;
}
//=======================================================================
//function : ModifiedShape
//purpose :
//=======================================================================
TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape
(const TopoDS_Shape& S) const
{
if(S.ShapeType() == TopAbs_VERTEX)
{
if(myVtxToReplace.IsBound(S))
{
return myVtxToReplace(S);
}
}
return myModifier.ModifiedShape(S);
}
//=======================================================================
//function : Build
@ -265,9 +282,8 @@ void BRepOffsetAPI_DraftAngle::Build()
}
else {
DoModif(myInitialShape);
//BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
CorrectWires();
BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
CorrectVertexTol();
}
}
@ -872,3 +888,91 @@ void BRepOffsetAPI_DraftAngle::CorrectWires()
}
}
}
//=======================================================================
//function : CorrectVertexTol
//purpose :
//=======================================================================
void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
{
TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges;
TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE);
for(; anExp.More(); anExp.Next())
{
anInitEdges.Add(anExp.Current());
TopoDS_Iterator anIter(anExp.Current());
for(; anIter.More(); anIter.Next())
{
anInitVertices.Add(anIter.Value());
}
}
//
BRep_Builder aBB;
myVtxToReplace.Clear();
anExp.Init(myShape, TopAbs_EDGE);
for(; anExp.More(); anExp.Next())
{
const TopoDS_Shape& anE = anExp.Current();
//Skip old (not modified) edges
if(anInitEdges.Contains(anE))
continue;
//
//Skip processed edges
if(aNewEdges.Contains(anE))
continue;
//
aNewEdges.Add(anE);
//
Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
TopoDS_Iterator anIter(anE);
for(; anIter.More(); anIter.Next())
{
const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
if(anInitVertices.Contains(aVtx))
{
if(myVtxToReplace.IsBound(aVtx))
{
aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
}
else
{
Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
if(aVTol < anETol)
{
TopoDS_Vertex aNewVtx;
gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
myVtxToReplace.Bind(aVtx, aNewVtx);
}
}
}
else
{
aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
}
}
}
//
if(myVtxToReplace.IsEmpty())
{
return;
}
//
BRepTools_Substitution aSub;
TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
for(; anIter.More(); anIter.Next())
{
TopTools_ListOfShape aSubVtx;
aSubVtx.Append(anIter.Value());
aSub.Substitute(anIter.Key(), aSubVtx);
}
aSub.Build( myShape );
if (aSub.IsCopied( myShape ))
{
const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
if (! listSh.IsEmpty())
myShape = listSh.First();
}
//
}

@ -22,6 +22,7 @@
#include <Standard_Handle.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <BRepBuilderAPI_ModifyShape.hxx>
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
@ -185,6 +186,14 @@ public:
//! <S>.
Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& S) Standard_OVERRIDE;
//! Returns the modified shape corresponding to <S>.
//! S can correspond to the entire initial shape or to its subshape.
//! Raises exceptions
//! Standard_NoSuchObject if S is not the initial shape or
//! a subshape of the initial shape to which the
//! transformation has been applied.
Standard_EXPORT virtual TopoDS_Shape ModifiedShape (const TopoDS_Shape& S) const Standard_OVERRIDE;
@ -196,10 +205,9 @@ protected:
private:
Standard_EXPORT void CorrectVertexTol();
TopTools_ListOfShape myModifiedShapes;
TopTools_DataMapOfShapeShape myVtxToReplace;
};

@ -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);
}
@ -381,6 +459,8 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
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();
@ -398,8 +478,6 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
}
}
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(),
@ -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;
}

@ -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,10 +1521,22 @@ 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;
}
}
}
}
// small loop of validation/protection

@ -0,0 +1,32 @@
puts "========"
puts "OCC26426"
puts "========"
puts ""
################################################################################################################
# Draft angle algorithm modifies input argument + the result of the operation have very large tolerance values
################################################################################################################
restore [locate_data_file OCC26426-prism_shape.brep] b
set bug_info_0 [tolerance b]
set bug_info_0 [lindex $bug_info_0 1]
set bug_info_0 [string trim [string range $bug_info_0 [expr {[string first "=" $bug_info_0] + 1}] [expr {[string length $bug_info_0] - 1}]]]
explode b f
depouille r b 0 0 -1 b_1 -10 0 0 -40 0 0 1
set bug_info_1 [tolerance b]
set bug_info_1 [lindex $bug_info_1 1]
set bug_info_1 [string trim [string range $bug_info_1 [expr {[string first "=" $bug_info_1] + 1}] [expr {[string length $bug_info_1] - 1}]]]
set bug_info_2 [tolerance r]
set bug_info_2 [lindex $bug_info_2 1]
set bug_info_2 [string trim [string range $bug_info_2 [expr {[string first "=" $bug_info_2] + 1}] [expr {[string length $bug_info_2] - 1}]]]
if {$bug_info_0 < $bug_info_1} {
puts "ERROR: OCC26426 is reproduced. Tolerance has been increased (case 1)."
}
if {[expr {$bug_info_0 + 0.0000001}] < $bug_info_2} {
puts "ERROR: OCC26426 is reproduced. Tolerance has been increased (case 2)."
}

@ -1,5 +1,7 @@
#E6----------------------------------------------
puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_"
#puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC26426 ALL: Error: The tolerance of the resulting shape is too big "
ptorus pt 25 24 90
profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \

@ -1,5 +1,5 @@
#C5----------------------------------------------
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6"
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
plane ps 10 -3 0 1 0 0 0 .2 1
psphere ps ps 20

@ -1,5 +1,5 @@
#D3---------------------------------------------
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6"
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC22803 Linux Windows: Error : The area of the resulting shape is"
plane pt 0 0 0 1 0 0

@ -1,8 +1,9 @@
# Original bug : pro12877
# Date : 02 Dec 98
puts "TODO OCC22803 All: Error: The tolerance of the resulting shape is too big"
#puts "TODO OCC22803 All: Error: The tolerance of the resulting shape is too big"
#puts "TODO OCC23511 Linux: The area of the resulting shape is 186543"
puts "TODO OCC26426 All: Faulty shapes in variables faulty_1 to faulty_"
restore [locate_data_file CFE903_pro12ggx.rle] base

@ -1,7 +1,7 @@
# Original bug : pro16449
# Date : 18 Dec 98
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_4"
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
restore [locate_data_file CFE903_pro16gha.rle] base