1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-08 14:17:06 +03:00

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.
This commit is contained in:
nbv
2013-12-03 16:05:46 +04:00
committed by asuraven
parent 5e4f263d1c
commit e168d693ed
6 changed files with 612 additions and 243 deletions

View File

@@ -244,6 +244,10 @@ void BRepCheck::Print(const BRepCheck_Status stat,
case BRepCheck_EnclosedRegion:
OS << "BRepCheck_EnclosedRegion\n";
break;
case BRepCheck_CollapsedEdge:
OS << "BRepCheck_CollapsedEdge\n";
break;
default:
break;
}

View File

@@ -123,6 +123,48 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
{
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)
{
#ifdef DEB
cout<<"BRepCheck_Analyzer : ";
Standard_Failure::Caught()->Print(cout);
cout<<endl;
#endif
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);
}
}
try
{
BRepCheck_Status ste = Handle(BRepCheck_Edge)::
@@ -143,12 +185,15 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
if ( ! myMap(S).IsNull() )
{
myMap(S)->SetFailStatus(S);
}
Handle(BRepCheck_Result) aRes = myMap(aVertex);
if ( ! aRes.IsNull() )
{
aRes->SetFailStatus(aVertex);
aRes->SetFailStatus(S);
}
}
TopTools_MapOfShape MapS;
@@ -256,6 +301,12 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
performwire = Standard_False;
break;
}
//if(ste == BRepCheck_CollapsedEdge)
//{
// isInvalidTolerance = Standard_True;
// break;
//}
}
}
}

View File

@@ -27,6 +27,15 @@
#include <BRep_PolygonOnTriangulation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_TFace.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRep_CurveRepresentation.hxx>
#include <BRep_ListOfCurveRepresentation.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_GCurve.hxx>
#include <BRep_CurveOnSurface.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepCheck.hxx>
@@ -40,6 +49,10 @@
#include <Geom_Curve.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
@@ -60,8 +73,23 @@
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <Precision.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Edge,BRepCheck_Result)
//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
@@ -69,6 +97,7 @@ static
const Adaptor3d_CurveOnSurface&,
const Standard_Real,
const Standard_Boolean);
static
void PrintProblematicPoint(const gp_Pnt&,
const Standard_Real,
@@ -305,6 +334,11 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
{
case TopAbs_WIRE:
{
//if (CheckTolerance(TopoDS::Edge(myShape)) == BRepCheck_CollapsedEdge)
//{
// BRepCheck::Add(lst,BRepCheck_CollapsedEdge);
// return;
//}
}
break;
@@ -313,6 +347,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
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)
@@ -556,12 +591,14 @@ Standard_Boolean BRepCheck_Edge::GeometricControls() const
//function : SetStatus
//purpose :
//=======================================================================
void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus)
{
BRepCheck::Add(myMap(myShape),theStatus);
}
//=======================================================================
//function : Tolerance
//purpose :
@@ -778,6 +815,86 @@ BRepCheck_Status BRepCheck_Edge::
return BRepCheck_NoError;
}
//=======================================================================
//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 :

View File

