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

0024964: ThruSections crashes the DRAW.exe

Test case for issue CR24964
This commit is contained in:
jgv
2014-06-19 13:27:27 +04:00
committed by apn
parent 9bdafcbe2d
commit e01907f12a
2 changed files with 189 additions and 158 deletions

View File

@@ -105,7 +105,7 @@
//=======================================================================
static Standard_Real PreciseUpar(const Standard_Real anUpar,
const Handle(Geom_BSplineSurface)& aSurface)
const Handle(Geom_BSplineSurface)& aSurface)
{
Standard_Real Tol = Precision::PConfusion();
Standard_Integer i1, i2;
@@ -126,17 +126,17 @@ static Standard_Real PreciseUpar(const Standard_Real anUpar,
//=======================================================================
static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
const Standard_Real presPln,
TopoDS_Face& theFace)
const Standard_Real presPln,
TopoDS_Face& theFace)
{
Standard_Boolean isDegen = Standard_True;
TopoDS_Iterator iter(W);
for (; iter.More(); iter.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
if (!BRep_Tool::Degenerated(anEdge))
isDegen = Standard_False;
}
{
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
if (!BRep_Tool::Degenerated(anEdge))
isDegen = Standard_False;
}
if (isDegen)
return Standard_True;
@@ -144,22 +144,22 @@ static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
if (!W.IsNull()) {
BRepBuilderAPI_FindPlane Searcher( W, presPln );
if (Searcher.Found())
{
theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
Ok = Standard_True;
}
{
theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
Ok = Standard_True;
}
else // try to find another surface
{
BRepBuilderAPI_MakeFace MF( W );
if (MF.IsDone())
{
BRepBuilderAPI_MakeFace MF( W );
if (MF.IsDone())
{
theFace = MF.Face();
Ok = Standard_True;
}
theFace = MF.Face();
Ok = Standard_True;
}
}
}
return Ok;
return Ok;
}
//=============================================================================
@@ -168,7 +168,7 @@ static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
//=============================================================================
static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
const TopoDS_Shape& aShell)
const TopoDS_Shape& aShell)
{
TopExp_Explorer Explo(aFace, TopAbs_EDGE);
TopoDS_Shape anEdge = Explo.Current();
@@ -180,11 +180,11 @@ static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
TopoDS_Shape theEdge;
for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
{
theEdge = Explo.Current();
if (theEdge.IsSame(anEdge))
break;
}
{
theEdge = Explo.Current();
if (theEdge.IsSame(anEdge))
break;
}
TopAbs_Orientation Or2 = theEdge.Orientation();
if (Or1 == Or2)
@@ -198,8 +198,8 @@ static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
//=======================================================================
static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
const TopoDS_Wire& wire2, const Standard_Real presPln,
TopoDS_Face& face1, TopoDS_Face& face2)
const TopoDS_Wire& wire2, const Standard_Real presPln,
TopoDS_Face& face1, TopoDS_Face& face2)
{
if (shell.IsNull())
StdFail_NotDone::Raise("Thrusections is not build");
@@ -207,26 +207,26 @@ static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
BRep_Builder BB;
if (!B)
{
// It is necessary to close the extremities
B = PerformPlan(wire1, presPln, face1);
{
// It is necessary to close the extremities
B = PerformPlan(wire1, presPln, face1);
if (B) {
B = PerformPlan(wire2, presPln, face2);
if (B) {
B = PerformPlan(wire2, presPln, face2);
if (B) {
if (!face1.IsNull() && !IsSameOriented( face1, shell ))
face1.Reverse();
if (!face2.IsNull() && !IsSameOriented( face2, shell ))
face2.Reverse();
if (!face1.IsNull() && !IsSameOriented( face1, shell ))
face1.Reverse();
if (!face2.IsNull() && !IsSameOriented( face2, shell ))
face2.Reverse();
if (!face1.IsNull())
BB.Add(shell, face1);
if (!face2.IsNull())
BB.Add(shell, face2);
if (!face1.IsNull())
BB.Add(shell, face1);
if (!face2.IsNull())
BB.Add(shell, face2);
shell.Closed(Standard_True);
}
shell.Closed(Standard_True);
}
}
}
TopoDS_Solid solid;
BB.MakeSolid(solid);
@@ -239,7 +239,7 @@ static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
BB.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
BB.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(newShell.Reversed()));
// B.Add(solid, TopoDS::Shell(newShell.Reversed()));
}
solid.Closed(Standard_True);
@@ -253,11 +253,11 @@ static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
//=======================================================================
BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled,
const Standard_Real pres3d):
myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
const Standard_Real pres3d):
myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
{
myWCheck = Standard_True;
//----------------------------
//----------------------------
myParamType = Approx_ChordLength;
myDegMax = 8;
myContinuity = GeomAbs_C2;
@@ -274,13 +274,13 @@ BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean is
//=======================================================================
void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
const Standard_Real pres3d)
const Standard_Real pres3d)
{
myIsSolid = isSolid;
myIsRuled = ruled;
myPres3d = pres3d;
myWCheck = Standard_True;
//----------------------------
//----------------------------
myParamType = Approx_ChordLength;
myDegMax = 6;
myContinuity = GeomAbs_C2;
@@ -348,28 +348,28 @@ void BRepOffsetAPI_ThruSections::Build()
Standard_Integer i;
TopExp_Explorer explo;
for (i = 2; i <= myWires.Length()-1; i++)
{
Standard_Boolean wdeg = Standard_True;
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
Standard_Boolean wdeg = Standard_True;
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
Standard_Failure::Raise("Wrong usage of punctual sections");
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
Standard_Failure::Raise("Wrong usage of punctual sections");
}
if (myWires.Length() <= 2)
{
Standard_Boolean wdeg = Standard_True;
for (i = 1; i <= myWires.Length(); i++)
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
{
Standard_Boolean wdeg = Standard_True;
for (i = 1; i <= myWires.Length(); i++)
for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
Standard_Failure::Raise("Wrong usage of punctual sections");
}
Standard_Failure::Raise("Wrong usage of punctual sections");
}
if (myWCheck) {
// compute origin and orientation on wires to avoid twisted results
@@ -415,7 +415,7 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
{
Standard_Integer nbSects = myWires.Length();
BRepFill_Generator aGene;
// for (Standard_Integer i=1; i<=nbSects; i++) {
// for (Standard_Integer i=1; i<=nbSects; i++) {
Standard_Integer i;
for (i=1; i<=nbSects; i++) {
aGene.AddWire(TopoDS::Wire(myWires(i)));
@@ -439,10 +439,10 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
BRepClass3d_SolidClassifier clas3d(solid);
clas3d.PerformInfinitePoint(Precision::Confusion());
if (clas3d.State() == TopAbs_IN) {
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
}
myShape = solid;
@@ -492,35 +492,35 @@ void BRepOffsetAPI_ThruSections::CreateRuled()
TopTools_MapOfShape MapFaces;
if (degen2){
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
}
else {
for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
MapFaces.Add(it.Value());
}
}
if (degen1) {
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
}
else {
for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
const TopoDS_Shape& Face = it.Value();
if (MapFaces.Contains(Face)) {
myGenerated.Bind(edge1, Face);
break;
}
}
}
if (!degen1) anExp1.Next();
@@ -593,15 +593,15 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// if the wire is punctual
anExp.Init(TopoDS::Wire(wire));
for(j=1; j<=nbEdges; j++) {
nb++;
shapes(nb) = anExp.Current();
nb++;
shapes(nb) = anExp.Current();
}
}
else {
// otherwise
for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
nb++;
shapes(nb) = anExp.Current();
nb++;
shapes(nb) = anExp.Current();
}
}
}
@@ -677,7 +677,7 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// copy the degenerated edge
TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
edge1 = TopoDS::Edge(aLocalShape);
// edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
// edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
edge1.Orientation(TopAbs_FORWARD);
}
else {
@@ -699,14 +699,14 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
edge2 = TopoDS::Edge(vcouture(i));
else {
if ( w2Point ) {
// copy of the degenerated edge
TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
edge2 = TopoDS::Edge(aLocalShape);
// edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
edge2.Orientation(TopAbs_FORWARD);
// copy of the degenerated edge
TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
edge2 = TopoDS::Edge(aLocalShape);
// edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
edge2.Orientation(TopAbs_FORWARD);
}
else {
B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
}
v2f.Orientation(TopAbs_FORWARD);
B.Add(edge2, v2f);
@@ -726,7 +726,7 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
B.Add(edge3, v2f);
B.Range(edge3, f2, l2);
if (uClosed) {
couture = edge3;
couture = edge3;
}
}
else {
@@ -755,34 +755,34 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
// set PCurve
if (vClosed) {
B.UpdateEdge(edge1,
new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
Precision::Confusion());
new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
Precision::Confusion());
B.Range(edge1,face,f1,l1);
}
else {
B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge1,face,f1,l1);
B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge2,face,f1,l1);
}
if ( uClosed && nbEdges ==1 ) {
B.UpdateEdge(edge3,
new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
B.Range(edge3,face,f2,l2);
}
else {
B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge3,face,f2,l2);
B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
Precision::Confusion());
Precision::Confusion());
B.Range(edge4,face,f2,l2);
}
B.Add(face,W);
@@ -816,10 +816,10 @@ void BRepOffsetAPI_ThruSections::CreateSmoothed()
BRepClass3d_SolidClassifier clas3d(solid);
clas3d.PerformInfinitePoint(Precision::Confusion());
if (clas3d.State() == TopAbs_IN) {
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
B.MakeSolid(solid);
TopoDS_Shape aLocalShape = shell.Reversed();
B.Add(solid, TopoDS::Shell(aLocalShape));
// B.Add(solid, TopoDS::Shell(shell.Reversed()));
}
myShape = solid;
@@ -924,15 +924,14 @@ static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge)
//=======================================================================
Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
TotalSurf(const TopTools_Array1OfShape& shapes,
const Standard_Integer NbSects,
const Standard_Integer NbEdges,
const Standard_Boolean w1Point,
const Standard_Boolean w2Point,
const Standard_Boolean vClosed) const
TotalSurf(const TopTools_Array1OfShape& shapes,
const Standard_Integer NbSects,
const Standard_Integer NbEdges,
const Standard_Boolean w1Point,
const Standard_Boolean w2Point,
const Standard_Boolean vClosed) const
{
Standard_Integer i,j,jdeb=1,jfin=NbSects;
TopoDS_Edge edge;
TopoDS_Vertex vf,vl;
GeomFill_SectionGenerator section;
@@ -943,7 +942,7 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
if (w1Point) {
jdeb++;
edge = TopoDS::Edge(shapes(1));
TopoDS_Edge edge = TopoDS::Edge(shapes(1));
TopExp::Vertices(edge,vl,vf);
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = BRep_Tool::Pnt(vf);
@@ -979,12 +978,17 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
for (i=2; i<=NbEdges; i++) {
// read the edge
// read the edge
TopoDS_Edge aNextEdge = TopoDS::Edge (shapes((j-1)*NbEdges+i));
Standard_Real aTolV = Precision::Confusion();
TopExp::Vertices(aNextEdge,vf,vl);
aTolV = Max(aTolV, BRep_Tool::Tolerance(vf));
aTolV = Max(aTolV, BRep_Tool::Tolerance(vl));
aTolV = Min(aTolV, 1.e-3);
curvBS = EdgeToBSpline (aNextEdge);
// concatenation
CompBS.Add(curvBS, Precision::Confusion(), Standard_True, Standard_False, 1);
// concatenation
CompBS.Add(curvBS, aTolV, Standard_True, Standard_False, 1);
}
// return the final section
@@ -993,14 +997,14 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
// case of looping sections
if (j==jdeb && vClosed) {
BS1 = BS;
BS1 = BS;
}
}
}
if (w2Point) {
edge = TopoDS::Edge(shapes(NbSects*NbEdges));
TopoDS_Edge edge = TopoDS::Edge(shapes(NbSects*NbEdges));
TopExp::Vertices(edge,vl,vf);
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = BRep_Tool::Pnt(vf);
@@ -1040,9 +1044,9 @@ Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
if(anApprox.IsDone()) {
surface =
new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
anApprox.SurfUKnots(), anApprox.SurfVKnots(),
anApprox.SurfUMults(), anApprox.SurfVMults(),
anApprox.UDegree(), anApprox.VDegree());
anApprox.SurfUKnots(), anApprox.SurfVKnots(),
anApprox.SurfUMults(), anApprox.SurfVMults(),
anApprox.UDegree(), anApprox.VDegree());
}
return surface;

View File

@@ -0,0 +1,27 @@
puts "============"
puts "OCC24964"
puts "============"
puts ""
#########################################################################
# ThruSections crashes the DRAW.exe
#########################################################################
restore [locate_data_file bug24964_w1.brep] w1
restore [locate_data_file bug24964_w2.brep] w2
restore [locate_data_file bug24964_w3.brep] w3
thrusections result 0 0 w1 w2 w3
set square 163127
set nb_v_good 30
set nb_e_good 45
set nb_w_good 15
set nb_f_good 15
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 106
set 2dviewer 1