Skip to content

Commit

Permalink
Fix for incorrect tapered extrude height found in #1383
Browse files Browse the repository at this point in the history
  • Loading branch information
jmwright committed Aug 15, 2023
1 parent 56c9bda commit 0b1eca8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 19 deletions.
39 changes: 20 additions & 19 deletions cadquery/occ_impl/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 = {
Expand Down Expand Up @@ -900,7 +899,7 @@ def rotate(
Vector(startVector).toPnt(),
(Vector(endVector) - Vector(startVector)).toDir(),
),
angleDegrees * DEG2RAD,
radians(angleDegrees),
)

return self._apply_transform(Tr)
Expand Down Expand Up @@ -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())

Expand Down Expand Up @@ -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
)
Expand All @@ -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())
Expand Down Expand Up @@ -2175,7 +2174,7 @@ def makeHelix(
else:
geom_surf = Geom_ConicalSurface(
gp_Ax3(Vector(center).toPnt(), Vector(dir).toDir()),
angle * DEG2RAD,
radians(angle),
radius,
)

Expand Down Expand Up @@ -2816,7 +2815,7 @@ def dprism(
shape,
face.wrapped,
basis.wrapped if basis else TopoDS_Face(),
taper * DEG2RAD,
radians(taper),
additive,
False,
)
Expand Down Expand Up @@ -2983,7 +2982,7 @@ def makeCone(
radius1,
radius2,
height,
angleDegrees * DEG2RAD,
radians(angleDegrees),
).Shape()
)

Expand All @@ -3006,7 +3005,7 @@ def makeCylinder(
gp_Ax2(Vector(pnt).toPnt(), Vector(dir).toDir()),
radius,
height,
angleDegrees * DEG2RAD,
radians(angleDegrees),
).Shape()
)

Expand All @@ -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()
)

Expand Down Expand Up @@ -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()
)

Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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())
Expand Down
27 changes: 27 additions & 0 deletions tests/test_cadquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 0b1eca8

Please sign in to comment.