From b0f92d3d5c78548a1e5d14f7b7c28463a3981092 Mon Sep 17 00:00:00 2001 From: ona Date: Wed, 7 Sep 2022 18:48:09 +0300 Subject: [PATCH] 0032239: Data Exchange, STEP import - bounding box is too large - ShapeFix_Face::FixMissingSeam method is fixed in order to handle degenerated torus - Calculation of degenerated torus bounding box is fixed - Test reference data is changed --- src/BndLib/BndLib.cxx | 106 +++++++++++++++++++++++++++++++++ src/ShapeFix/ShapeFix_Face.cxx | 21 ++++++- tests/bugs/moddata_1/bug15 | 2 +- tests/bugs/step/bug32239 | 57 ++++++++++++++++++ 4 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 tests/bugs/step/bug32239 diff --git a/src/BndLib/BndLib.cxx b/src/BndLib/BndLib.cxx index 67f372816f..adbd0238bc 100644 --- a/src/BndLib/BndLib.cxx +++ b/src/BndLib/BndLib.cxx @@ -1221,6 +1221,105 @@ static void ComputeSphere (const gp_Sphere& Sphere, } } +//======================================================================= +//function : computeDegeneratedTorus +//purpose : compute bounding box for degenerated torus +//======================================================================= + +static void computeDegeneratedTorus (const gp_Torus& theTorus, + const Standard_Real theUMin, const Standard_Real theUMax, + const Standard_Real theVMin, const Standard_Real theVMax, + Bnd_Box& theB) +{ + gp_Pnt aP = theTorus.Location(); + Standard_Real aRa = theTorus.MajorRadius(); + Standard_Real aRi = theTorus.MinorRadius(); + Standard_Real aXmin,anYmin,aZmin,aXmax,anYmax,aZmax; + aXmin = aP.X() - aRa - aRi; + aXmax = aP.X() + aRa + aRi; + anYmin = aP.Y() - aRa - aRi; + anYmax = aP.Y() + aRa + aRi; + aZmin = aP.Z() - aRi; + aZmax = aP.Z() + aRi; + + Standard_Real aPhi = ACos (-aRa / aRi); + + Standard_Real anUper = 2. * M_PI - Precision::PConfusion(); + Standard_Real aVper = 2. * aPhi - Precision::PConfusion(); + if (theUMax - theUMin >= anUper && theVMax - theVMin >= aVper) + { + // a whole torus + theB.Update(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax); + return; + } + + Standard_Real anU,aV; + Standard_Real anUmax = theUMin + 2. * M_PI; + const gp_Ax3& aPos = theTorus.Position(); + gp_Pnt aPExt = aP; + aPExt.SetX(aXmin); + ElSLib::TorusParameters(aPos,aRa,aRi,aPExt,anU,aV); + anU = ElCLib::InPeriod(anU,theUMin,anUmax); + if(anU >= theUMin && anU <= theUMax && aV >= theVMin && aV <= theVMax) + { + theB.Add(aPExt); + } + // + aPExt.SetX(aXmax); + ElSLib::TorusParameters(aPos,aRa,aRi,aPExt,anU,aV); + anU = ElCLib::InPeriod(anU,theUMin,anUmax); + if(anU >= theUMin && anU <= theUMax && aV >= theVMin && aV <= theVMax) + { + theB.Add(aPExt); + } + aPExt.SetX(aP.X()); + // + aPExt.SetY(anYmin); + ElSLib::TorusParameters(aPos,aRa,aRi,aPExt,anU,aV); + anU = ElCLib::InPeriod(anU,theUMin,anUmax); + if(anU >= theUMin && anU <= theUMax && aV >= theVMin && aV <= theVMax) + { + theB.Add(aPExt); + } + // + aPExt.SetY(anYmax); + ElSLib::TorusParameters(aPos,aRa,aRi,aPExt,anU,aV); + anU = ElCLib::InPeriod(anU,theUMin,anUmax); + if(anU >= theUMin && anU <= theUMax && aV >= theVMin && aV <= theVMax) + { + theB.Add(aPExt); + } + aPExt.SetY(aP.Y()); + // + aPExt.SetZ(aZmin); + ElSLib::TorusParameters(aPos,aRa,aRi,aPExt,anU,aV); + anU = ElCLib::InPeriod(anU,theUMin,anUmax); + if(anU >= theUMin && anU <= theUMax && aV >= theVMin && aV <= theVMax) + { + theB.Add(aPExt); + } + // + aPExt.SetZ(aZmax); + ElSLib::TorusParameters(aPos,aRa,aRi,aPExt,anU,aV); + anU = ElCLib::InPeriod(anU,theUMin,anUmax); + if(anU >= theUMin && anU <= theUMax && aV >= theVMin && aV <= theVMax) + { + theB.Add(aPExt); + } + // + // Add boundaries of patch + // UMin, UMax + gp_Circ aC = ElSLib::TorusUIso(aPos,aRa,aRi,theUMin); + BndLib::Add(aC,theVMin,theVMax,0.,theB); + aC = ElSLib::TorusUIso(aPos,aRa,aRi,theUMax); + BndLib::Add(aC,theVMin,theVMax,0.,theB); + // VMin, VMax + aC = ElSLib::TorusVIso(aPos,aRa,aRi,theVMin); + BndLib::Add(aC,theUMin,theUMax,0.,theB); + aC = ElSLib::TorusVIso(aPos,aRa,aRi,theVMax); + BndLib::Add(aC,theUMin,theUMax,0.,theB); +} + void BndLib::Add(const gp_Sphere& S,const Standard_Real UMin, const Standard_Real UMax,const Standard_Real VMin, const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) @@ -1265,6 +1364,13 @@ void BndLib::Add(const gp_Torus& S,const Standard_Real UMin, if (Fi2 #include #include +#include #include #include #include @@ -1585,6 +1586,9 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam() } BRep_Builder B; + Handle(Geom_ToroidalSurface) aTorSurf = Handle(Geom_ToroidalSurface)::DownCast(mySurf->Surface()); + Standard_Boolean anIsDegeneratedTor = ( aTorSurf.IsNull() ? Standard_False : aTorSurf->MajorRadius() < aTorSurf->MinorRadius() ); + if ( w1.IsNull() ) return Standard_False; else if ( w2.IsNull()) { // For spheres and BSpline cone-like surfaces(bug 24055): @@ -1595,7 +1599,18 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam() gp_Dir2d d; Standard_Real aRange; - if ( ismodeu && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) { + if( ismodeu && anIsDegeneratedTor ) + { + Standard_Real aRa = aTorSurf->MajorRadius(); + Standard_Real aRi = aTorSurf->MinorRadius(); + Standard_Real aPhi = ACos (-aRa / aRi); + p.SetCoord (0.0, ( ismodeu > 0 ? M_PI + aPhi : aPhi )); + + Standard_Real aXCoord = -ismodeu; + d.SetCoord ( aXCoord, 0.); + aRange = 2.*M_PI; + } + else if ( ismodeu && mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) { p.SetCoord ( ( ismodeu < 0 ? 0. : 2.*M_PI ), ismodeu * 0.5 * M_PI ); Standard_Real aXCoord = -ismodeu; d.SetCoord ( aXCoord, 0.); @@ -1663,7 +1678,7 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam() // 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) + if (!vclosed || !uclosed || anIsDegeneratedTor) { Standard_Real deltaOther = 0.5 * (m2[coord][0] + m2[coord][1]) - 0.5 * (m1[coord][0] + m1[coord][1]); if (deltaOther * isneg < 0) @@ -1711,7 +1726,7 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam() // 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 ) { + if ( uclosed && vclosed && !anIsDegeneratedTor ) { Standard_Real shiftw2 = ShapeAnalysis::AdjustByPeriod ( 0.5 * ( m2[coord][0] + m2[coord][1] ), 0.5 * ( m1[coord][0] + m1[coord][1] + diff --git a/tests/bugs/moddata_1/bug15 b/tests/bugs/moddata_1/bug15 index 0a25f8328e..ad0d312a0e 100755 --- a/tests/bugs/moddata_1/bug15 +++ b/tests/bugs/moddata_1/bug15 @@ -14,5 +14,5 @@ vdisplay result vsetdispmode result 1 vfit -checktrinfo result -tri 1075 -nod 635 +checktrinfo result -tri 1317 -nod 756 checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/step/bug32239 b/tests/bugs/step/bug32239 new file mode 100644 index 0000000000..7602c50b33 --- /dev/null +++ b/tests/bugs/step/bug32239 @@ -0,0 +1,57 @@ +puts "====================================" +puts "0032239: Data Exchange, STEP import - bounding box is too large" +puts "====================================" +puts "" + +pload ALL + +# Read file + +stepread [locate_data_file bug32239.STEP] b * + +# Check that shape is valid + +checkshape b_1 + +# Check bounding box + +set xmin0 -62.992562093513783 +set ymin0 -51.45371311501097 +set zmin0 -33.223762093513777 +set xmax0 43.263112093513783 +set ymax0 33.211062093513789 +set zmax0 37.744962093513792 +set bb [bounding b_1] +set xmin [lindex $bb 0] +set ymin [lindex $bb 1] +set zmin [lindex $bb 2] +set xmax [lindex $bb 3] +set ymax [lindex $bb 4] +set zmax [lindex $bb 5] + +if { [expr abs($xmin - $xmin0)] > 1.0e-5 } { + set bb_changed 1 +} +if { [expr abs($xmax - $xmax0)] > 1.0e-5 } { + set bb_changed 1 +} +if { [expr abs($ymin - $ymin0)] > 1.0e-5 } { + set bb_changed 1 +} +if { [expr abs($ymax - $ymax0)] > 1.0e-5 } { + set bb_changed 1 +} +if { [expr abs($zmin - $zmin0)] > 1.0e-5 } { + set bb_changed 1 +} +if { [expr abs($zmax - $zmax0)] > 1.0e-5 } { + set bb_changed 1 +} + +if { [info exists bb_changed] } { + puts "Error: not expected bounding box" +} + +renamevar b_1 result +checkview -display result -3d -path ${imagedir}/${test_image}.png +