Added face support in SameParameter in classes ShapeAnalysis_Edge, ShapeFix_Edge.
Test case for issue CR26620
Minor correction.
return OK;
}
+//=======================================================================
+//function : CheckSameParameter
+//purpose :
+//=======================================================================
+
+Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge,
+ Standard_Real& maxdev,
+ const Standard_Integer NbControl)
+{
+ TopoDS_Face anEmptyFace;
+ return CheckSameParameter(edge, anEmptyFace, maxdev, NbControl);
+}
+
//=======================================================================
//function : CheckSameParameter
//=======================================================================
Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge,
- Standard_Real& maxdev,
- const Standard_Integer NbControl)
+ const TopoDS_Face& face,
+ Standard_Real& maxdev,
+ const Standard_Integer NbControl)
{
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
if (BRep_Tool::Degenerated (edge)) return Standard_False;
return Standard_False;
}
+ Handle(Geom_Surface) aFaceSurf;
+ TopLoc_Location L;
+ if ( !face.IsNull() )
+ {
+ aFaceSurf = BRep_Tool::Surface(face, L);
+ }
+
// iterate on pcurves
itcr.Initialize ( TE->Curves() );
- for ( ; itcr.More(); itcr.Next() ) {
+ for ( ; itcr.More(); itcr.Next() )
+ {
Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
+ if ( !(face.IsNull()) ) // Face is not null.
+ {
+ // Check for different surface.
+ if (!GC->IsCurveOnSurface(aFaceSurf, GC->Location()))
+ continue;
+ }
+
Standard_Real f, l;
GC->Range ( f, l );
Handle(Geom_Surface) Su = GC->Surface();
//Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
Adaptor3d_CurveOnSurface ACS;
ACS.Load(GHPC, GAHS);
- if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) {
+ if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) )
+ {
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
}
- if ( GC->IsCurveOnClosedSurface() ) {
+ if ( GC->IsCurveOnClosedSurface() )
+ {
GHPC->ChangeCurve2d().Load ( GC->PCurve2(), f, l ); // same bounds
ACS.Load(GHPC, GAHS); // sans doute inutile
- if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) {
- myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
+ if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) )
+ {
+ myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
}
}
}
//! If deviation is greater than tolerance of the edge (i.e.
//! incorrect flag) returns False, else returns True.
Standard_EXPORT Standard_Boolean CheckSameParameter (const TopoDS_Edge& edge, Standard_Real& maxdev, const Standard_Integer NbControl = 23);
+
+ //! Checks the edge to be SameParameter.
+ //! Calculates the maximal deviation between 3d curve and each
+ //! pcurve of the edge on <NbControl> equidistant points (the same
+ //! algorithm as in BRepCheck; default value is 23 as in BRepCheck).
+ //! This deviation is returned in <maxdev> parameter.
+ //! If deviation is greater than tolerance of the edge (i.e.
+ //! incorrect flag) returns False, else returns True.
+ Standard_EXPORT Standard_Boolean CheckSameParameter (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, Standard_Real& theMaxdev, const Standard_Integer theNbControl = 23);
//! Computes the maximal deviation between the two curve
//! representations.
for ( TopExp_Explorer anEdgeExp(shape, TopAbs_FACE); anEdgeExp.More(); anEdgeExp.Next() )
++aNbFaces;
+ TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
+ TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, aMapEF);
+
BRep_Builder B;
//Standard_Integer nbexcp = 0;
Standard_Integer nbfail = 0, numedge = 0;
B.SameParameter (E,Standard_False);
}
- sfe->FixSameParameter (E); // K2-SEP97
+ TopTools_ListOfShape aListOfFaces;
+ aMapEF.FindFromKey(E, aListOfFaces);
+ if (aListOfFaces.Extent() != 0)
+ {
+ TopTools_ListOfShape::Iterator aListOfFacesIt(aListOfFaces);
+ for ( ; aListOfFacesIt.More() ; aListOfFacesIt.Next())
+ {
+ TopoDS_Face aF = TopoDS::Face( aListOfFacesIt.Value() );
+ sfe->FixSameParameter (E, aF);
+ }
+ }
+ else
+ {
+ sfe->FixSameParameter (E); // K2-SEP97
+ }
if (!BRep_Tool::SameParameter (E)) { ierr = 1; nbfail ++; }
//purpose :
//=======================================================================
- Standard_Boolean ShapeFix_Edge::FixVertexTolerance(const TopoDS_Edge& edge,
+Standard_Boolean ShapeFix_Edge::FixVertexTolerance(const TopoDS_Edge& edge,
const TopoDS_Face& face)
{
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
return Standard_True;
}
+//=======================================================================
+//function : FixSameParameter
+//purpose :
+//=======================================================================
+
+Standard_Boolean ShapeFix_Edge::FixSameParameter(const TopoDS_Edge& edge,
+ const Standard_Real tolerance)
+{
+ TopoDS_Face anEmptyFace;
+ return FixSameParameter(edge, anEmptyFace, tolerance);
+}
//=======================================================================
//function : FixSameParameter
//=======================================================================
Standard_Boolean ShapeFix_Edge::FixSameParameter(const TopoDS_Edge& edge,
+ const TopoDS_Face& face,
const Standard_Real tolerance)
{
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
-
+
if ( BRep_Tool::Degenerated ( edge ) )
{
BRep_Builder B;
TopoDS_Edge copyedge;
TopoDS_Vertex V1 = sae.FirstVertex (edge);
TopoDS_Vertex V2 = sae.LastVertex (edge);
- Standard_Real TolFV = ( V1.IsNull() ? 0. : BRep_Tool::Tolerance ( V1 ) );
- Standard_Real TolLV = ( V2.IsNull() ? 0. : BRep_Tool::Tolerance ( V2 ) );
+ Standard_Real TolFV = ( V1.IsNull() ? 0.0 : BRep_Tool::Tolerance ( V1 ) );
+ Standard_Real TolLV = ( V2.IsNull() ? 0.0 : BRep_Tool::Tolerance ( V2 ) );
Standard_Real tol = BRep_Tool::Tolerance (edge);
-
+
Standard_Boolean wasSP = BRep_Tool::SameParameter ( edge ), SP = Standard_False;
{
try
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
}
}
-
+
// compute deviation on the original pcurves
Standard_Real maxdev;
B.SameParameter ( edge, Standard_True );
- sae.CheckSameParameter ( edge, maxdev );
+
+ // Should check all pcurves in case of non-sameparametrization input.
+ TopoDS_Face aFace = face;
+ if (!wasSP)
+ {
+ TopoDS_Face anEmptyFace;
+ aFace = anEmptyFace;
+ }
+
+ sae.CheckSameParameter ( edge, aFace, maxdev );
if ( sae.Status ( ShapeExtend_FAIL2 ) )
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
-
+
// if BRepLib was OK, compare and select the best variant
if ( SP )
{
sae.CheckSameParameter ( copyedge, BRLDev );
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
if ( BRLTol < BRLDev ) BRLTol = BRLDev;
-
+
//chose the best result
if ( BRLTol < maxdev )
{
//restore tolerances because they could be modified by BRepLib
if ( ! V1.IsNull() ) SFST.SetTolerance ( V1, Max (maxdev, TolFV), TopAbs_VERTEX);
if ( ! V2.IsNull() ) SFST.SetTolerance ( V2, Max (maxdev, TolLV), TopAbs_VERTEX);
-
+
if ( maxdev > tol )
{
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
//! DONE5 - if the edge resulting from BRepLib has been chosen, i.e. variant b. above
//! (only for edges with not set SameParameter)
Standard_EXPORT Standard_Boolean FixSameParameter (const TopoDS_Edge& edge, const Standard_Real tolerance = 0.0);
+
+ //! Tries to make edge SameParameter and sets corresponding
+ //! tolerance and SameParameter flag.
+ //! First, it makes edge same range if SameRange flag is not set.
+ //!
+ //! If flag SameParameter is set, this method calls the
+ //! function ShapeAnalysis_Edge::CheckSameParameter() that
+ //! calculates the maximal deviation of pcurves of the edge from
+ //! its 3d curve. If deviation > tolerance, the tolerance of edge
+ //! is increased to a value of deviation. If deviation < tolerance
+ //! nothing happens.
+ //!
+ //! If flag SameParameter is not set, this method chooses the best
+ //! variant (one that has minimal tolerance), either
+ //! a. only after computing deviation (as above) or
+ //! b. after calling standard procedure BRepLib::SameParameter
+ //! and computing deviation (as above). If <tolerance> > 0, it is
+ //! used as parameter for BRepLib::SameParameter, otherwise,
+ //! tolerance of the edge is used.
+ //!
+ //! Use : Is to be called after all pcurves and 3d curve of the edge are
+ //! correctly computed
+ //! Remark : SameParameter flag is always set to True after this method
+ //! Returns: True, if something done, else False
+ //! Status : OK - edge was initially SameParameter, nothing is done
+ //! FAIL1 - computation of deviation of pcurves from 3d curve has failed
+ //! FAIL2 - BRepLib::SameParameter() has failed
+ //! DONE1 - tolerance of the edge was increased
+ //! DONE2 - flag SameParameter was set to True (only if
+ //! BRepLib::SameParameter() did not set it)
+ //! DONE3 - edge was modified by BRepLib::SameParameter() to SameParameter
+ //! DONE4 - not used anymore
+ //! DONE5 - if the edge resulting from BRepLib has been chosen, i.e. variant b. above
+ //! (only for edges with not set SameParameter)
+ Standard_EXPORT Standard_Boolean FixSameParameter (const TopoDS_Edge& edge,
+ const TopoDS_Face& face,
+ const Standard_Real tolerance = 0.0);
//! Returns the status (in the form of True/False) of last Fix
Standard_EXPORT Standard_Boolean Status (const ShapeExtend_Status status) const;
Handle(ShapeFix_Edge) sfe = myFixWire->FixEdgeTool();
for (TopExp_Explorer Eed (myFace, TopAbs_EDGE); Eed.More(); Eed.Next()) {
TopoDS_Edge edg = TopoDS::Edge (Eed.Current());
- sfe->FixVertexTolerance(edg);
+ sfe->FixVertexTolerance(edg, myFace);
}
// B.UpdateFace (myFace,myPrecision);
// for case when vertex belong to the different faces it is necessary to check vertices tolerances
//after all fixes.
//This fix it should be performed for example for case when cutting edge was performed.
-
Handle(ShapeFix_Edge) sfe = FixEdgeTool();
- TopExp_Explorer anExpE (myResult, TopAbs_EDGE);
- for ( ; anExpE.More(); anExpE.Next())
- sfe->FixVertexTolerance( TopoDS::Edge (anExpE.Current()));
+ TopExp_Explorer anExpF (myResult, TopAbs_FACE);
+ for ( ; anExpF.More(); anExpF.Next())
+ {
+ TopoDS_Face aF = TopoDS::Face(anExpF.Current());
+ TopExp_Explorer anExpE (aF, TopAbs_EDGE);
+ for ( ; anExpE.More(); anExpE.Next())
+ sfe->FixVertexTolerance( TopoDS::Edge (anExpE.Current()), aF);
+ }
}
}
myResult = Context()->Apply(myResult);
// TEMPORARILY without special mode !!!
Handle(ShapeExtend_WireData) sbwd = WireData();
for (Standard_Integer iedge = 1; iedge <= sbwd->NbEdges(); iedge++)
- if ( myFixEdge->FixVertexTolerance (sbwd->Edge (iedge)) )
+ if ( myFixEdge->FixVertexTolerance (sbwd->Edge (iedge), Face()) )
{
Fixed = Standard_True;
}
}
}
}
- myFixEdge->FixSameParameter ( sbwd->Edge(i) );
+ myFixEdge->FixSameParameter ( sbwd->Edge(i), Face());
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
{
for ( i=1; i <= nb; i++)
{
- myFixEdge->FixVertexTolerance (sbwd->Edge (i), face);
+ myFixEdge->FixVertexTolerance (sbwd->Edge (i), Face());
if ( myFixEdge->Status ( ShapeExtend_DONE ) )
myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE8 );
if ( myFixEdge->Status ( ShapeExtend_FAIL ) )
// no call to BRepLib: B.SameParameter ( edge, Standard_False );
Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
- sfe->FixSameParameter ( edge );
+ sfe->FixSameParameter ( edge, face );
c2d = BRep_Tool::CurveOnSurface ( edge, face, first, last );
tol = BRep_Tool::Tolerance ( edge );
return Standard_True;
--- /dev/null
+puts "REQUIRED ALL: Faulty shapes in variables faulty_1 to"
+
+puts "============"
+puts "OCC26620"
+puts "============"
+puts ""
+#######################################################################
+## Shape healing unreasonably downgrades tolerance of a face
+#######################################################################
+
+restore [locate_data_file bug26620_ff.brep] ff
+
+puts "\nBefore shape healing"
+checkshape ff
+tolerance ff
+
+fixshape r ff
+
+puts "\nAfter shape healing"
+checkshape r
+regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance r] full MaxTol
+
+set expected_MaxTolerance 0.1
+set tol_abs_MaxTolerance 0.5
+set tol_rel_MaxTolerance 0.5
+checkreal "MaxTolerance" ${MaxTol} ${expected_MaxTolerance} ${tol_abs_MaxTolerance} ${tol_rel_MaxTolerance}