mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +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
@ -251,6 +251,23 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shap
|
|||||||
return myGenerated;
|
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
|
//function : Build
|
||||||
@ -265,9 +282,8 @@ void BRepOffsetAPI_DraftAngle::Build()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DoModif(myInitialShape);
|
DoModif(myInitialShape);
|
||||||
//BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
|
|
||||||
CorrectWires();
|
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 <Standard_Handle.hxx>
|
||||||
|
|
||||||
#include <TopTools_ListOfShape.hxx>
|
#include <TopTools_ListOfShape.hxx>
|
||||||
|
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||||
#include <BRepBuilderAPI_ModifyShape.hxx>
|
#include <BRepBuilderAPI_ModifyShape.hxx>
|
||||||
#include <Standard_Real.hxx>
|
#include <Standard_Real.hxx>
|
||||||
#include <Standard_Boolean.hxx>
|
#include <Standard_Boolean.hxx>
|
||||||
@ -185,6 +186,14 @@ public:
|
|||||||
//! <S>.
|
//! <S>.
|
||||||
Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& S) Standard_OVERRIDE;
|
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:
|
private:
|
||||||
|
|
||||||
|
Standard_EXPORT void CorrectVertexTol();
|
||||||
|
|
||||||
|
TopTools_DataMapOfShapeShape myVtxToReplace;
|
||||||
TopTools_ListOfShape myModifiedShapes;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,13 +54,91 @@
|
|||||||
#include <TopoDS_Shape.hxx>
|
#include <TopoDS_Shape.hxx>
|
||||||
#include <TopoDS_Vertex.hxx>
|
#include <TopoDS_Vertex.hxx>
|
||||||
#include <TopTools_ListIteratorOfListOfShape.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
|
//function : Draft_Modification
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Draft_Modification::Draft_Modification (const TopoDS_Shape& S) :
|
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);
|
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();
|
Handle(Geom_Surface) SB = myFMap.FindFromKey(F).Geometry();
|
||||||
|
|
||||||
|
Tol = BRep_Tool::Tolerance(E);
|
||||||
|
|
||||||
const Draft_EdgeInfo& Einf = myEMap.FindFromKey(E);
|
const Draft_EdgeInfo& Einf = myEMap.FindFromKey(E);
|
||||||
if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
|
if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
|
||||||
C = Einf.FirstPC();
|
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)) {
|
// if (!BRep_Tool::IsClosed(E,F)) {
|
||||||
BRep_Tool::Range(NewE,Fp,Lp);
|
BRep_Tool::Range(NewE,Fp,Lp);
|
||||||
Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap.FindFromKey(E).Geometry(),
|
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);
|
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;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1508,6 +1508,7 @@ void Draft_Modification::Perform ()
|
|||||||
|
|
||||||
for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
|
for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
|
||||||
const TopoDS_Edge& Edg = Vinf.Edge();
|
const TopoDS_Edge& Edg = Vinf.Edge();
|
||||||
|
Standard_Real initpar = Vinf.Parameter(Edg);
|
||||||
//const Draft_EdgeInfo& Einf = myEMap(Edg);
|
//const Draft_EdgeInfo& Einf = myEMap(Edg);
|
||||||
Draft_EdgeInfo& Einf = myEMap.ChangeFromKey(Edg);
|
Draft_EdgeInfo& Einf = myEMap.ChangeFromKey(Edg);
|
||||||
//Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
|
//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 );
|
Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
|
||||||
}
|
}
|
||||||
else
|
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;
|
Vinf.ChangeParameter(Edg) = param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// small loop of validation/protection
|
// 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----------------------------------------------
|
#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
|
ptorus pt 25 24 90
|
||||||
profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \
|
profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#C5----------------------------------------------
|
#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
|
plane ps 10 -3 0 1 0 0 0 .2 1
|
||||||
psphere ps ps 20
|
psphere ps ps 20
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#D3---------------------------------------------
|
#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"
|
puts "TODO OCC22803 Linux Windows: Error : The area of the resulting shape is"
|
||||||
|
|
||||||
plane pt 0 0 0 1 0 0
|
plane pt 0 0 0 1 0 0
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
# Original bug : pro12877
|
# Original bug : pro12877
|
||||||
# Date : 02 Dec 98
|
# 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 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
|
restore [locate_data_file CFE903_pro12ggx.rle] base
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Original bug : pro16449
|
# Original bug : pro16449
|
||||||
# Date : 18 Dec 98
|
# 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
|
restore [locate_data_file CFE903_pro16gha.rle] base
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user