From 8e509b0ba194e9c502997dfc1000c9d4f9672a08 Mon Sep 17 00:00:00 2001 From: oan Date: Thu, 28 Apr 2016 19:07:15 +0300 Subject: [PATCH] 0027442: Rotation sweep can't be rendered in 3D Do not insert internal nodes for Cylinder in case if it is less than DefFace value or in case of long cylinder with small radius due to protection against overflow during casting to integer. Small correction of shape name in test case for issue CR27442 --- src/BRepMesh/BRepMesh_FastDiscretFace.cxx | 32 +++++++++++++++-------- tests/bugs/mesh/bug27442 | 21 +++++++++++++++ 2 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 tests/bugs/mesh/bug27442 diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx index a43cd9b29d..7d8882d1e4 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx @@ -617,19 +617,29 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesCylinder( gp_Cylinder aCylinder = myAttribute->Surface()->Cylinder(); const Standard_Real aRadius = aCylinder.Radius(); - // Calculate parameters for iteration in U direction - Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep( - aRadius, myAttribute->GetDefFace(), myAngle, myMinSize); - + Standard_Integer nbU = 0; + Standard_Integer nbV = 0; const Standard_Real su = umax - umin; - const Standard_Integer nbU = (Standard_Integer)(su / Du); - Du = su / (nbU + 1); - - // Calculate parameters for iteration in V direction const Standard_Real sv = vmax - vmin; - Standard_Integer nbV = (Standard_Integer)(nbU*sv / (su*aRadius)); - nbV = Min(nbV, 100 * nbU); - Standard_Real Dv = sv / (nbV + 1); + const Standard_Real aArcLen = su * aRadius; + if (aArcLen > myAttribute->GetDefFace ()) + { + // Calculate parameters for iteration in U direction + const Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep ( + aRadius, myAttribute->GetDefFace (), myAngle, myMinSize); + nbU = (Standard_Integer)(su / Du); + + // Calculate parameters for iteration in V direction + const Standard_Real aDv = nbU*sv / aArcLen; + // Protection against overflow during casting to int in case + // of long cylinder with small radius. + nbV = aDv > static_cast (IntegerLast ()) ? + 0 : (Standard_Integer)(aDv); + nbV = Min (nbV, 100 * nbU); + } + + const Standard_Real Du = su / (nbU + 1); + const Standard_Real Dv = sv / (nbV + 1); Standard_Real pasu, pasv, pasvmax = vmax - Dv*0.5, pasumax = umax - Du*0.5; for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv) diff --git a/tests/bugs/mesh/bug27442 b/tests/bugs/mesh/bug27442 new file mode 100644 index 0000000000..e477d6e177 --- /dev/null +++ b/tests/bugs/mesh/bug27442 @@ -0,0 +1,21 @@ +puts "=========" +puts "OCC27442" +puts "=========" +puts "" +################################# +# Rotation sweep can't be rendered in 3D +################################# +cpulimit 20 + +pload ALL +restore [locate_data_file bug27442_facerot.brep] f +revol result f 444.5 -958.0 4 0 1 0 95 +vdisplay result +vsetdispmode 1 +vfit + +# relative tolerance (%) +set rel_tol 1 +set area_eps 0 + +checkview -screenshot -3d -path ${imagedir}/${test_image}.png \ No newline at end of file