From 6e8ab7b8af3005cd0f062d6bf098274603e0e107 Mon Sep 17 00:00:00 2001 From: nbv Date: Tue, 3 Dec 2013 16:05:46 +0400 Subject: [PATCH] 0023731: The shape obtained by stepread is valid in terms of checkshape but it is not valid in terms of usability. 1. New status "BrepCheck_CollapsedEdge" is added. 2. Draw command "tolsphere": draws a sphere with center in given vertex, radius is tolerance of given vertex. 3. test case added 4. Small correction of output of "checkshape" command result. --- src/BRepCheck/BRepCheck.cdl | 1 + src/BRepCheck/BRepCheck.cxx | 7 + src/BRepCheck/BRepCheck_Analyzer.cxx | 562 +++++++++++--------- src/BRepCheck/BRepCheck_Edge.cdl | 15 +- src/BRepCheck/BRepCheck_Edge.cxx | 151 +++++- src/BRepCheck/BRepCheck_Face.cdl | 7 + src/BRepCheck/BRepCheck_Face.cxx | 9 + src/BRepCheck/BRepCheck_Wire.cdl | 6 + src/BRepCheck/BRepCheck_Wire.cxx | 11 + src/BRepTest/BRepTest_CheckCommands.cxx | 143 ++--- src/BRepTest/BRepTest_PrimitiveCommands.cxx | 79 +++ tests/bugs/modalg_5/bug23731 | 24 + 12 files changed, 687 insertions(+), 328 deletions(-) create mode 100644 tests/bugs/modalg_5/bug23731 diff --git a/src/BRepCheck/BRepCheck.cdl b/src/BRepCheck/BRepCheck.cdl index 9928b17c7e..75fe1239e5 100755 --- a/src/BRepCheck/BRepCheck.cdl +++ b/src/BRepCheck/BRepCheck.cdl @@ -72,6 +72,7 @@ is InvalidSameRangeFlag, InvalidSameParameterFlag, InvalidDegeneratedFlag, + CollapsedEdge, FreeEdge, InvalidMultiConnexity, diff --git a/src/BRepCheck/BRepCheck.cxx b/src/BRepCheck/BRepCheck.cxx index 1eecf255d7..8f62271cb6 100755 --- a/src/BRepCheck/BRepCheck.cxx +++ b/src/BRepCheck/BRepCheck.cxx @@ -181,6 +181,13 @@ void BRepCheck::Print(const BRepCheck_Status stat, case BRepCheck_CheckFail: OS << "BRepCheck_CheckFail\n"; break; + case BRepCheck_CollapsedEdge: + OS << "BRepCheck_CollapsedEdge\n"; + break; + case BRepCheck_InvalidToleranceValue: + OS << "BRepCheck_InvalidToleranceValue\n"; + break; + default: break; } diff --git a/src/BRepCheck/BRepCheck_Analyzer.cxx b/src/BRepCheck/BRepCheck_Analyzer.cxx index 3e13829679..45fd7a4196 100755 --- a/src/BRepCheck/BRepCheck_Analyzer.cxx +++ b/src/BRepCheck/BRepCheck_Analyzer.cxx @@ -109,15 +109,17 @@ void BRepCheck_Analyzer::Put(const TopoDS_Shape& S, void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S) { - for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) { + for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) Perform(theIterator.Value()); - } + // TopAbs_ShapeEnum styp; TopExp_Explorer exp; // styp = S.ShapeType(); - switch (styp) { + + switch (styp) + { case TopAbs_VERTEX: // modified by NIZHNY-MKK Wed May 19 16:56:16 2004.BEGIN // There is no need to check anything. @@ -127,306 +129,376 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S) // modified by NIZHNY-MKK Wed May 19 16:56:23 2004.END break; - case TopAbs_EDGE: { - // Modified by skv - Tue Apr 27 11:38:08 2004 Begin - // There is no need to check anything except vertices on single edge. - // if (myShape.IsSame(S)) { - // myMap(S)->Blind(); - // } - // Modified by skv - Tue Apr 27 11:38:09 2004 End - TopTools_MapOfShape MapS; - - for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) { - const TopoDS_Shape& aVertex = exp.Current(); - try { - OCC_CATCH_SIGNALS - if (MapS.Add(aVertex)) { - myMap(aVertex)->InContext(S); - } + case TopAbs_EDGE: + { + Handle(BRepCheck_Result)& aRes = myMap(S); + + try + { + BRepCheck_Status ste = Handle(BRepCheck_Edge):: + DownCast(aRes)->CheckTolerance(TopoDS::Edge(S)); + + if(ste != BRepCheck_NoError) + { + Handle(BRepCheck_Edge)::DownCast(aRes)->SetStatus(ste); + break; + } } - catch(Standard_Failure) { + catch(Standard_Failure) + { #ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<Print(cout); + cout<SetFailStatus(S); - } - Handle(BRepCheck_Result) aRes = myMap(aVertex); - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(aVertex); - aRes->SetFailStatus(S); - } + if ( ! myMap(S).IsNull() ) + { + myMap(S)->SetFailStatus(S); + } + + if ( ! aRes.IsNull() ) + { + aRes->SetFailStatus(exp.Current()); + aRes->SetFailStatus(S); + } } - } + + TopTools_MapOfShape MapS; + + for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) + { + const TopoDS_Shape& aVertex = exp.Current(); + try + { + OCC_CATCH_SIGNALS + if (MapS.Add(aVertex)) + myMap(aVertex)->InContext(S); + } + catch(Standard_Failure) + { +#ifdef DEB + cout<<"BRepCheck_Analyzer : "; + Standard_Failure::Caught()->Print(cout); + cout<SetFailStatus(S); + + Handle(BRepCheck_Result) aRes = myMap(aVertex); + + if ( ! aRes.IsNull() ) + { + aRes->SetFailStatus(aVertex); + aRes->SetFailStatus(S); + } + }//catch(Standard_Failure) + }//for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) } break; case TopAbs_WIRE: - // Modified by Sergey KHROMOV - Mon May 6 15:53:39 2002 Begin - // There is no need to check the orientation of a single wire - // (not in context of face). - // { - // if (myShape.IsSame(S)) { - // Handle(BRepCheck_Wire)::DownCast(myMap(S))->Orientation(TopoDS_Face(), - // Standard_True); - // } - // } - // Modified by Sergey KHROMOV - Mon May 6 15:53:40 2002 End + { +// TopTools_MapOfShape MapS; +// Standard_Boolean InvalidTolerance = Standard_False; +// +// for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next()) +// { +// try +// { +// OCC_CATCH_SIGNALS +// +// if (MapS.Add(exp.Current())) +// { +// Handle(BRepCheck_Result)& res = myMap(exp.Current()); +// res->InContext(S); +// for (res->InitContextIterator(); +// res->MoreShapeInContext(); +// res->NextShapeInContext()) +// { +// if(res->ContextualShape().IsSame(S)) +// break; +// } +// +// BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); +// for (; itl.More(); itl.Next()) +// { +// BRepCheck_Status ste = itl.Value(); +// if(ste == BRepCheck_CollapsedEdge) +// { +// InvalidTolerance = Standard_True; +// break; +// } +// }//for (; itl.More(); itl.Next()) +// }//if (MapS.Add(exp.Current())) +// } +// catch(Standard_Failure) +// { +//#ifdef DEB +// cout<<"BRepCheck_Analyzer : "; +// Standard_Failure::Caught()->Print(cout); +// cout<SetFailStatus(S); +// +// Handle(BRepCheck_Result) aRes = myMap(exp.Current()); +// +// if ( ! aRes.IsNull() ) +// { +// aRes->SetFailStatus(exp.Current()); +// aRes->SetFailStatus(S); +// } +// }//catch(Standard_Failure) +// }//for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next()) +// +// if (InvalidTolerance) +// Handle(BRepCheck_Wire)::DownCast(myMap(S))-> +// SetStatus(BRepCheck_InvalidToleranceValue); + } break; case TopAbs_FACE: { TopTools_MapOfShape MapS; - for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) { - try { - OCC_CATCH_SIGNALS - if (MapS.Add(exp.Current())) { - myMap(exp.Current())->InContext(S); - } - } - catch(Standard_Failure) { + for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next()) + { + try + { + OCC_CATCH_SIGNALS + if (MapS.Add(exp.Current())) + { + myMap(exp.Current())->InContext(S); + } + } + catch(Standard_Failure) + { #ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<Print(cout); + cout<SetFailStatus(S); - } - Handle(BRepCheck_Result) aRes = myMap(exp.Current()); + if ( ! myMap(S).IsNull() ) + { + myMap(S)->SetFailStatus(S); + } + + Handle(BRepCheck_Result) aRes = myMap(exp.Current()); - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(exp.Current()); - aRes->SetFailStatus(S); - } - } + if ( ! aRes.IsNull() ) + { + aRes->SetFailStatus(exp.Current()); + aRes->SetFailStatus(S); + } + } } + Standard_Boolean performwire = Standard_True; + Standard_Boolean isInvalidTolerance = Standard_False; MapS.Clear(); - for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next()) { - try { - OCC_CATCH_SIGNALS - if (MapS.Add(exp.Current())) { - Handle(BRepCheck_Result)& res = myMap(exp.Current()); - res->InContext(S); - if (performwire) { - for (res->InitContextIterator(); - res->MoreShapeInContext(); - res->NextShapeInContext()) { - if(res->ContextualShape().IsSame(S)) { - break; - } - } - BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); - for (; itl.More(); itl.Next()) { - BRepCheck_Status ste = itl.Value(); - if (ste == BRepCheck_NoCurveOnSurface || - ste == BRepCheck_InvalidCurveOnSurface || - ste == BRepCheck_InvalidRange || - ste == BRepCheck_InvalidCurveOnClosedSurface) { - performwire = Standard_False; - break; - } - } - } - } - } - catch(Standard_Failure) { + for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next()) + { + try + { + OCC_CATCH_SIGNALS + if (MapS.Add(exp.Current())) + { + Handle(BRepCheck_Result)& res = myMap(exp.Current()); + res->InContext(S); + if (performwire) + { + for ( res->InitContextIterator(); + res->MoreShapeInContext(); + res->NextShapeInContext()) + { + if(res->ContextualShape().IsSame(S)) + break; + } + + BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); + for (; itl.More(); itl.Next()) + { + BRepCheck_Status ste = itl.Value(); + if (ste == BRepCheck_NoCurveOnSurface || + ste == BRepCheck_InvalidCurveOnSurface || + ste == BRepCheck_InvalidRange || + ste == BRepCheck_InvalidCurveOnClosedSurface) + { + performwire = Standard_False; + break; + } + + //if(ste == BRepCheck_CollapsedEdge) + //{ + // isInvalidTolerance = Standard_True; + // break; + //} + } + } + } + } + catch(Standard_Failure) + { #ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<Print(cout); + cout<SetFailStatus(S); + } - if ( ! myMap(S).IsNull() ) { - myMap(S)->SetFailStatus(S); - } - Handle(BRepCheck_Result) aRes = myMap(exp.Current()); + Handle(BRepCheck_Result) aRes = myMap(exp.Current()); - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(exp.Current()); - aRes->SetFailStatus(S); - } - } + if ( ! aRes.IsNull() ) + { + aRes->SetFailStatus(exp.Current()); + aRes->SetFailStatus(S); + } + } } + Standard_Boolean orientofwires = performwire; - for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next()) { - try { - OCC_CATCH_SIGNALS - Handle(BRepCheck_Result)& res = myMap(exp.Current()); - res->InContext(S); - if (orientofwires) { - for (res->InitContextIterator(); - res->MoreShapeInContext(); - res->NextShapeInContext()) { - if(res->ContextualShape().IsSame(S)) { - break; - } - } - BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); - for (; itl.More(); itl.Next()) { - BRepCheck_Status ste = itl.Value(); - if (ste != BRepCheck_NoError) { - orientofwires = Standard_False; - break; - } - } - } - } - catch(Standard_Failure) { + for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next()) + { + try + { + OCC_CATCH_SIGNALS + Handle(BRepCheck_Result)& res = myMap(exp.Current()); + res->InContext(S); + if (orientofwires) + { + for ( res->InitContextIterator(); + res->MoreShapeInContext(); + res->NextShapeInContext()) + { + if(res->ContextualShape().IsSame(S)) + { + break; + } + } + BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape()); + for (; itl.More(); itl.Next()) + { + BRepCheck_Status ste = itl.Value(); + if (ste != BRepCheck_NoError) + { + orientofwires = Standard_False; + break; + } + } + } + } + catch(Standard_Failure) + { #ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<Print(cout); + cout<SetFailStatus(S); - } - Handle(BRepCheck_Result) aRes = myMap(exp.Current()); + if ( ! myMap(S).IsNull() ) + { + myMap(S)->SetFailStatus(S); + } - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(exp.Current()); - aRes->SetFailStatus(S); - } - } + Handle(BRepCheck_Result) aRes = myMap(exp.Current()); + + if ( ! aRes.IsNull() ) + { + aRes->SetFailStatus(exp.Current()); + aRes->SetFailStatus(S); + } + } } - - try { + + try + { OCC_CATCH_SIGNALS - if (performwire) { - if (orientofwires) { - Handle(BRepCheck_Face)::DownCast(myMap(S))-> - OrientationOfWires(Standard_True);// on enregistre - } - // else { - // Handle(BRepCheck_Face)::DownCast(myMap(S))-> - // IntersectWires(Standard_True); // on enregistre - // } - else { - Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable(); - } - } - else { - Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable(); - } + if(isInvalidTolerance) + { + Handle(BRepCheck_Face):: + DownCast(myMap(S))->SetStatus(BRepCheck_InvalidToleranceValue); + } + else if (performwire) + { + if (orientofwires) + { + Handle(BRepCheck_Face)::DownCast(myMap(S))-> + OrientationOfWires(Standard_True);// on enregistre + } + else + { + Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable(); + } + } + else + { + Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable(); + } } - catch(Standard_Failure) { + catch(Standard_Failure) + { #ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<Print(cout); + cout<SetFailStatus(S); + } - if ( ! myMap(S).IsNull() ) { - myMap(S)->SetFailStatus(S); - } - - for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next()) { - Handle(BRepCheck_Result) aRes = myMap(exp.Current()); - - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(exp.Current()); - aRes->SetFailStatus(S); - myMap(S)->SetFailStatus(exp.Current()); - } - } + for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next()) + { + Handle(BRepCheck_Result) aRes = myMap(exp.Current()); + + if ( ! aRes.IsNull() ) + { + aRes->SetFailStatus(exp.Current()); + aRes->SetFailStatus(S); + myMap(S)->SetFailStatus(exp.Current()); + } + } } } break; case TopAbs_SHELL: //modified by NIZNHY-PKV Mon Oct 13 14:23:53 2008f - /* { - Standard_Boolean VerifyOrientation, bFlag; - // - VerifyOrientation = Standard_True; - // - exp.Init(S,TopAbs_FACE); - for (; exp.More(); exp.Next()) { - const TopoDS_Shape& aF=exp.Current(); - try { - OCC_CATCH_SIGNALS - bFlag= !(Handle(BRepCheck_Face)::DownCast(myMap(aF))->IsUnorientable()); - VerifyOrientation = (VerifyOrientation && bFlag); - } - catch(Standard_Failure) { -#ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<SetFailStatus(S); - } - Handle(BRepCheck_Result) aRes = myMap(exp.Current()); - - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(exp.Current()); - aRes->SetFailStatus(S); - } - } - } // - try { - OCC_CATCH_SIGNALS - if (VerifyOrientation) { - Handle(BRepCheck_Shell)::DownCast(myMap(S))->Orientation(Standard_True); - } - else { - Handle(BRepCheck_Shell)::DownCast(myMap(S))->SetUnorientable(); - } - } - catch(Standard_Failure) { -#ifdef DEB - cout<<"BRepCheck_Analyzer : "; - Standard_Failure::Caught()->Print(cout); - cout<SetFailStatus(S); - } - exp.Init(S,TopAbs_FACE); - for (; exp.More(); exp.Next()) { - Handle(BRepCheck_Result) aRes = myMap(exp.Current()); - if ( ! aRes.IsNull() ) { - aRes->SetFailStatus(exp.Current()); - aRes->SetFailStatus(S); - myMap(S)->SetFailStatus(exp.Current()); - } - } - } - } - */ //modified by NIZNHY-PKV Mon Oct 13 14:24:04 2008t break; - // - case TopAbs_SOLID: { + + case TopAbs_SOLID: + { exp.Init(S,TopAbs_SHELL); - for (; exp.More(); exp.Next()) { + for (; exp.More(); exp.Next()) + { const TopoDS_Shape& aShell=exp.Current(); - try { + try + { OCC_CATCH_SIGNALS myMap(aShell)->InContext(S); } - catch(Standard_Failure) { + catch(Standard_Failure) + { #ifdef DEB cout<<"BRepCheck_Analyzer : "; Standard_Failure::Caught()->Print(cout); cout<SetFailStatus(S); } + // Handle(BRepCheck_Result) aRes = myMap(aShell); - if (!aRes.IsNull() ) { + if (!aRes.IsNull() ) + { aRes->SetFailStatus(exp.Current()); aRes->SetFailStatus(S); } + }//catch(Standard_Failure) + }//for (; exp.More(); exp.Next()) } - } - } break;//case TopAbs_SOLID default: break; diff --git a/src/BRepCheck/BRepCheck_Edge.cdl b/src/BRepCheck/BRepCheck_Edge.cdl index ca806530a8..a344b07de0 100755 --- a/src/BRepCheck/BRepCheck_Edge.cdl +++ b/src/BRepCheck/BRepCheck_Edge.cdl @@ -27,7 +27,8 @@ class Edge from BRepCheck inherits Result from BRepCheck uses Shape from TopoDS, Edge from TopoDS, CurveRepresentation from BRep, - HCurve from Adaptor3d + HCurve from Adaptor3d, + Status from BRepCheck is @@ -61,6 +62,18 @@ is is static; + SetStatus(me: mutable; + theStatus:Status from BRepCheck) + + --- Purpose: Sets status of Edge; + is static; + + CheckTolerance(me: mutable; theEdge: Edge from TopoDS) + --- Purpose: Checks, if tolerance of vertexes overlaps + -- theEdge; + returns Status from BRepCheck + is static; + fields myCref : CurveRepresentation from BRep; diff --git a/src/BRepCheck/BRepCheck_Edge.cxx b/src/BRepCheck/BRepCheck_Edge.cxx index efe5ace99e..f7d86d1c6f 100755 --- a/src/BRepCheck/BRepCheck_Edge.cxx +++ b/src/BRepCheck/BRepCheck_Edge.cxx @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -37,6 +39,7 @@ #include +#include #include #include @@ -61,8 +64,22 @@ #include #include #include +#include #include +//Golden ratio +static const Standard_Real GoldRatio = (sqrt(5.0)-1)/2.0; + +static const Standard_Real DivPoints[] = { + GoldRatio, + 1.0-GoldRatio, + 4.0*GoldRatio-2.0, + 3.0-4.0*GoldRatio, + 0.5 + }; + +static const Standard_Integer maxNIter = sizeof(DivPoints)/sizeof(DivPoints[0]); + //modified by NIZNHY-PKV Thu May 05 09:01:57 2011f static @@ -70,6 +87,7 @@ static const Adaptor3d_CurveOnSurface&, const Standard_Real, const Standard_Boolean); + static void PrintProblematicPoint(const gp_Pnt&, const Standard_Real, @@ -89,7 +107,7 @@ static // const Standard_Boolean); //modified by NIZNHY-PKV Thu May 05 09:02:01 2011t -#define NCONTROL 23 +static const Standard_Integer NCONTROL=23; //======================================================================= //function : BRepCheck_Edge @@ -242,12 +260,24 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) return; } - switch (styp) { + switch (styp) + { + case TopAbs_WIRE: + { + //if (CheckTolerance(TopoDS::Edge(myShape)) == BRepCheck_CollapsedEdge) + //{ + // BRepCheck::Add(lst,BRepCheck_CollapsedEdge); + // return; + //} + } + break; + case TopAbs_FACE: if (!myCref.IsNull()) { Standard_Boolean SameParameter = TE->SameParameter(); Standard_Boolean SameRange = TE->SameRange(); + // Modified by skv - Tue Apr 27 11:48:13 2004 Begin if (!SameParameter || !SameRange) { if (!SameParameter) @@ -279,8 +309,8 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) // gka OCC // Modified by skv - Tue Apr 27 11:50:35 2004 Begin // if (SameRange && (fabs(f-First) > Precision::PConfusion() || fabs(l-Last)> Precision::PConfusion())) { //f != First || l != Last)) { gka OCC - if (fabs(f-First) > Precision::PConfusion() || - fabs(l-Last) > Precision::PConfusion()) { + if (Abs(f-First) > Precision::PConfusion() || + Abs(l-Last) > Precision::PConfusion()) { BRepCheck::Add(lst,BRepCheck_InvalidSameRangeFlag); BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); // if (SameParameter) { @@ -455,6 +485,16 @@ Standard_Boolean BRepCheck_Edge::GeometricControls() const return myGctrl; } +//======================================================================= +//function : SetStatus +//purpose : +//======================================================================= + +void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus) +{ + BRepCheck::Add(myMap(myShape),theStatus); +} + @@ -554,6 +594,86 @@ Standard_Real BRepCheck_Edge::Tolerance() return sqrt(tolCal)*1.05; } +//======================================================================= +//function : CheckTolerance +//purpose : Cheks, if theEdge lies entirely into sphere, center of which +// is middle point of line segment, which joins first and last +// vertex of an edge, and radius is aTol (see function's body). +//======================================================================= +BRepCheck_Status BRepCheck_Edge::CheckTolerance(const TopoDS_Edge& theEdge) +{ + BRepCheck_Status aStatus = BRepCheck_NoError; + Standard_Real aTol1 = 1.0e-7, aTol2 = 1.0e-7; + + if(BRep_Tool::Degenerated(theEdge)) + { + aStatus = BRepCheck_NoError; + return aStatus; + } + + TopoDS_Vertex aV1 = TopExp::FirstVertex(theEdge), + aV2 = TopExp::LastVertex(theEdge); + + if(aV2.IsNull() || aV1.IsNull()) + { + aStatus = BRepCheck_NoError; + return aStatus; + } + + gp_Pnt aPnt1, aPnt2; + + aPnt1 = BRep_Tool::Pnt(aV1); + aPnt2 = BRep_Tool::Pnt(aV2); + + aTol1 = BRep_Tool::Tolerance(aV1); + aTol2 = BRep_Tool::Tolerance(aV2); + + if( Precision::IsInfinite(aTol1) || + Precision::IsInfinite(aTol2)) + { + aStatus = BRepCheck_CollapsedEdge; + return aStatus; + } + + Standard_Real st = aTol1 + aTol2; + + if(aPnt1.SquareDistance(aPnt2) >= st*st) + { + aStatus = BRepCheck_NoError; + return aStatus; + } + + gp_Pnt aPn( (aPnt1.X() + aPnt2.X())/2.0, + (aPnt1.Y() + aPnt2.Y())/2.0, + (aPnt1.Z() + aPnt2.Z())/2.0); + + + const Standard_Real aTol = Max(aTol1,aTol2) + aPnt1.Distance(aPnt2)/2.0; + const Standard_Real aTols = aTol*aTol; + + BRepAdaptor_Curve BACurve(theEdge); + + const Standard_Real aFirst = BACurve.FirstParameter(), + aLast = BACurve.LastParameter(); + + const Standard_Real dParam = aLast - aFirst; + + for(Standard_Integer i = 0; i < maxNIter; i++) + { + const Standard_Real ParOnC = aFirst + DivPoints[i]*dParam; + + gp_Pnt pt = BACurve.Value(ParOnC); + if((aPn.SquareDistance(pt) >= aTols)) + { + aStatus = BRepCheck_NoError; + return aStatus; + } + } + + aStatus = BRepCheck_CollapsedEdge; + return aStatus; +} + //======================================================================= //function : Validate //purpose : @@ -571,12 +691,13 @@ Standard_Boolean Validate(const Adaptor3d_Curve& CRef, Error = 0.; First = CRef.FirstParameter(); Last = CRef.LastParameter(); - // + aPC=Precision::PConfusion(); proj = (!SameParameter || - fabs(Other.FirstParameter()-First) > aPC || - fabs( Other.LastParameter()-Last) > aPC); - if (!proj) { + Abs(Other.FirstParameter()-First) > aPC || + Abs( Other.LastParameter()-Last) > aPC); + if (!proj) + { Standard_Integer i; Standard_Real Tol2, prm, dD; gp_Pnt pref, pother; @@ -588,7 +709,7 @@ Standard_Boolean Validate(const Adaptor3d_Curve& CRef, //Tol2=Tol*Tol; //modified by NIZNHY-PKV Thu May 05 09:06:47 2011t - for (i = 0; i< NCONTROL; ++i) { + for (i = 0; i < NCONTROL; ++i) { prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1); pref = CRef.Value(prm); pother = Other.Value(prm); @@ -666,18 +787,6 @@ Standard_Boolean Validate(const Adaptor3d_Curve& CRef, } } } - //FINISH : -/* -#ifdef DEB - if (! Status) { - cout << " **** probleme de SameParameter au point :" << endl; - cout << " " << problematic_point.Coord(1) << " " - << problematic_point.Coord(2) << " " - << problematic_point.Coord(3) << endl ; - cout << " Erreur detectee :" << Error << " Tolerance :" << Tol << endl; - } -#endif -*/ return Status ; diff --git a/src/BRepCheck/BRepCheck_Face.cdl b/src/BRepCheck/BRepCheck_Face.cdl index ea7f5ff5c3..3ea7d0e1c5 100755 --- a/src/BRepCheck/BRepCheck_Face.cdl +++ b/src/BRepCheck/BRepCheck_Face.cdl @@ -73,6 +73,13 @@ is is static; + SetStatus(me: mutable; + theStatus:Status from BRepCheck) + + --- Purpose: Sets status of Face; + is static; + + IsUnorientable(me) diff --git a/src/BRepCheck/BRepCheck_Face.cxx b/src/BRepCheck/BRepCheck_Face.cxx index 024f912fd0..6d1f21b5dc 100755 --- a/src/BRepCheck/BRepCheck_Face.cxx +++ b/src/BRepCheck/BRepCheck_Face.cxx @@ -452,6 +452,15 @@ void BRepCheck_Face::SetUnorientable() BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape); } +//======================================================================= +//function : SetStatus +//purpose : +//======================================================================= + +void BRepCheck_Face::SetStatus(const BRepCheck_Status theStatus) +{ + BRepCheck::Add(myMap(myShape),theStatus); +} //======================================================================= //function : IsUnorientable diff --git a/src/BRepCheck/BRepCheck_Wire.cdl b/src/BRepCheck/BRepCheck_Wire.cdl index 40c53ab79d..e745d1e87d 100755 --- a/src/BRepCheck/BRepCheck_Wire.cdl +++ b/src/BRepCheck/BRepCheck_Wire.cdl @@ -126,6 +126,12 @@ is ---Purpose: set SelfIntersect() to be checked is static; + SetStatus(me: mutable; + theStatus:Status from BRepCheck) + + --- Purpose: Sets status of Wire; + is static; + fields diff --git a/src/BRepCheck/BRepCheck_Wire.cxx b/src/BRepCheck/BRepCheck_Wire.cxx index 51d242c89c..444c031ef6 100755 --- a/src/BRepCheck/BRepCheck_Wire.cxx +++ b/src/BRepCheck/BRepCheck_Wire.cxx @@ -1512,6 +1512,17 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F, // return (BRepCheck_NoError); } + +//======================================================================= +//function : SetStatus +//purpose : +//======================================================================= + +void BRepCheck_Wire::SetStatus(const BRepCheck_Status theStatus) +{ + BRepCheck::Add(myMap(myShape),theStatus); +} + //======================================================================= //function : GeometricControls //purpose : diff --git a/src/BRepTest/BRepTest_CheckCommands.cxx b/src/BRepTest/BRepTest_CheckCommands.cxx index 1d35f7962e..99c1b78993 100755 --- a/src/BRepTest/BRepTest_CheckCommands.cxx +++ b/src/BRepTest/BRepTest_CheckCommands.cxx @@ -80,6 +80,11 @@ # include #endif +//Number of BRepCheck_Statuses in BRepCheck_Status.hxx file +//(BRepCheck_NoError is not considered, i.e. general status +//is smaller by one specified in file) +static const Standard_Integer NumberOfStatus = 34; + static char* checkfaultyname = NULL; Standard_EXPORT void BRepTest_CheckCommands_SetFaultyName(const char* name) { @@ -216,6 +221,7 @@ static void Print(Standard_OStream& OS, OS << "On Shape " << Name << " :\n"; for (;itl.More(); itl.Next()) { + if (itl.Value() != BRepCheck_NoError) BRepCheck::Print(itl.Value(),OS); } } @@ -229,6 +235,10 @@ static void Print(Standard_OStream& OS, case TopAbs_EDGE: PrintSub(OS,Ana,S,TopAbs_VERTEX); break; + case TopAbs_WIRE: + PrintSub(OS,Ana,S,TopAbs_EDGE); + PrintSub(OS,Ana,S,TopAbs_VERTEX); + break; case TopAbs_FACE: PrintSub(OS,Ana,S,TopAbs_WIRE); PrintSub(OS,Ana,S,TopAbs_EDGE); @@ -509,46 +519,50 @@ static void FillProblems(const BRepCheck_Status stat, NbProblems->SetValue(11,NbProblems->Value(11)+1); break; case BRepCheck_InvalidDegeneratedFlag: NbProblems->SetValue(12,NbProblems->Value(12)+1); break; - case BRepCheck_FreeEdge: + case BRepCheck_CollapsedEdge: NbProblems->SetValue(13,NbProblems->Value(13)+1); break; - case BRepCheck_InvalidMultiConnexity: + case BRepCheck_FreeEdge: NbProblems->SetValue(14,NbProblems->Value(14)+1); break; - case BRepCheck_InvalidRange: + case BRepCheck_InvalidMultiConnexity: NbProblems->SetValue(15,NbProblems->Value(15)+1); break; - case BRepCheck_EmptyWire: + case BRepCheck_InvalidRange: NbProblems->SetValue(16,NbProblems->Value(16)+1); break; - case BRepCheck_RedundantEdge: + case BRepCheck_EmptyWire: NbProblems->SetValue(17,NbProblems->Value(17)+1); break; - case BRepCheck_SelfIntersectingWire: + case BRepCheck_RedundantEdge: NbProblems->SetValue(18,NbProblems->Value(18)+1); break; - case BRepCheck_NoSurface: + case BRepCheck_SelfIntersectingWire: NbProblems->SetValue(19,NbProblems->Value(19)+1); break; - case BRepCheck_InvalidWire: + case BRepCheck_NoSurface: NbProblems->SetValue(20,NbProblems->Value(20)+1); break; - case BRepCheck_RedundantWire: + case BRepCheck_InvalidWire: NbProblems->SetValue(21,NbProblems->Value(21)+1); break; - case BRepCheck_IntersectingWires: + case BRepCheck_RedundantWire: NbProblems->SetValue(22,NbProblems->Value(22)+1); break; - case BRepCheck_InvalidImbricationOfWires: + case BRepCheck_IntersectingWires: NbProblems->SetValue(23,NbProblems->Value(23)+1); break; - case BRepCheck_EmptyShell: + case BRepCheck_InvalidImbricationOfWires: NbProblems->SetValue(24,NbProblems->Value(24)+1); break; - case BRepCheck_RedundantFace: + case BRepCheck_EmptyShell: NbProblems->SetValue(25,NbProblems->Value(25)+1); break; - case BRepCheck_UnorientableShape: + case BRepCheck_RedundantFace: NbProblems->SetValue(26,NbProblems->Value(26)+1); break; - case BRepCheck_NotClosed: + case BRepCheck_UnorientableShape: NbProblems->SetValue(27,NbProblems->Value(27)+1); break; - case BRepCheck_NotConnected: + case BRepCheck_NotClosed: NbProblems->SetValue(28,NbProblems->Value(28)+1); break; - case BRepCheck_SubshapeNotInShape: + case BRepCheck_NotConnected: NbProblems->SetValue(29,NbProblems->Value(29)+1); break; - case BRepCheck_BadOrientation: + case BRepCheck_SubshapeNotInShape: NbProblems->SetValue(30,NbProblems->Value(30)+1); break; - case BRepCheck_BadOrientationOfSubshape: + case BRepCheck_BadOrientation: NbProblems->SetValue(31,NbProblems->Value(31)+1); break; - case BRepCheck_CheckFail: + case BRepCheck_BadOrientationOfSubshape: NbProblems->SetValue(32,NbProblems->Value(32)+1); break; + case BRepCheck_InvalidToleranceValue: + NbProblems->SetValue(33,NbProblems->Value(33)+1); break; + case BRepCheck_CheckFail: + NbProblems->SetValue(34,NbProblems->Value(34)+1); break; default: break; } @@ -674,8 +688,9 @@ void StructuralDump(Draw_Interpretor& theCommands, theCommands<<" Check Count"<<"\n"; theCommands<<" ------------------------------------------------"<<"\n"; - Handle(TColStd_HArray1OfInteger) NbProblems = new TColStd_HArray1OfInteger(1,32); - for(i=1; i<=32; i++) NbProblems->SetValue(i,0); + Handle(TColStd_HArray1OfInteger) NbProblems = new + TColStd_HArray1OfInteger(1,NumberOfStatus); + for(i=1; i<=NumberOfStatus; i++) NbProblems->SetValue(i,0); Handle(TopTools_HSequenceOfShape) sl,slv,sle,slw,slf,sls,slo; sl = new TopTools_HSequenceOfShape(); theMap.Clear(); @@ -719,64 +734,70 @@ void StructuralDump(Draw_Interpretor& theCommands, theCommands<<" Invalid Degenerated Flag ................. "<Value(12)<<"\n"; //cout<<" Invalid Degenerated Flag ................. "<Value(12)<Value(13)>0) - theCommands<<" Free Edge ................................ "<Value(13)<<"\n"; - //cout<<" Free Edge ................................ "<Value(13)<Value(13)<<"\n"; + //cout<<" Invalid Degenerated Flag ................. "<Value(12)<Value(14)>0) - theCommands<<" Invalid MultiConnexity ................... "<Value(14)<<"\n"; - //cout<<" Invalid MultiConnexity ................... "<Value(14)<Value(14)<<"\n"; + //cout<<" Free Edge ................................ "<Value(13)<Value(15)>0) - theCommands<<" Invalid Range ............................ "<Value(15)<<"\n"; - //cout<<" Invalid Range ............................ "<Value(15)<Value(15)<<"\n"; + //cout<<" Invalid MultiConnexity ................... "<Value(14)<Value(16)>0) - theCommands<<" Empty Wire ............................... "<Value(16)<<"\n"; - //cout<<" Empty Wire ............................... "<Value(16)<Value(16)<<"\n"; + //cout<<" Invalid Range ............................ "<Value(15)<Value(17)>0) - theCommands<<" Redundant Edge ........................... "<Value(17)<<"\n"; - //cout<<" Redundant Edge ........................... "<Value(17)<Value(17)<<"\n"; + //cout<<" Empty Wire ............................... "<Value(16)<Value(18)>0) - theCommands<<" Self Intersecting Wire ................... "<Value(18)<<"\n"; - //cout<<" Self Intersecting Wire ................... "<Value(18)<Value(18)<<"\n"; + //cout<<" Redundant Edge ........................... "<Value(17)<Value(19)>0) - theCommands<<" No Surface ............................... "<Value(19)<<"\n"; - //cout<<" No Surface ............................... "<Value(19)<Value(19)<<"\n"; + //cout<<" Self Intersecting Wire ................... "<Value(18)<Value(20)>0) - theCommands<<" Invalid Wire ............................. "<Value(20)<<"\n"; - //cout<<" Invalid Wire ............................. "<Value(20)<Value(20)<<"\n"; + //cout<<" No Surface ............................... "<Value(19)<Value(21)>0) - theCommands<<" Redundant Wire ........................... "<Value(21)<<"\n"; - //cout<<" Redundant Wire ........................... "<Value(21)<Value(21)<<"\n"; + //cout<<" Invalid Wire ............................. "<Value(20)<Value(22)>0) - theCommands<<" Intersecting Wires ....................... "<Value(22)<<"\n"; - //cout<<" Intersecting Wires ....................... "<Value(22)<Value(22)<<"\n"; + //cout<<" Redundant Wire ........................... "<Value(21)<Value(23)>0) - theCommands<<" Invalid Imbrication of Wires ............. "<Value(23)<<"\n"; - //cout<<" Invalid Imbrication of Wires ............. "<Value(23)<Value(23)<<"\n"; + //cout<<" Intersecting Wires ....................... "<Value(22)<Value(24)>0) - theCommands<<" Empty Shell .............................. "<Value(24)<<"\n"; - //cout<<" Empty Shell .............................. "<Value(24)<Value(24)<<"\n"; + //cout<<" Invalid Imbrication of Wires ............. "<Value(23)<Value(25)>0) - theCommands<<" Redundant Face ........................... "<Value(25)<<"\n"; - //cout<<" Redundant Face ........................... "<Value(25)<Value(25)<<"\n"; + //cout<<" Empty Shell .............................. "<Value(24)<Value(26)>0) - theCommands<<" Unorientable Shape ....................... "<Value(26)<<"\n"; - //cout<<" Unorientable Shape ....................... "<Value(26)<Value(26)<<"\n"; + //cout<<" Redundant Face ........................... "<Value(25)<Value(27)>0) - theCommands<<" Not Closed ............................... "<Value(27)<<"\n"; - //cout<<" Not Closed ............................... "<Value(27)<Value(27)<<"\n"; + //cout<<" Unorientable Shape ....................... "<Value(26)<Value(28)>0) - theCommands<<" Not Connected ............................ "<Value(28)<<"\n"; - //cout<<" Not Connected ............................ "<Value(28)<Value(28)<<"\n"; + //cout<<" Not Closed ............................... "<Value(27)<Value(29)>0) - theCommands<<" Subshape not in Shape .................... "<Value(29)<<"\n"; - //cout<<" Subshape not in Shape .................... "<Value(29)<Value(29)<<"\n"; + //cout<<" Not Connected ............................ "<Value(28)<Value(30)>0) - theCommands<<" Bad Orientation .......................... "<Value(30)<<"\n"; - //cout<<" Bad Orientation .......................... "<Value(30)<Value(30)<<"\n"; + //cout<<" Subshape not in Shape .................... "<Value(29)<Value(31)>0) - theCommands<<" Bad Orientation of Subshape .............. "<Value(31)<<"\n"; - //cout<<" Bad Orientation of Subshape .............. "<Value(31)<Value(31)<<"\n"; + //cout<<" Bad Orientation .......................... "<Value(30)<Value(32)>0) - theCommands<<" checkshape failure......... .............. "<Value(32)<<"\n"; + theCommands<<" Bad Orientation of Subshape .............. "<Value(32)<<"\n"; + //cout<<" Bad Orientation of Subshape .............. "<Value(31)<Value(33)>0) + theCommands<<" Invalid tolerance value................... "<Value(33)<<"\n"; + //cout<<" checkshape failure......... .............. "<Value(32)<Value(34)>0) + theCommands<<" checkshape failure........................ "<Value(34)<<"\n"; //cout<<" checkshape failure......... .............. "<Value(32)< #include #include +#include +#include #include +#include +#include #include #include #include @@ -263,6 +267,78 @@ static Standard_Integer torus(Draw_Interpretor& , Standard_Integer n, const char return 0; } +//======================================================================= +//function : DrawTolerance +//purpose : +//======================================================================= +static Standard_Integer DrawTolerance(Draw_Interpretor& theDI, Standard_Integer theNArg, const char** a) +{ + if(theNArg != 3) + { + theDI << "use toolsphere name vertex\\edge\n"; + return 1; + } + + TopoDS_Shape aS = DBRep::Get(a[2]); + if(aS.IsNull()) + { + theDI << "No source shape found\n"; + return 1; + } + + Standard_Real aRadius; + gp_Pnt aCenter; + + switch(aS.ShapeType()) + { + case TopAbs_VERTEX: + { + TopoDS_Vertex aV = TopoDS::Vertex(aS); + aRadius = BRep_Tool::Tolerance(aV); + aCenter = BRep_Tool::Pnt(aV); + } + break; + case TopAbs_EDGE: + { + TopoDS_Edge anE = TopoDS::Edge(DBRep::Get(a[2])); + TopoDS_Vertex aV1 = TopExp::FirstVertex(anE), + aV2 = TopExp::LastVertex(anE); + + Standard_Real aTol1 = BRep_Tool::Tolerance(aV1); + Standard_Real aTol2 = BRep_Tool::Tolerance(aV2); + + if( Precision::IsInfinite(aTol1) || + Precision::IsInfinite(aTol2)) + { + theDI << "Tolerance is infinity\n"; + return 0; + } + + gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1); + gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2); + + aCenter = gp_Pnt( (aPnt1.X() + aPnt2.X())/2.0, + (aPnt1.Y() + aPnt2.Y())/2.0, + (aPnt1.Z() + aPnt2.Z())/2.0); + + aRadius = Max(aTol1,aTol2) + aPnt1.Distance(aPnt2)/2.0; + } + break; + default: + { + theDI << "Enter a vertex or an edge (see help)\n"; + return 1; + } + } + + TopoDS_Solid S = BRepPrimAPI_MakeSphere(aCenter,aRadius); + + DBRep::Set(a[1],S); + return 0; +} + + + //======================================================================= @@ -287,6 +363,9 @@ void BRepTest::PrimitiveCommands(Draw_Interpretor& theCommands) theCommands.Add("pcone", "pcone name [plane(ax2)] R1 R2 H [angle]",__FILE__,cone,g); theCommands.Add("psphere", "psphere name [plane(ax2)] R [angle1 angle2] [angle]",__FILE__,sphere,g); theCommands.Add("ptorus", "ptorus name [plane(ax2)] R1 R2 [angle1 angle2] [angle]",__FILE__,torus,g); + theCommands.Add("tolsphere", "toolsphere name vertex\\edge (if vertex is given, center of sphere is the \"vertex\", " + "radius is a tolerance of vertex; if edge is given, sphere is built, which is determined in " + "BRepCheck_Edge::CheckTolerance(...) function)",__FILE__,DrawTolerance,g); } diff --git a/tests/bugs/modalg_5/bug23731 b/tests/bugs/modalg_5/bug23731 new file mode 100644 index 0000000000..a408ef7cfd --- /dev/null +++ b/tests/bugs/modalg_5/bug23731 @@ -0,0 +1,24 @@ +puts "============" +puts "CR23731" +puts "============" +puts "" +###################################################### +# The shape obtained by stepread is valid in terms of checkshape but it is not valid in terms of usability. +###################################################### + +catch { pload XDE } + +set filepath [locate_data_file OCC6289.stp] +stepread $filepath a * + +explode a_1 f + +renamevar a_1_24 result + +smallview +donly result +fit + +set square 1 + +set only_screen_axo 1