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 #26426
This commit is contained in:
parent
e438ef2550
commit
345d30560e
src
BRepOffsetAPI
Draft
tests
@ -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,6 +54,84 @@
|
||||
#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
|
||||
@ -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
|
||||
|
||||
|
32
tests/bugs/modalg_6/bug26426
Normal file
32
tests/bugs/modalg_6/bug26426
Normal file
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user