1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0025923: Remove small wires on face read from STEP

The analysis of small area in the method ShapeAnalysis_Wire::CheckSmallArea is performed the following way:
- On the fisrt step algorithm produces a rough estimation of part of surface area.
- In a case if obtained estimation is less than tolerance then evaluate real area and comapre this value with tolerance.
- New flag has been added to XSTEPResource/IGES. In a case if flag is true the faces with small 3d area is removed from ShapeFix context.

Test-case for issue #25923 and update test-cases in de group according to the new behavior.
This commit is contained in:
azn
2015-05-21 14:46:00 +03:00
committed by bugmaster
parent 602d1eadf1
commit 56a9db93fe
33 changed files with 326 additions and 171 deletions

View File

@@ -105,6 +105,13 @@ is
---C++: inline
---Purpose: Returns (modifiable) the fix small area wire mode, by default
-- False. If True, drops small wires.
RemoveSmallAreaFaceMode (me: mutable) returns Integer;
---C++: return &
---C++: inline
---Purpose: Returns (modifiable) the remove face with small area, by default
-- False. If True, drops faces with small outer wires.
FixIntersectingWiresMode (me: mutable) returns Integer;
---C++: return &
---C++: inline
@@ -202,7 +209,7 @@ is
-- missing seam edge
-- Returns True if missing seam was added
FixSmallAreaWire (me: mutable) returns Boolean;
FixSmallAreaWire (me: mutable; theIsRemoveSmallFace: Boolean = Standard_False) returns Boolean;
---Purpose: Detects wires with small area (that is less than
-- 100*Precision::PConfusion(). Removes these wires if they are internal.
-- Returns : True if at least one small wire removed,
@@ -276,6 +283,7 @@ fields
myFixAddNaturalBoundMode : Integer;
myFixMissingSeamMode : Integer;
myFixSmallAreaWireMode : Integer;
myRemoveSmallAreaFaceMode : Integer;
myFixLoopWiresMode : Integer; -- gka 08.01.2004
myFixIntersectingWiresMode : Integer; -- skl 23.12.2003
myFixSplitFaceMode : Integer; -- skl 03.02.2004

View File

@@ -41,6 +41,7 @@
#include <Geom_Curve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GProp_GProps.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
@@ -51,6 +52,7 @@
#include <TopExp_Explorer.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <BRepGProp.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
@@ -685,13 +687,14 @@ Standard_Boolean ShapeFix_Face::Perform()
myFace = TopoDS::Face ( exp.Current() );
// fix small-area wires
if ( NeedFix ( myFixSmallAreaWireMode, Standard_False ) ) {
if ( FixSmallAreaWire() )
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
if ( NeedFix ( myFixSmallAreaWireMode, Standard_False ) )
{
const Standard_Boolean isRemoveFace = NeedFix( myRemoveSmallAreaFaceMode, Standard_False );
if ( FixSmallAreaWire( isRemoveFace ) )
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
}
}
if ( ! Context().IsNull() ) {
if(Status ( ShapeExtend_DONE ) && !isReplaced && !aInitFace.IsSame(savShape))
{
@@ -1840,51 +1843,69 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
//function : FixSmallAreaWire
//purpose :
//=======================================================================
//%14 pdn 24.02.99 PRO10109, USA60293 fix wire on face with small area.
Standard_Boolean ShapeFix_Face::FixSmallAreaWire()
Standard_Boolean ShapeFix_Face::FixSmallAreaWire(const Standard_Boolean theIsRemoveSmallFace)
{
if ( ! Context().IsNull() ) {
TopoDS_Shape S = Context()->Apply ( myFace );
myFace = TopoDS::Face ( S );
if ( !Context().IsNull() )
{
TopoDS_Shape aShape = Context()->Apply(myFace);
myFace = TopoDS::Face(aShape);
}
//smh#8
TopoDS_Shape emptyCopied = myFace.EmptyCopied();
TopoDS_Face face = TopoDS::Face (emptyCopied);
BRep_Builder aBuilder;
Standard_Integer nbRemoved = 0, nbWires = 0;
BRep_Builder B;
Standard_Real prec = ::Precision::PConfusion()*100;
for (TopoDS_Iterator wi (myFace, Standard_False); wi.More(); wi.Next()) {
if(wi.Value().ShapeType() != TopAbs_WIRE &&
(wi.Value().Orientation() != TopAbs_FORWARD && wi.Value().Orientation() != TopAbs_REVERSED))
continue;
TopoDS_Wire wire = TopoDS::Wire ( wi.Value() );
Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire(wire,myFace,prec);
if ( saw->CheckSmallArea(prec) )
TopoDS_Shape anEmptyCopy = myFace.EmptyCopied();
TopoDS_Face aFace = TopoDS::Face(anEmptyCopy);
const TopoDS_Wire anOuterWire = BRepTools::OuterWire(myFace);
const Standard_Real aTolerance3d = ShapeFix_Root::Precision();
for (TopoDS_Iterator aWIt(myFace, Standard_False); aWIt.More(); aWIt.Next())
{
const TopoDS_Shape& aShape = aWIt.Value();
if ( aShape.ShapeType() != TopAbs_WIRE &&
aShape.Orientation() != TopAbs_FORWARD &&
aShape.Orientation() != TopAbs_REVERSED )
{
SendWarning ( wire, Message_Msg ("FixAdvFace.FixSmallAreaWire.MSG0") );// Null area wire detected, wire skipped
nbRemoved++;
continue;
}
const TopoDS_Wire& aWire = TopoDS::Wire(aShape);
const Standard_Boolean isOuterWire = anOuterWire.IsEqual(aWire);
Handle(ShapeAnalysis_Wire) anAnalyzer = new ShapeAnalysis_Wire(aWire, myFace, aTolerance3d);
if ( anAnalyzer->CheckSmallArea(aWire, isOuterWire) )
{
// Null area wire detected, wire skipped
SendWarning(aWire, Message_Msg("FixAdvFace.FixSmallAreaWire.MSG0"));
++nbRemoved;
}
else
{
B.Add(face,wire);
nbWires++;
aBuilder.Add(aFace, aWire);
++nbWires;
}
}
if ( nbRemoved <=0 ) return Standard_False;
if ( nbWires <=0 ) {
if ( nbRemoved <= 0 )
return Standard_False;
if ( nbWires <= 0 )
{
#ifdef OCCT_DEBUG
cout << "Warning: ShapeFix_Face: All wires on a face have small area; left untouched" << endl;
#endif
if ( theIsRemoveSmallFace && !Context().IsNull() )
Context()->Remove(myFace);
return Standard_False;
}
#ifdef OCCT_DEBUG
cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed" << endl;
#endif
if ( ! Context().IsNull() ) Context()->Replace ( myFace, face );
myFace = face;
if ( !Context().IsNull() )
Context()->Replace(myFace, aFace);
myFace = aFace;
return Standard_True;
}
//=======================================================================

View File

@@ -63,6 +63,16 @@ inline Standard_Integer& ShapeFix_Face::FixSmallAreaWireMode()
return myFixSmallAreaWireMode;
}
//=======================================================================
//function : RemoveSmallAreaFaceMode
//purpose :
//=======================================================================
inline Standard_Integer& ShapeFix_Face::RemoveSmallAreaFaceMode()
{
return myRemoveSmallAreaFaceMode;
}
//=======================================================================
//function : FixIntersectingWiresMode
//purpose :