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:
@@ -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 );
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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 :
|
||||
|
Reference in New Issue
Block a user