Archived issue #0024109
ShapeAnalysis_Wire::CheckSmall does incorrectly estimate edge length (used for FixSmall)
Description
In the following Code from ShapeAnalysis_Wire.cxx (from line 676), first the euclidian distance between the vertices is checked (okay), but then an approximation for the length of the edge is done by calculating the mid-point (Pm = c3d->Value ( (cf+cl)/2. ); ).
TopoDS_Vertex V1 = sae.FirstVertex (E);
TopoDS_Vertex V2 = sae.LastVertex (E);
gp_Pnt p1 = BRep_Tool::Pnt (V1);
gp_Pnt p2 = BRep_Tool::Pnt (V2);
Standard_Real dist = p1.Distance(p2);
Standard_Real prec = precsmall;
if (dist > prec) return Standard_False; // pas nulle
gp_Pnt Pm;
Standard_Real cf,cl;
Handle(Geom_Curve) c3d;
if ( sae.Curve3d (E,c3d,cf,cl,Standard_False) ) Pm = c3d->Value ( (cf+cl)/2. );
if ( Pm.Distance(p1) > prec || Pm.Distance(p2) > prec ) return Standard_False;
What's wrong is the fact that the length is approximated using the expression
Pm.Distance(p1) > prec || Pm.Distance(p2) > prec
But p1 and p2 are not the startpoint and endpoint on the edge but the vertex centres. They can be arbitrarily far away from the actual geometric curve of the edge. Take the following scenario:
- an edge of length zero (so it's basically a point), located at (0,0,0). Therefore mid-point Pm is also located at (0,0,0).
- the start and end vertex have a distance > prec from the zero length edge
- then this routine incorrectly reports that this is not a small edge, because Pm.Distance(p1) > prec and Pm.Distance(p2) > prec
Correct -in my opinion- would be the following code
gp_Pnt Pm;
gp_Pnt Ps, Pe;
Standard_Real cf,cl;
Handle(Geom_Curve) c3d;
if ( sae.Curve3d (E,c3d,cf,cl,Standard_False) )
{
Pm = c3d->Value ( (cf+cl)/2. );
Ps = c3d->Value (cf);
Pe = c3d->Value (cl);
}
if ( Pm.Distance(Ps) > prec || Pm.Distance(Pe) > prec ) return Standard_False;
TopoDS_Vertex V1 = sae.FirstVertex (E);
TopoDS_Vertex V2 = sae.LastVertex (E);
gp_Pnt p1 = BRep_Tool::Pnt (V1);
gp_Pnt p2 = BRep_Tool::Pnt (V2);
Standard_Real dist = p1.Distance(p2);
Standard_Real prec = precsmall;
if (dist > prec) return Standard_False; // pas nulle
gp_Pnt Pm;
Standard_Real cf,cl;
Handle(Geom_Curve) c3d;
if ( sae.Curve3d (E,c3d,cf,cl,Standard_False) ) Pm = c3d->Value ( (cf+cl)/2. );
if ( Pm.Distance(p1) > prec || Pm.Distance(p2) > prec ) return Standard_False;
What's wrong is the fact that the length is approximated using the expression
Pm.Distance(p1) > prec || Pm.Distance(p2) > prec
But p1 and p2 are not the startpoint and endpoint on the edge but the vertex centres. They can be arbitrarily far away from the actual geometric curve of the edge. Take the following scenario:
- an edge of length zero (so it's basically a point), located at (0,0,0). Therefore mid-point Pm is also located at (0,0,0).
- the start and end vertex have a distance > prec from the zero length edge
- then this routine incorrectly reports that this is not a small edge, because Pm.Distance(p1) > prec and Pm.Distance(p2) > prec
Correct -in my opinion- would be the following code
gp_Pnt Pm;
gp_Pnt Ps, Pe;
Standard_Real cf,cl;
Handle(Geom_Curve) c3d;
if ( sae.Curve3d (E,c3d,cf,cl,Standard_False) )
{
Pm = c3d->Value ( (cf+cl)/2. );
Ps = c3d->Value (cf);
Pe = c3d->Value (cl);
}
if ( Pm.Distance(Ps) > prec || Pm.Distance(Pe) > prec ) return Standard_False;
Public activity
No public notes
Participants are labeled by their role within this record.