1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-09 18:50:54 +03:00

0026440: Invalid shape as a result of solid construction in BRepOffset_MakeOffset

Fixed degeneration in wall building in thicksolid mode.

Minor correction.

Test cases for issue CR26440
This commit is contained in:
aml 2015-09-03 14:40:03 +03:00 committed by bugmaster
parent d18c1ac06e
commit a8704c363d
5 changed files with 509 additions and 348 deletions

View File

@ -109,6 +109,8 @@
#include <TopTools_MapIteratorOfMapOfShape.hxx> #include <TopTools_MapIteratorOfMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx> #include <TopTools_SequenceOfShape.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <Geom_Line.hxx>
#include <stdio.h> #include <stdio.h>
// POP for NT // POP for NT
@ -524,6 +526,7 @@ void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
myJoin = Join; myJoin = Join;
myThickening = Thickening; myThickening = Thickening;
myDone = Standard_False; myDone = Standard_False;
myIsPerformSewing = Standard_False;
Clear(); Clear();
} }
@ -659,6 +662,7 @@ static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
} }
} }
//======================================================================= //=======================================================================
//function : MakeOffsetShape //function : MakeOffsetShape
//purpose : //purpose :
@ -778,6 +782,21 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
CorrectConicalFaces(); CorrectConicalFaces();
// Result solid should be computed in MakeOffset scope.
if (myThickening &&
myIsPerformSewing)
{
BRepBuilderAPI_Sewing aSew(myTol);
aSew.Add(myOffsetShape);
aSew.Perform();
myOffsetShape = aSew.SewedShape();
// Rebuild solid.
// Offset shape expected to be really closed after sewing.
myOffsetShape.Closed(Standard_True);
MakeSolid();
}
myDone = Standard_True; myDone = Standard_True;
} }
@ -2491,7 +2510,6 @@ static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
//function : MakeMissingWalls //function : MakeMissingWalls
//purpose : //purpose :
//======================================================================= //=======================================================================
void BRepOffset_MakeOffset::MakeMissingWalls () void BRepOffset_MakeOffset::MakeMissingWalls ()
{ {
TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary) TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
@ -2510,23 +2528,61 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
Standard_Boolean FirstStep = Standard_True; Standard_Boolean FirstStep = Standard_True;
TopoDS_Edge PrevEdge; TopoDS_Edge PrevEdge;
TopoDS_Vertex PrevVertex = StartVertex; TopoDS_Vertex PrevVertex = StartVertex;
Standard_Boolean isBuildFromScratch = Standard_False; // Problems with edges.
for (; itl.More(); itl.Next()) for (; itl.More(); itl.Next())
{ {
TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
// Check for offset existence.
if (!myInitOffsetEdge.HasImage(anEdge)) if (!myInitOffsetEdge.HasImage(anEdge))
continue; continue;
//if (BRep_Tool::Degenerated(anEdge))
//continue; // Check for existence of two different vertices.
TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
//TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
TopTools_ListOfShape LOE, LOE2; TopTools_ListOfShape LOE, LOE2;
myInitOffsetEdge.LastImage( anEdge, LOE ); myInitOffsetEdge.LastImage( anEdge, LOE );
myImageOffset.LastImage( LOE.Last(), LOE2 ); myImageOffset.LastImage( LOE.Last(), LOE2 );
TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() ); TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
////////////////////////////////////////////////////////////////////////
TopoDS_Vertex V1, V2, V3, V4; TopoDS_Vertex V1, V2, V3, V4;
TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/); TopExp::Vertices(OE, V4, V3);
TopExp::Vertices(OE, V4, V3/*, Standard_True*/); TopExp::Vertices(anEdge, V1, V2);
Standard_Real aF, aL;
const Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aF, aL);
if (!aC.IsNull() &&
(!aC->IsClosed() && !aC->IsPeriodic()))
{
gp_Pnt aPntF = BRep_Tool::Pnt(V1);
gp_Pnt aPntL = BRep_Tool::Pnt(V2);
Standard_Real aDistE = aPntF.SquareDistance(aPntL);
if ( aDistE < Precision::SquareConfusion())
{
// Bad case: non closed, but vertexes mapped to same 3d point.
continue;
}
Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
if (aDistE < anEdgeTol)
{
// Potential problems not detected via checkshape.
gp_Pnt aPntOF = BRep_Tool::Pnt(V4);
gp_Pnt aPntOL = BRep_Tool::Pnt(V3);
if (aPntOF.SquareDistance(aPntOL) > gp::Resolution())
{
// To avoid computation of complex analytical continuation of Sin / ArcSin.
Standard_Real aSinValue = Min(2 * anEdgeTol / aPntOF.Distance(aPntOL), 1.0);
Standard_Real aMaxAngle = Min(Abs(ASin(aSinValue)), M_PI_4); // Maximal angle.
Standard_Real aCurrentAngle = gp_Vec(aPntF, aPntL).Angle(gp_Vec(aPntOF, aPntOL));
if (aC->IsKind(STANDARD_TYPE(Geom_Line)) &&
Abs (aCurrentAngle) > aMaxAngle)
{
// anEdge not collinear to offset edge.
isBuildFromScratch = Standard_True;
myIsPerformSewing = Standard_True;
continue;
}
}
}
}
Standard_Boolean ToReverse = Standard_False; Standard_Boolean ToReverse = Standard_False;
if (!V1.IsSame(PrevVertex)) if (!V1.IsSame(PrevVertex))
{ {
@ -2534,23 +2590,30 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
aVtx = V3; V3 = V4; V4 = aVtx; aVtx = V3; V3 = V4; V4 = aVtx;
ToReverse = Standard_True; ToReverse = Standard_True;
} }
//Temporary
//anEdge.Reverse();
OE.Orientation(TopAbs::Reverse(anEdge.Orientation())); OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
TopoDS_Edge E3, E4; TopoDS_Edge E3, E4;
if (FirstStep) Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
if (FirstStep || isBuildFromScratch)
{ {
E4 = BRepLib_MakeEdge( V1, V4 ); E4 = BRepLib_MakeEdge( V1, V4 );
if (FirstStep)
StartEdge = E4; StartEdge = E4;
} }
else else
E4 = PrevEdge; E4 = PrevEdge;
Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
if (V2.IsSame(StartVertex) && !ArcOnV2) if (V2.IsSame(StartVertex) && !ArcOnV2)
E3 = StartEdge; E3 = StartEdge;
else else
E3 = BRepLib_MakeEdge( V2, V3 ); E3 = BRepLib_MakeEdge( V2, V3 );
E4.Reverse(); E4.Reverse();
if (isBuildFromScratch)
{
E3.Reverse();
E4.Reverse();
}
TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD); TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge); const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD); Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
@ -2572,6 +2635,7 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
BB.Add(theWire, OE); BB.Add(theWire, OE);
BB.Add(theWire, E4); BB.Add(theWire, E4);
} }
BRepLib::BuildCurves3d( theWire, myTol ); BRepLib::BuildCurves3d( theWire, myTol );
theWire.Closed(Standard_True); theWire.Closed(Standard_True);
TopoDS_Face NewFace; TopoDS_Face NewFace;
@ -2850,10 +2914,19 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
PrevVertex = V2; PrevVertex = V2;
} }
else else
{
if (isBuildFromScratch)
{
PrevEdge = TopoDS::Edge(E4);
PrevVertex = V1;
isBuildFromScratch = Standard_False;
}
else
{ {
PrevEdge = E3; PrevEdge = E3;
PrevVertex = V2; PrevVertex = V2;
} }
}
FirstStep = Standard_False; FirstStep = Standard_False;
} }
} }

