From 0b1eca802805f09a6ca7abefa7cc7aacae3c4169 Mon Sep 17 00:00:00 2001 From: Jeremy Wright Date: Tue, 15 Aug 2023 09:11:03 -0400 Subject: [PATCH 1/2] Fix for incorrect tapered extrude height found in #1383 --- cadquery/occ_impl/shapes.py | 39 +++++++++++++++++++------------------ tests/test_cadquery.py | 27 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index a3d4a8e9d..c7de1a02c 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -244,7 +244,7 @@ from OCP.BRepAlgo import BRepAlgo -from math import pi, sqrt, inf +from math import pi, sqrt, inf, radians, cos import warnings @@ -253,7 +253,6 @@ Real = Union[float, int] TOLERANCE = 1e-6 -DEG2RAD = 2 * pi / 360.0 HASH_CODE_MAX = 2147483647 # max 32bit signed int, required by OCC.Core.HashCode shape_LUT = { @@ -900,7 +899,7 @@ def rotate( Vector(startVector).toPnt(), (Vector(endVector) - Vector(startVector)).toDir(), ), - angleDegrees * DEG2RAD, + radians(angleDegrees), ) return self._apply_transform(Tr) @@ -1757,7 +1756,7 @@ def makeCircle( return cls(BRepBuilderAPI_MakeEdge(circle_gp).Edge()) else: # arc case circle_geom = GC_MakeArcOfCircle( - circle_gp, angle1 * DEG2RAD, angle2 * DEG2RAD, orientation + circle_gp, radians(angle1), radians(angle2), orientation ).Value() return cls(BRepBuilderAPI_MakeEdge(circle_geom).Edge()) @@ -1796,7 +1795,7 @@ def makeEllipse( if y_radius > x_radius: # swap x and y radius and rotate by 90° afterwards to create an ellipse with x_radius < y_radius - correction_angle = 90.0 * DEG2RAD + correction_angle = radians(90.0) ellipse_gp = gp_Elips(ax2, y_radius, x_radius).Rotated( ax1, correction_angle ) @@ -1810,8 +1809,8 @@ def makeEllipse( # take correction_angle into account ellipse_geom = GC_MakeArcOfEllipse( ellipse_gp, - angle1 * DEG2RAD - correction_angle, - angle2 * DEG2RAD - correction_angle, + radians(angle1) - correction_angle, + radians(angle2) - correction_angle, sense == 1, ).Value() ellipse = cls(BRepBuilderAPI_MakeEdge(ellipse_geom).Edge()) @@ -2175,7 +2174,7 @@ def makeHelix( else: geom_surf = Geom_ConicalSurface( gp_Ax3(Vector(center).toPnt(), Vector(dir).toDir()), - angle * DEG2RAD, + radians(angle), radius, ) @@ -2816,7 +2815,7 @@ def dprism( shape, face.wrapped, basis.wrapped if basis else TopoDS_Face(), - taper * DEG2RAD, + radians(taper), additive, False, ) @@ -2983,7 +2982,7 @@ def makeCone( radius1, radius2, height, - angleDegrees * DEG2RAD, + radians(angleDegrees), ).Shape() ) @@ -3006,7 +3005,7 @@ def makeCylinder( gp_Ax2(Vector(pnt).toPnt(), Vector(dir).toDir()), radius, height, - angleDegrees * DEG2RAD, + radians(angleDegrees), ).Shape() ) @@ -3031,8 +3030,8 @@ def makeTorus( gp_Ax2(Vector(pnt).toPnt(), Vector(dir).toDir()), radius1, radius2, - angleDegrees1 * DEG2RAD, - angleDegrees2 * DEG2RAD, + radians(angleDegrees1), + radians(angleDegrees2), ).Shape() ) @@ -3104,9 +3103,9 @@ def makeSphere( BRepPrimAPI_MakeSphere( gp_Ax2(Vector(pnt).toPnt(), Vector(dir).toDir()), radius, - angleDegrees1 * DEG2RAD, - angleDegrees2 * DEG2RAD, - angleDegrees3 * DEG2RAD, + radians(angleDegrees1), + radians(angleDegrees2), + radians(angleDegrees3), ).Shape() ) @@ -3246,9 +3245,11 @@ def extrudeLinear( ) else: faceNormal = face.normalAt() - d = 1 if vecNormal.getAngle(faceNormal) < 90 * DEG2RAD else -1 + d = 1 if vecNormal.getAngle(faceNormal) < radians(90.0) else -1 + + # Divided by cos of taper angle to ensure the height chosen by the user is respected prism_builder = LocOpe_DPrism( - face.wrapped, d * vecNormal.Length, d * taper * DEG2RAD + face.wrapped, (d * vecNormal.Length) / cos(radians(taper)), d * radians(taper) ) return cls(prism_builder.Shape()) @@ -3298,7 +3299,7 @@ def revolve( v2 = Vector(axisEnd) v2 = v2 - v1 revol_builder = BRepPrimAPI_MakeRevol( - face.wrapped, gp_Ax1(v1.toPnt(), v2.toDir()), angleDegrees * DEG2RAD, True + face.wrapped, gp_Ax1(v1.toPnt(), v2.toDir()), radians(angleDegrees), True ) return cls(revol_builder.Shape()) diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index 55424f9ec..154ad362c 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -3686,6 +3686,33 @@ def testTaperedExtrudeCutBlind(self): .cutBlind(-h, True, float(t)) ) + def testTaperedExtrudeHeight(self): + """ + Ensures that the tapered prism has the correct height. + """ + + # Tapered extrusion to check the height of, with positive taper + s = ( + Workplane('XY') + .rect(100.0,100.0) + .extrude(100.0, taper=20.0) + ) + + # Get the bounding box and make sure the height matches the requested height + bb = s.val().BoundingBox() + self.assertAlmostEqual(bb.zlen, 100.0) + + # Tapered extrusion to check the height of, with negative taper + s2 = ( + Workplane('XY') + .rect(100.0,100.0) + .extrude(100.0, taper=-20.0) + ) + + # Get the bounding box and make sure the height matches the requested height + bb2 = s2.val().BoundingBox() + self.assertAlmostEqual(bb2.zlen, 100.0) + def testClose(self): # Close without endPoint and startPoint coincide. # Create a half-circle From 94a00f80f17649cff9585d8c72ac012f6fd2025c Mon Sep 17 00:00:00 2001 From: Jeremy Wright Date: Tue, 15 Aug 2023 09:14:25 -0400 Subject: [PATCH 2/2] Black formatting fix --- cadquery/occ_impl/shapes.py | 4 +++- tests/test_cadquery.py | 12 ++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index c7de1a02c..b7287f48f 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -3249,7 +3249,9 @@ def extrudeLinear( # Divided by cos of taper angle to ensure the height chosen by the user is respected prism_builder = LocOpe_DPrism( - face.wrapped, (d * vecNormal.Length) / cos(radians(taper)), d * radians(taper) + face.wrapped, + (d * vecNormal.Length) / cos(radians(taper)), + d * radians(taper), ) return cls(prism_builder.Shape()) diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index 154ad362c..6ffe35426 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -3692,22 +3692,14 @@ def testTaperedExtrudeHeight(self): """ # Tapered extrusion to check the height of, with positive taper - s = ( - Workplane('XY') - .rect(100.0,100.0) - .extrude(100.0, taper=20.0) - ) + s = Workplane("XY").rect(100.0, 100.0).extrude(100.0, taper=20.0) # Get the bounding box and make sure the height matches the requested height bb = s.val().BoundingBox() self.assertAlmostEqual(bb.zlen, 100.0) # Tapered extrusion to check the height of, with negative taper - s2 = ( - Workplane('XY') - .rect(100.0,100.0) - .extrude(100.0, taper=-20.0) - ) + s2 = Workplane("XY").rect(100.0, 100.0).extrude(100.0, taper=-20.0) # Get the bounding box and make sure the height matches the requested height bb2 = s2.val().BoundingBox()