@@ -516,6 +516,31 @@ void ContextualDump(Draw_Interpretor& theCommands,
static void FillProblems(const BRepCheck_Status stat,
Handle(TColStd_HArray1OfInteger)& NbProblems)
{
case BRepCheck_CollapsedEdge:
NbProblems->SetValue(13,NbProblems->Value(13)+1); break;
NbProblems->SetValue(14,NbProblems->Value(14)+1); break;
NbProblems->SetValue(15,NbProblems->Value(15)+1); break;
NbProblems->SetValue(16,NbProblems->Value(16)+1); break;
NbProblems->SetValue(17,NbProblems->Value(17)+1); break;
NbProblems->SetValue(18,NbProblems->Value(18)+1); break;
NbProblems->SetValue(19,NbProblems->Value(19)+1); break;
NbProblems->SetValue(20,NbProblems->Value(20)+1); break;
NbProblems->SetValue(21,NbProblems->Value(21)+1); break;
NbProblems->SetValue(22,NbProblems->Value(22)+1); break;
NbProblems->SetValue(23,NbProblems->Value(23)+1); break;
NbProblems->SetValue(24,NbProblems->Value(24)+1); break;
NbProblems->SetValue(25,NbProblems->Value(25)+1); break;
NbProblems->SetValue(26,NbProblems->Value(26)+1); break;
NbProblems->SetValue(27,NbProblems->Value(27)+1); break;
NbProblems->SetValue(28,NbProblems->Value(28)+1); break;
NbProblems->SetValue(29,NbProblems->Value(29)+1); break;
NbProblems->SetValue(30,NbProblems->Value(30)+1); break;
NbProblems->SetValue(31,NbProblems->Value(31)+1); break;
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;
const Standard_Integer anID = static_cast<Standard_Integer> (stat);
@@ -655,9 +680,78 @@ void StructuralDump(Draw_Interpretor& theCommands,
GetProblemShapes(theAna, theShape, sl, NbProblems);
theMap.Clear();
if(NbProblems->Value(13)>0)
theCommands<<" Edge is collapsed in vertex............... "<<NbProblems->Value(13)<<"\n";
//cout<<" Invalid Degenerated Flag ................. "<<NbProblems->Value(12)<<endl;
if(NbProblems->Value(14)>0)
theCommands<<" Free Edge ................................ "<<NbProblems->Value(14)<<"\n";
//cout<<" Free Edge ................................ "<<NbProblems->Value(14)<<endl;
if(NbProblems->Value(15)>0)
theCommands<<" Invalid MultiConnexity ................... "<<NbProblems->Value(15)<<"\n";
//cout<<" Invalid MultiConnexity ................... "<<NbProblems->Value(15)<<endl;
if(NbProblems->Value(16)>0)
theCommands<<" Invalid Range ............................ "<<NbProblems->Value(16)<<"\n";
//cout<<" Invalid Range ............................ "<<NbProblems->Value(16)<<endl;
if(NbProblems->Value(17)>0)
theCommands<<" Empty Wire ............................... "<<NbProblems->Value(17)<<"\n";
//cout<<" Empty Wire ............................... "<<NbProblems->Value(17)<<endl;
if(NbProblems->Value(18)>0)
theCommands<<" Redundant Edge ........................... "<<NbProblems->Value(18)<<"\n";
//cout<<" Redundant Edge ........................... "<<NbProblems->Value(18)<<endl;
if(NbProblems->Value(19)>0)
theCommands<<" Self Intersecting Wire ................... "<<NbProblems->Value(19)<<"\n";
//cout<<" Self Intersecting Wire ................... "<<NbProblems->Value(19)<<endl;
if(NbProblems->Value(20)>0)
theCommands<<" No Surface ............................... "<<NbProblems->Value(20)<<"\n";
//cout<<" No Surface ............................... "<<NbProblems->Value(20)<<endl;
if(NbProblems->Value(21)>0)
theCommands<<" Invalid Wire ............................. "<<NbProblems->Value(21)<<"\n";
//cout<<" Invalid Wire ............................. "<<NbProblems->Value(21)<<endl;
if(NbProblems->Value(22)>0)
theCommands<<" Redundant Wire ........................... "<<NbProblems->Value(22)<<"\n";
//cout<<" Redundant Wire ........................... "<<NbProblems->Value(22)<<endl;
if(NbProblems->Value(23)>0)
theCommands<<" Intersecting Wires ....................... "<<NbProblems->Value(23)<<"\n";
//cout<<" Intersecting Wires ....................... "<<NbProblems->Value(23)<<endl;
if(NbProblems->Value(24)>0)
theCommands<<" Invalid Imbrication of Wires ............. "<<NbProblems->Value(24)<<"\n";
//cout<<" Invalid Imbrication of Wires ............. "<<NbProblems->Value(24)<<endl;
if(NbProblems->Value(25)>0)
theCommands<<" Empty Shell .............................. "<<NbProblems->Value(25)<<"\n";
//cout<<" Empty Shell .............................. "<<NbProblems->Value(25)<<endl;
if(NbProblems->Value(26)>0)
theCommands<<" Redundant Face ........................... "<<NbProblems->Value(26)<<"\n";
//cout<<" Redundant Face ........................... "<<NbProblems->Value(26)<<endl;
if(NbProblems->Value(27)>0)
theCommands<<" Unorientable Shape ....................... "<<NbProblems->Value(27)<<"\n";
//cout<<" Unorientable Shape ....................... "<<NbProblems->Value(27)<<endl;
if(NbProblems->Value(28)>0)
theCommands<<" Not Closed ............................... "<<NbProblems->Value(28)<<"\n";
//cout<<" Not Closed ............................... "<<NbProblems->Value(28)<<endl;
if(NbProblems->Value(29)>0)
theCommands<<" Not Connected ............................ "<<NbProblems->Value(29)<<"\n";
//cout<<" Not Connected ............................ "<<NbProblems->Value(29)<<endl;
if(NbProblems->Value(30)>0)
theCommands<<" Subshape not in Shape .................... "<<NbProblems->Value(30)<<"\n";
//cout<<" Subshape not in Shape .................... "<<NbProblems->Value(30)<<endl;
if(NbProblems->Value(31)>0)
theCommands<<" Bad Orientation .......................... "<<NbProblems->Value(31)<<"\n";
//cout<<" Bad Orientation .......................... "<<NbProblems->Value(31)<<endl;
if(NbProblems->Value(32)>0)
theCommands<<" Bad Orientation of Subshape .............. "<<NbProblems->Value(32)<<"\n";
//cout<<" Bad Orientation of Subshape .............. "<<NbProblems->Value(32)<<endl;
if(NbProblems->Value(33)>0)
theCommands<<" Invalid tolerance value................... "<<NbProblems->Value(33)<<"\n";
//cout<<" checkshape failure......... .............. "<<NbProblems->Value(33)<<endl;
if(NbProblems->Value(34)>0)
theCommands<<" checkshape failure......... .............. "<<NbProblems->Value(34)<<"\n";
//cout<<" checkshape failure......... .............. "<<NbProblems->Value(34)<<endl;
Standard_Integer aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnCurve);
if(NbProblems->Value(aProblemID) > 0)
theCommands<<" Invalid Point on Curve ................... "<<NbProblems->Value(aProblemID)<<"\n";
if(NbProblems->Value(34)>0)
theCommands<<" checkshape failure........................ "<<NbProblems->Value(34)<<"\n";
//cout<<" checkshape failure......... .............. "<<NbProblems->Value(32)<<endl;
aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnCurveOnSurface);
if(NbProblems->Value(aProblemID)>0)

View File

@@ -19,7 +19,11 @@
#include <Draw_Interpretor.hxx>
#include <Draw_Appli.hxx>
#include <DrawTrSurf.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI.hxx>
#include <BRepPreviewAPI_MakeBox.hxx>
@@ -383,6 +387,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;
}
//=======================================================================
@@ -459,6 +535,9 @@ void BRepTest::PrimitiveCommands(Draw_Interpretor& theCommands)
"\n\t\t: - angle2 second angle to create a torus ring segment"
"\n\t\t: - angle angle to create a torus pipe segment",
__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);
}

View File

@@ -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