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

0026261: Create a tool to remove tails from any wire

A tool to remove tails from the wires of a shape was created.
The tool is based on mechanism 'ShapeFix',
is located in types 'ShapeFix_Wire' and 'ShapeAnalysis_Wire',
is enabled through method 'ShapeFix_Wire::FixTailMode' and
is initialized by methods 'ShapeFix_Wire::SetMaxTailAngle' and 'ShapeFix_Wire::SetMaxTailWidth' and
is called through method 'ShapeFix_Wire::FixTails'.
The status of any performing of the last method is accessible through method 'ShapeFix_Wire::StatusFixTails'.
The tail angle is checked only at the tail start.

Mechanism 'ShapeFix' was modified:
- the tool is disabled by default;
- algorithm 'Fix notched edges' is disabled then the tool is enabled;
- the tool and the last algorithm work in turns then the tool works on the request.

'Draw' command 'fixshape' was extended by options '-maxtaila' and '-maxtailw' to test the tool.

'Draw' tests to test the tool were created.

Algorithm 'fixshape' was changed in type 'ShapeProcess_OperLibrary' to
- use new parameters named 'FixTailMode', 'MaxTailAngle' (in degrees) and 'MaxTailWidth' from the algorithm context;
- apply the tool after the shape will be fully fixed if the tool was enabled.

Place holders for the new parameters were created in the resource file of mechsnism 'STEPControl_Reader'.

Test cases for issue CR26261
This commit is contained in:
abk
2015-05-19 20:03:11 +03:00
committed by bugmaster
parent 70fd50ec90
commit fbf3becf65
38 changed files with 852 additions and 21 deletions

View File

@@ -462,6 +462,7 @@ Standard_Boolean ShapeFix_Face::Perform()
theAdvFixWire->StatusConnected(ShapeExtend_DONE) ||
theAdvFixWire->StatusEdgeCurves(ShapeExtend_DONE) ||
theAdvFixWire->StatusNotches(ShapeExtend_DONE) || // CR0024983
theAdvFixWire->StatusFixTails(ShapeExtend_DONE) ||
theAdvFixWire->StatusDegenerated(ShapeExtend_DONE) ||
theAdvFixWire->StatusClosed(ShapeExtend_DONE));
TopoDS_Wire w = theAdvFixWire->Wire();
@@ -561,9 +562,10 @@ Standard_Boolean ShapeFix_Face::Perform()
}
if ( theAdvFixWire->Perform() ) {
isfixReorder = theAdvFixWire->StatusReorder(ShapeExtend_DONE);
fixed = (theAdvFixWire->StatusLacking(ShapeExtend_DONE) ||
theAdvFixWire->StatusSelfIntersection(ShapeExtend_DONE) ||
theAdvFixWire->StatusNotches(ShapeExtend_DONE)); //Standard_True;
fixed = (theAdvFixWire->StatusLacking(ShapeExtend_DONE) ||
theAdvFixWire->StatusSelfIntersection(ShapeExtend_DONE) ||
theAdvFixWire->StatusNotches(ShapeExtend_DONE) ||
theAdvFixWire->StatusFixTails(ShapeExtend_DONE));
TopoDS_Wire w = theAdvFixWire->Wire();
if(fixed) {
if ( ! Context().IsNull() ) Context()->Replace ( wire, w );

View File

@@ -59,8 +59,10 @@ class Wire from ShapeFix inherits Root from ShapeFix
-- a) Wire (ether TopoDS_Wire or ShapeExtend_Wire)
-- b) Face or surface
-- c) Precision
-- d) Maximal tail angle and width
-- This can be done either by calling corresponding methods
-- (LoadWire, SetFace or SetSurface, and SetPrecision), or
-- (LoadWire, SetFace or SetSurface, SetPrecision, SetMaxTailAngle
-- and SetMaxTailWidth), or
-- by loading already filled ShapeAnalisis_Wire with method Load
uses
@@ -131,6 +133,12 @@ is
SetPrecision (me: mutable; prec: Real) is redefined;
---Purpose: Set working precision (to root and to analyzer)
SetMaxTailAngle (me: mutable; theMaxTailAngle: Real);
---Purpose: Sets the maximal allowed angle of the tails in radians.
SetMaxTailWidth (me: mutable; theMaxTailWidth: Real);
---Purpose: Sets the maximal allowed width of the tails.
IsLoaded (me) returns Boolean;
---C++: inline
---Purpose: Tells if the wire is loaded
@@ -313,6 +321,9 @@ is
-- -1 default
-- 1 method will be called
-- 0 method will not be called
FixTailMode(me: mutable) returns Integer;
---C++: inline
---C++: return &
--- Fixing methods:
@@ -767,6 +778,8 @@ is
-- FAIL1 - There was no pcurve found on some edge
-- FAIL2 - Method failed to fix the gap
FixTails(me: mutable) returns Boolean;
--- Result of fixes:
StatusReorder (me; status: Status from ShapeExtend) returns Boolean;
@@ -800,6 +813,9 @@ is
-- DONE: some problem(s) was(were) detected and successfully fixed
-- FAIL: some problem(s) cannot be fixed
---Level : Public (API)
StatusFixTails(me; status: Status from ShapeExtend) returns Boolean;
---C++: inline
LastFixStatus (me; status: Status from ShapeExtend) returns Boolean;
---C++: inline
---Purpose: Queries the status of last call to methods Fix... of
@@ -843,6 +859,7 @@ fields
myFixSelfIntersectingEdgeMode: Integer is protected;
myFixIntersectingEdgesMode: Integer is protected;
myFixNonAdjacentIntersectingEdgesMode: Integer is protected;
myFixTailMode: Integer is protected;
myRemoveLoopMode: Integer is protected;
-- -1 - old variant (default)
@@ -874,4 +891,7 @@ fields
myStatusGaps2d: Integer is protected;
myStatusRemovedSegment: Boolean is protected;
myStatusNotches: Integer is protected;
myStatusFixTails: Integer is protected;
myMaxTailAngleSine: Real is protected;
myMaxTailWidth: Real is protected;
end Wire;

