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

0025553: ShapeFix_Face::FixMissingSeam() fails to correct a face

Modification to support case when edges on face  have incorrect orientation was added.
Modification to support case when wires have intersecting segment was added

Test cases for issue 25553 added; other affected tests corrected (improvements)

Corrected test case
This commit is contained in:
gka
2015-09-10 17:42:22 +03:00
committed by bugmaster
parent eb75e31c4c
commit 0d3d226ed3
9 changed files with 116 additions and 57 deletions

View File

@@ -1654,52 +1654,73 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
ws.Append ( w2 );
}
// Check consistency of orientations of the two wires that need to be connected by a seam
Standard_Real uf=SUF, vf=SVF;
Standard_Integer coord = ( ismodeu ? 1 : 0 );
Standard_Integer isneg = ( ismodeu ? ismodeu : -ismodev );
Standard_Real period = ( ismodeu ? URange : VRange );
TopoDS_Shape S;
Standard_Real m1[2][2], m2[2][2];
S = myFace.EmptyCopied();
B.Add ( S, w1 );
ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m1[0][0], m1[0][1], m1[1][0], m1[1][1]);
S = myFace.EmptyCopied();
B.Add ( S, w2 );
ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m2[0][0], m2[0][1], m2[1][0], m2[1][1]);
// For the case when surface is closed only in one direction it is necesary to check
// validity of orientation of the open wires in parametric space.
// In case of U closed surface wire with minimal V coordinate should be directed in positive direction by U
// In case of V closed surface wire with minimal U coordinate should be directed in negative direction by V
if (!vclosed || !uclosed)
{
Standard_Real deltaOther = 0.5 * (m2[coord][0] + m2[coord][1]) - 0.5 * (m1[coord][0] + m1[coord][1]);
if (deltaOther * isneg < 0)
{
w1.Reverse();
w2.Reverse();
}
}
// sort original wires
Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
sfw->SetFace ( myFace );
sfw->SetPrecision ( Precision() );
Handle(ShapeExtend_WireData) wd1 = new ShapeExtend_WireData ( w1 );
Handle(ShapeExtend_WireData) wd2 = new ShapeExtend_WireData ( w2 );
// sorting
// Standard_Boolean degenerated = ( secondDeg != firstDeg );
// if ( ! degenerated ) {
sfw->Load ( wd1 );
sfw->FixReorder();
// }
sfw->Load ( wd1 );
sfw->FixReorder();
sfw->Load ( wd2 );
sfw->FixReorder();
TopoDS_Wire w11 = wd1->Wire();
TopoDS_Wire w21 = wd2->Wire();
//:abv 29.08.01: reconstruct face taking into account reversing
TopoDS_Shape dummy = myFace.EmptyCopied();
TopoDS_Face tmpF = TopoDS::Face ( dummy );
tmpF.Orientation ( TopAbs_FORWARD );
for ( i=1; i <= ws.Length(); i++ ) {
TopoDS_Wire wire = TopoDS::Wire ( ws.Value(i) );
if ( wire.IsSame ( w1 ) ) wire = w1;
else if ( wire.IsSame ( w2 ) ) wire = w2;
if ( wire.IsSame ( w1 ) ) wire = w11;
else if ( wire.IsSame ( w2 ) ) wire = w21;
else
{
// other wires (not boundary) are considered as holes; make sure to have them oriented accordingly
TopoDS_Shape curface = tmpF.EmptyCopied();
B.Add(curface,wire);
curface.Orientation ( myFace.Orientation() );
if( ShapeAnalysis::IsOuterBound(TopoDS::Face(curface)))
wire.Reverse();
}
B.Add ( tmpF, wire );
}
tmpF.Orientation ( myFace.Orientation() );
Standard_Real uf=SUF, vf=SVF;
// A special kind of FixShifted is necessary for torus-like
// surfaces to adjust wires by period ALONG the missing SEAM direction
// tr9_r0501-ug.stp #187640
if ( uclosed && vclosed ) {
Standard_Integer coord = ( ismodeu ? 1 : 0 );
Standard_Integer isneg = ( ismodeu ? ismodeu : -ismodev );
Standard_Real period = ( ismodeu ? URange : VRange );
TopoDS_Shape S;
Standard_Real m1[2][2], m2[2][2];
S = tmpF.EmptyCopied();
B.Add ( S, w1 );
ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m1[0][0], m1[0][1], m1[1][0], m1[1][1]);
S = tmpF.EmptyCopied();
B.Add ( S, w2 );
ShapeAnalysis::GetFaceUVBounds (TopoDS::Face(S), m2[0][0], m2[0][1], m2[1][0], m2[1][1]);
Standard_Real shiftw2 =
ShapeAnalysis::AdjustByPeriod ( 0.5 * ( m2[coord][0] + m2[coord][1] ),
0.5 * ( m1[coord][0] + m1[coord][1] +
@@ -1711,9 +1732,10 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
if(it.Value().ShapeType() != TopAbs_WIRE)
continue;
TopoDS_Wire w = TopoDS::Wire ( it.Value() );
if ( w == w1 ) continue;
if ( w == w11 ) continue;
Standard_Real shift;
if ( w == w2 ) shift = shiftw2;
if ( w == w21 ) shift = shiftw2;
else {
S = tmpF.EmptyCopied();
B.Add ( S, w );

View File

@@ -223,6 +223,7 @@ Standard_Boolean ShapeFix_IntersectionTool::CutEdge(const TopoDS_Edge &edge,
return Standard_True;
}
}
return Standard_False;
}
@@ -1651,7 +1652,11 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
if(Abs(pend-p11)>Abs(pend-p12)) cut=p12;
else cut=p11;
Standard_Boolean IsCutLine;
CutEdge(edge1, pend, cut, face, IsCutLine);
if(!CutEdge(edge1, pend, cut, face, IsCutLine))
{
IsModified1 = Standard_False;
continue;
}
if(newtol>BRep_Tool::Tolerance(NewV)) {
B.UpdateVertex(NewV,newtol*1.00001);
}
@@ -1698,14 +1703,20 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
if(Abs(pend-p21)>Abs(pend-p22)) cut=p22;
else cut=p21;
Standard_Boolean IsCutLine;
CutEdge(edge2, pend, cut, face, IsCutLine);
if(!CutEdge(edge2, pend, cut, face, IsCutLine))
{
IsModified2 = Standard_False;
continue;
}
if(newtol>BRep_Tool::Tolerance(NewV)) {
B.UpdateVertex(NewV,newtol*1.00001);
}
}
if( IsModified1 || IsModified2 ) {
//num2--;
//necessary to make intersect with the same pair of the edges once again with modified ranges
num2--;
hasModifWire = Standard_True; //gka 06.09.04
continue;
}