Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for incorrect tapered extrude height found in #1383 #1388

Merged
merged 2 commits into from
Aug 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 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,13 @@ 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 +3301,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
19 changes: 19 additions & 0 deletions tests/test_cadquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -3686,6 +3686,25 @@ 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