View File

@@ -129,7 +129,7 @@
//purpose :
//=======================================================================
ShapeFix_Wire::ShapeFix_Wire()
ShapeFix_Wire::ShapeFix_Wire() : myMaxTailAngleSine(0), myMaxTailWidth(-1)
{
myFixEdge = new ShapeFix_Edge;
myAnalyzer = new ShapeAnalysis_Wire;
@@ -143,8 +143,10 @@ ShapeFix_Wire::ShapeFix_Wire()
//purpose :
//=======================================================================
ShapeFix_Wire::ShapeFix_Wire (const TopoDS_Wire& wire,
const TopoDS_Face &face, const Standard_Real prec)
ShapeFix_Wire::ShapeFix_Wire (
const TopoDS_Wire& wire,
const TopoDS_Face &face,
const Standard_Real prec) : myMaxTailAngleSine(0), myMaxTailWidth(-1)
{
myFixEdge = new ShapeFix_Edge;
myAnalyzer = new ShapeAnalysis_Wire;
@@ -165,6 +167,25 @@ void ShapeFix_Wire::SetPrecision (const Standard_Real prec)
myAnalyzer->SetPrecision ( prec );
}
//=======================================================================
//function : SetMaxTailAngle
//purpose :
//=======================================================================
void ShapeFix_Wire::SetMaxTailAngle(const Standard_Real theMaxTailAngle)
{
myMaxTailAngleSine = Sin(theMaxTailAngle);
myMaxTailAngleSine = (myMaxTailAngleSine >= 0) ? myMaxTailAngleSine : 0;
}
//=======================================================================
//function : SetMaxTailWidth
//purpose :
//=======================================================================
void ShapeFix_Wire::SetMaxTailWidth(const Standard_Real theMaxTailWidth)
{
myMaxTailWidth = theMaxTailWidth;
}
//=======================================================================
//function : ClearModes
//purpose :
@@ -194,6 +215,7 @@ void ShapeFix_Wire::ClearModes()
myFixSelfIntersectingEdgeMode = -1;
myFixIntersectingEdgesMode = -1;
myFixNonAdjacentIntersectingEdgesMode = -1;
myFixTailMode = 0;
myFixReorderMode = -1;
myFixSmallMode = -1;
@@ -227,6 +249,8 @@ void ShapeFix_Wire::ClearStatuses()
myStatusGaps3d = emptyStatus; //szv#9:S4244:19Aug99 new method introduced
myStatusGaps2d = emptyStatus; //szv#9:S4244:19Aug99 new method introduced
myStatusClosed = emptyStatus;
myStatusNotches = emptyStatus;
myStatusFixTails = emptyStatus;
}
//=======================================================================
@@ -361,11 +385,21 @@ Standard_Boolean ShapeFix_Wire::Perform()
}
//pdn - temporary to test
if ( NeedFix ( myFixNotchedEdgesMode, ReorderOK ) ) {
if (myFixTailMode <= 0 && NeedFix(myFixNotchedEdgesMode, ReorderOK))
{
Fixed |= FixNotchedEdges();
if(Fixed) FixShifted(); //skl 07.03.2002 for OCC180
}
if (myFixTailMode != 0)
{
Fixed |= FixTails();
if (Fixed)
{
FixShifted();
}
}
if ( NeedFix ( myFixSelfIntersectionMode, myClosedMode ) ) {
Standard_Integer savFixIntersectingEdgesMode = myFixIntersectingEdgesMode;
// switch off FixIntEdges if reorder not done
@@ -3322,3 +3356,171 @@ void ShapeFix_Wire::UpdateWire ()
sbwd->Remove ( i-- );
}
}
//=======================================================================
//function : FixTails
//purpose :
//=======================================================================
Standard_Boolean ShapeFix_Wire::FixTails()
{
if (myMaxTailWidth < 0 || !IsReady())
{
return Standard_False;
}
myLastFixStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
if (!Context().IsNull())
{
UpdateWire();
}
Handle(ShapeExtend_WireData) aSEWD = WireData();
Standard_Integer aECount = NbEdges(), aENs[] = {aECount, 1};
Standard_Boolean aCheckAngle = Standard_True;
while (aECount >= 2 && aENs[1] <= aECount)
{
const TopoDS_Edge aEs[] = {aSEWD->Edge(aENs[0]), aSEWD->Edge(aENs[1])};
TopoDS_Edge aEParts[2][2];
if (!myAnalyzer->CheckTail(aEs[0], aEs[1],
aCheckAngle ? myMaxTailAngleSine : -1, myMaxTailWidth, MaxTolerance(),
aEParts[0][0], aEParts[0][1], aEParts[1][0], aEParts[1][1]))
{
aENs[0] = aENs[1]++;
aCheckAngle = Standard_True;
continue;
}
// Provide not less than 1 edge in the result wire.
Standard_Integer aSplitCounts[] =
{aEParts[0][1].IsNull() ? 0 : 1, aEParts[1][1].IsNull() ? 0 : 1};
const Standard_Integer aRemoveCount =
(aEParts[0][0].IsNull() ? 0 : 1) + (aEParts[1][0].IsNull() ? 0 : 1);
if (aECount + aSplitCounts[0] + aSplitCounts[1] < 1 + aRemoveCount)
{
aENs[0] = aENs[1]++;
aCheckAngle = Standard_True;
continue;
}
// Split the edges.
for (Standard_Integer aEI = 0; aEI < 2; ++aEI)
{
if (aSplitCounts[aEI] == 0)
{
continue;
}
// Replace the edge by the wire of its parts in the shape.
const TopoDS_Edge aE = aEs[aEI];
if (!Context().IsNull())
{
TopoDS_Wire aEWire;
BRep_Builder().MakeWire(aEWire);
BRep_Builder().Add(aEWire, aEParts[aEI][0]);
BRep_Builder().Add(aEWire, aEParts[aEI][1]);
TopoDS_Edge aFE = TopoDS::Edge(aE.Oriented(TopAbs_FORWARD));
Context()->Replace(aFE, aEWire);
}
// Replace the edge by its parts in the edge wire.
const TopAbs_Orientation aOrient = aE.Orientation();
aEParts[aEI][0].Orientation(aOrient);
aEParts[aEI][1].Orientation(aOrient);
const Standard_Integer aFirstPI = (aOrient != TopAbs_REVERSED) ? 0 : 1;
const Standard_Integer aAdd =
(aEI == 0 || aENs[1] < aENs[0]) ? 0 : aSplitCounts[0];
aSEWD->Set(aEParts[aEI][aFirstPI], aENs[aEI] + aAdd);
aSEWD->Add(aEParts[aEI][1 - aFirstPI], aENs[aEI] + 1 + aAdd);
}
// Remove the tail.
if (aRemoveCount == 2)
{
aCheckAngle = Standard_True;
FixDummySeam(aENs[0] + aSplitCounts[0] +
((aENs[0] < aENs[1]) ? 0 : aSplitCounts[1]));
if (!Context().IsNull())
{
UpdateWire();
}
myLastFixStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE);
if (aSplitCounts[0] + aSplitCounts[1] == 2)
{
aENs[0] = aENs[1]++;
continue;
}
if (aSplitCounts[0] == aSplitCounts[1])
{
aECount -= 2;
if (aENs[1] >= 3)
{
--aENs[0];
--aENs[1];
}
else
{
aENs[0] = aECount;
aENs[1] = 1;
}
aCheckAngle = Standard_False;
}
else
{
--aECount;
if (aSplitCounts[0] != 0)
{
aENs[0] = (aENs[0] <= aECount) ? aENs[0] : aECount;
}
else
{
if (aENs[1] >= 3)
{
--aENs[0];
--aENs[1];
}
else
{
aENs[0] = aECount;
aENs[1] = 1;
}
}
}
}
else
{
aCheckAngle = Standard_False;
--aECount;
const Standard_Integer aRI = aEParts[0][0].IsNull() ? 1 : 0;
if (aSplitCounts[aRI] != 0)
{
if (aRI == 0)
{
if (aENs[1] >= 3)
{
--aENs[0];
--aENs[1];
}
else
{
aENs[0] = aECount;
aENs[1] = 1;
}
}
else
{
aENs[0] = (aENs[1] > 1) ? aENs[0] : aECount;
}
}
aSEWD->Remove(aENs[aRI] + ((aRI != 0 || aSplitCounts[0] == 0) ? 0 : 1));
if (!Context().IsNull())
{
Context()->Remove(aEs[aRI].Oriented(TopAbs_FORWARD));
UpdateWire();
}
myLastFixStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE);
}
}
myStatusNotches = myLastFixStatus;
return ShapeExtend::DecodeStatus(myLastFixStatus, ShapeExtend_DONE);
}

View File

@@ -405,6 +405,15 @@ inline Standard_Integer& ShapeFix_Wire::FixNonAdjacentIntersectingEdgesMode()
return myFixNonAdjacentIntersectingEdgesMode;
}
//=======================================================================
//function : FixTailMode
//purpose :
//=======================================================================
inline Standard_Integer& ShapeFix_Wire::FixTailMode()
{
return myFixTailMode;
}
//=======================================================================
//function : Status.. for high-level methods
@@ -516,6 +525,16 @@ inline Standard_Boolean ShapeFix_Wire::StatusNotches(const ShapeExtend_Status s
{
return ShapeExtend::DecodeStatus ( myStatusNotches, status );
}
//=======================================================================
//function : StatusFixTails
//purpose :
//=======================================================================
inline Standard_Boolean ShapeFix_Wire::StatusFixTails(const ShapeExtend_Status status) const
{
return ShapeExtend::DecodeStatus(myStatusFixTails, status);
}
//=======================================================================
//function : LastFixStatus - Status for low-level methods (common)
//purpose :