View File

@ -161,6 +161,7 @@ private:
Standard_Boolean myDone; Standard_Boolean myDone;
BRepOffset_Error myError; BRepOffset_Error myError;
BRepOffset_MakeLoops myMakeLoops; BRepOffset_MakeLoops myMakeLoops;
Standard_Boolean myIsPerformSewing; // Handle bad walls in thicksolid mode.
}; };

29
tests/bugs/modalg_6/bug26440_1 Executable file
View File

@ -0,0 +1,29 @@
puts "============"
puts "CR26440"
puts "============"
puts ""
##########################################################################################################
# Invalid shape as a result of solid construction in BRepOffset_MakeOffset
##########################################################################################################
restore [locate_data_file bug26440_plate.brep] sh1
thickshell result sh1 160
set square 2.40831e+07
set nbshapes_expected "
Number of shapes in shape
VERTEX : 196
EDGE : 308
WIRE : 110
FACE : 110
SHELL : 1
SOLID : 1
COMPSOLID : 0
COMPOUND : 0
SHAPE : 726
"
checknbshapes result -ref ${nbshapes_expected} -t -m "solid construction"
set 3dviewer 1

29
tests/bugs/modalg_6/bug26440_2 Executable file
View File

@ -0,0 +1,29 @@
puts "============"
puts "CR26440"
puts "============"
puts ""
##########################################################################################################
# Invalid shape as a result of solid construction in BRepOffset_MakeOffset
##########################################################################################################
restore [locate_data_file bug26440_plate2.brep] sh1
thickshell result sh1 150 i
set square 5.00111e+06
set nbshapes_expected "
Number of shapes in shape
VERTEX : 146
EDGE : 225
WIRE : 75
FACE : 75
SHELL : 1
SOLID : 1
COMPSOLID : 0
COMPOUND : 0
SHAPE : 523
"
checknbshapes result -ref ${nbshapes_expected} -t -m "solid construction"
set 3dviewer 1

29
tests/bugs/modalg_6/bug26440_3 Executable file
View File

@ -0,0 +1,29 @@
puts "============"
puts "CR26440"
puts "============"
puts ""
##########################################################################################################
# Invalid shape as a result of solid construction in BRepOffset_MakeOffset
##########################################################################################################
restore [locate_data_file bug26440_plate3.brep] sh1
thickshell result sh1 160 i
set square 1.26188e+07
set nbshapes_expected "
Number of shapes in shape
VERTEX : 88
EDGE : 145
WIRE : 55
FACE : 55
SHELL : 1
SOLID : 1
COMPSOLID : 0
COMPOUND : 0
SHAPE : 345
"
checknbshapes result -ref ${nbshapes_expected} -t -m "solid construction"
set 3dviewer 1