Completed parameterization

This commit is contained in:
gumyr 2024-04-03 14:15:32 -04:00
parent c53ee55a76
commit b0876a0005

View file

@ -34,15 +34,15 @@ license:
import copy
from airfoils import Airfoil
from build123d import *
from bd_warehouse.fastener import *
from bd_warehouse.thread import *
from bd_warehouse.fastener import ClearanceHole, CounterSunkScrew
from bd_warehouse.thread import IsoThread
from ocp_vscode import show, set_defaults, Camera
set_defaults(reset_camera=Camera.CENTER)
nuke_diameter = 10 * CM
thickness = 2
multipart_fins = True
DIAMETER = 10 * CM
THICKNESS = 2
MULTIPART_FINS = True
#
# -------- Core Nuke Shape --------
@ -50,11 +50,11 @@ multipart_fins = True
airfoil = Airfoil.NACA4("0045")
aero_pnts = [Vector(p) for p in zip(airfoil._x_upper, airfoil._y_upper)]
aero_pnts_max_y = max(p.Y for p in aero_pnts)
aero_pnts_scaled = [p * (nuke_diameter / 2) / aero_pnts_max_y for p in aero_pnts]
aero_pnts_scaled = [p * (DIAMETER / 2) / aero_pnts_max_y for p in aero_pnts]
with BuildPart() as nuke_core:
with BuildSketch(
Plane((0, 0, 1.87 * nuke_diameter), x_dir=(0, 0, -1), z_dir=(0, 1, 0))
Plane((0, 0, 1.87 * DIAMETER), x_dir=(0, 0, -1), z_dir=(0, 1, 0))
) as nuke_profile:
with BuildLine() as nuke_outline:
aero = Spline(*aero_pnts_scaled[12:80]) # 200 points total
@ -66,7 +66,7 @@ with BuildPart() as nuke_core:
)
tail = Spline(
aero @ 1,
(1.54 * nuke_diameter, 0),
(1.54 * DIAMETER, 0),
tangents=[aero % 1, (0, -1)],
tangent_scalars=(1.25, 0.80),
)
@ -81,14 +81,14 @@ with BuildPart() as nuke_core:
with Locations(line @ param):
Rectangle(
2 * MM,
thickness,
THICKNESS,
rotation=line.tangent_angle_at(param),
mode=Mode.SUBTRACT,
)
with Locations(tail @ 0.45):
Rectangle(
5 * MM,
thickness,
THICKNESS,
rotation=tail.tangent_angle_at(0.45),
)
revolve()
@ -102,9 +102,10 @@ with BuildPart() as nuke_core:
#
# -------- Warning Ring --------
#
warning_ring_face = nuke_core.faces().sort_by(Axis.Z)[-15]
warning_ring_face = nuke_core_faces[-15]
warning_ring = thicken(warning_ring_face, -1 * MM)
warning_ring.color = Color("Gold")
warning_ring.label = "warning ring"
#
# -------- Fins --------
@ -114,59 +115,71 @@ warning_ring.color = Color("Gold")
fin_screw = CounterSunkScrew(size="M1.4-0.3", length=3 * MM, fastener_type="iso2009")
# fin_screw_head = split(fin_screw, Plane.XY.offset(-fin_screw.head_height))
fin_screw.color = Color(0xC0C0C0) # Silver
fin_screw.label = "fin screw"
with BuildPart() as fins:
with BuildPart() as fin_outer_ring:
with BuildSketch() as bs0:
Circle(nuke_diameter / 2)
Circle(nuke_diameter / 2 - thickness, mode=Mode.SUBTRACT)
Circle(DIAMETER / 2)
Circle(DIAMETER / 2 - THICKNESS, mode=Mode.SUBTRACT)
# Only want 1/4 of the ring
Rectangle(
2 * nuke_diameter,
2 * nuke_diameter,
2 * DIAMETER,
2 * DIAMETER,
align=Align.MIN,
rotation=45,
mode=Mode.INTERSECT,
)
extrude(amount=28)
with BuildSketch(Plane.XZ) as bs1:
Trapezoid(50, 19, 84, align=(Align.CENTER, Align.MIN))
fillet(bs1.vertices().group_by(Axis.Y)[-1], 4 * MM)
Trapezoid(
DIAMETER / 2,
DIAMETER * 0.19,
84,
align=(Align.CENTER, Align.MIN),
)
fillet(bs1.vertices().group_by(Axis.Y)[-1], DIAMETER * 0.04)
projection = project(mode=Mode.PRIVATE).faces().sort_by(Axis.Y)[1]
thicken(projection, amount=-thickness, mode=Mode.SUBTRACT)
thicken(projection, amount=-THICKNESS, mode=Mode.SUBTRACT)
# Replace to create the full ring
with PolarLocations(0, 3, start_angle=90, angular_range=270):
add(fin_outer_ring.part)
# Used to position featues below
outer_ring_face = fin_outer_ring.faces().sort_by(SortBy.AREA)[-1]
with BuildPart() as fin_inner_ring:
with BuildSketch(Plane.XY.offset(5.5)) as bs0:
Circle(18)
Circle(18 - thickness, mode=Mode.SUBTRACT)
extrude(amount=15)
with BuildSketch(Plane.XY.offset(DIAMETER * 0.055)):
Circle(DIAMETER * 0.18)
Circle(DIAMETER * 0.18 - THICKNESS, mode=Mode.SUBTRACT)
extrude(amount=DIAMETER * 0.15)
with BuildPart() as fin_supports:
with BuildSketch(Plane.XY.offset(10)) as fin_support_plan:
Rectangle(53 * 2, thickness, rotation=-45)
Rectangle(53 * 2, thickness, rotation=45)
Circle(50 - thickness, mode=Mode.INTERSECT)
Circle(18, mode=Mode.SUBTRACT)
Rectangle(DIAMETER + 2 * THICKNESS, THICKNESS, rotation=-45)
Rectangle(DIAMETER + 2 * THICKNESS, THICKNESS, rotation=45)
Circle(DIAMETER / 2 - THICKNESS, mode=Mode.INTERSECT)
Circle(DIAMETER * 0.18, mode=Mode.SUBTRACT)
extrude(until=Until.NEXT, target=nuke_core.part)
with BuildSketch(Plane.XZ) as support_trim:
Trapezoid(176, 57, 45, align=(Align.CENTER, Align.MIN))
Trapezoid(
DIAMETER * 1.76, DIAMETER * 0.57, 45, align=(Align.CENTER, Align.MIN)
)
split(bisect_by=Plane.YZ)
revolve(mode=Mode.INTERSECT)
fin_contacts = fin_supports.faces().group_by(Axis.Z)[-2]
fin_tabs = extrude(fin_contacts, amount=1 * MM, dir=(0, 0, 1))
fin_tabs = extrude(fin_contacts, amount=THICKNESS / 2, dir=(0, 0, 1))
support_fillet_edges = (
fins.edges().filter_by(Axis.Z).filter_by_position(Axis.Z, 0.0, 27.5)
fins.edges().filter_by(Axis.Z).filter_by_position(Axis.Z, 0.0, DIAMETER * 0.275)
)
fillet(support_fillet_edges, 6 * MM)
if multipart_fins:
fin_plan = section(section_by=Plane.XY.offset(28 + 10))
red_fins = extrude(fin_plan, amount=-28, mode=Mode.SUBTRACT)
fillet(support_fillet_edges, DIAMETER * 0.06)
if MULTIPART_FINS:
fin_plan = section(section_by=Plane.XY.offset(DIAMETER * (0.28 + 0.10)))
red_fins = extrude(fin_plan, amount=-DIAMETER * 0.28, mode=Mode.SUBTRACT)
red_fins.color = Color("FireBrick")
red_fins.label = "red fins"
screw_uv_values = [(0.015, 0.15), (0.015, 0.55), (0.985, 0.15), (0.985, 0.55)]
fin_screw_locs = []
@ -179,9 +192,10 @@ with BuildPart() as fins:
)
with Locations(fin_screw_locs):
ClearanceHole(fin_screw, depth=3 * MM, counter_sunk=True, fit="Close")
ClearanceHole(fin_screw, depth=THICKNESS * 1.5, counter_sunk=True, fit="Close")
fins.part.color = Color("OliveDrab")
fins.part.label = "fins"
#
# -------- Nose --------
@ -191,6 +205,7 @@ fins.part.color = Color("OliveDrab")
nose_screw = CounterSunkScrew(size="M3-0.5", length=10 * MM, fastener_type="iso14582")
nose_screw_head = split(nose_screw, Plane.XY.offset(-nose_screw.head_height))
nose_screw_head.color = Color(0xC0C0C0) # Silver
nose_screw_head.label = "nose screw"
with BuildPart() as nose:
add(nuke_core.part)
@ -199,44 +214,45 @@ with BuildPart() as nose:
nose.edges().group_by(Axis.Z)[0].sort_by(SortBy.LENGTH)
)
nose_face = nose.faces().sort_by(SortBy.AREA)[-1]
# The edge isn't of type CIRCLE (even though it is) so calculate radius
bottom_inside_edge_radius = bottom_inside_edge.bounding_box().size.X / 2
# Thread
with Locations((0, 0, bottom_edge.center().Z - 7 * MM)):
with Locations((0, 0, bottom_edge.center().Z - (DIAMETER * 0.06 + 1 * MM))):
nose_thread = IsoThread(
major_diameter=2 * (bottom_edge.radius - 1 * MM),
pitch=2 * MM,
length=6 * MM,
length=DIAMETER * 0.06,
external=True,
end_finishes=("fade", "square"),
)
with BuildSketch(Plane.XY.offset(bottom_edge.center().Z)):
Circle(bottom_inside_edge_radius)
Circle(nose_thread.min_radius - thickness, mode=Mode.SUBTRACT)
Circle(nose_thread.min_radius - THICKNESS, mode=Mode.SUBTRACT)
extrude(until=Until.NEXT)
with BuildSketch(Plane.XY.offset(bottom_edge.center().Z)):
Circle(bottom_edge.radius)
cap = extrude(amount=-1 * MM, taper=45)
with BuildSketch(cap.faces().sort_by(Axis.Z)[0]):
Circle(nose_thread.min_radius - thickness)
Circle(nose_thread.min_radius - THICKNESS)
extrude(amount=-1 * MM, mode=Mode.SUBTRACT)
with BuildSketch(cap.faces().sort_by(Axis.Z)[0]):
Circle(nose_thread.min_radius)
Circle(nose_thread.min_radius - thickness, mode=Mode.SUBTRACT)
extrude(amount=6 * MM)
Circle(nose_thread.min_radius - THICKNESS, mode=Mode.SUBTRACT)
extrude(amount=DIAMETER * 0.06)
# Nose cone screws
nose_screw_ref_pnt = nose_face.position_at(0.0, 0.3)
nose_screw_ref_nrm = nose_face.normal_at(nose_screw_ref_pnt)
nose_screw_locs = [
Rot(0, 0, a) * Location(Plane(nose_screw_ref_pnt, z_dir=nose_screw_ref_nrm))
for a in range(0, 360, 45)
Rot(0, 0, angle) * Location(Plane(nose_screw_ref_pnt, z_dir=nose_screw_ref_nrm))
for angle in range(0, 360, 45)
]
with Locations(nose_screw_locs):
ClearanceHole(nose_screw, fit="Close")
nose.part.color = Color("FireBrick")
nose.part.label = "nose"
#
# -------- Final Nuke Shape --------
@ -244,16 +260,18 @@ nose.part.color = Color("FireBrick")
top_screw = CounterSunkScrew(size="M4-0.7", length=10 * MM, fastener_type="iso14582")
top_screw_head = split(top_screw, Plane.XY.offset(-top_screw.head_height))
top_screw_head.color = Color(0xC0C0C0) # Silver
top_screw_head.label = "top screw"
middle_screw = CounterSunkScrew(size="M6-1", length=10 * MM, fastener_type="iso14582")
middle_screw_head = split(middle_screw, Plane.XY.offset(-middle_screw.head_height))
middle_screw_head.color = Color(0xC0C0C0) # Silver
middle_screw_head.label = "middle screw"
# Internal thread
nose_thread = IsoThread(
major_diameter=2 * (bottom_edge.radius - 1 * MM),
pitch=2 * MM,
length=6 * MM,
length=DIAMETER * 0.06,
external=False,
end_finishes=("square", "fade"),
)
@ -262,6 +280,7 @@ with BuildPart() as nuke:
add(nuke_core.part)
split(bisect_by=Plane.XY.offset(nuke_body_limits[1]), keep=Keep.BOTTOM)
# Create the thread
top_edge = (
nuke.edges()
.filter_by(GeomType.CIRCLE)
@ -270,11 +289,11 @@ with BuildPart() as nuke:
)
with BuildSketch(Plane.XY.offset(top_edge.center().Z)):
Circle(top_edge.radius)
extrude(amount=-6 * MM, taper=150)
extrude(amount=-DIAMETER * 0.06, taper=150)
with BuildSketch(Plane.XY.offset(top_edge.center().Z)):
Circle(nose_thread.major_diameter / 2 - 0.02 * MM)
extrude(amount=-6 * MM, mode=Mode.SUBTRACT)
with Locations((0, 0, nuke_body_limits[1] - 6 * MM)):
Circle(nose_thread.major_diameter / 2 - 0.02 * MM) # small fudge required
extrude(amount=-DIAMETER * 0.06, mode=Mode.SUBTRACT)
with Locations((0, 0, nuke_body_limits[1] - DIAMETER * 0.06)):
add(nose_thread)
# Create sockets for the fins
@ -313,18 +332,19 @@ with BuildPart() as nuke:
normal = whistle_ring_face.normal_at(*whistle_uv)
origin = whistle_ring_face.position_at(*whistle_uv)
pln = Plane(
origin=origin + Vector(normal.X, normal.Y, -0.5) * 2 * MM,
origin=origin + Vector(normal.X, normal.Y, -0.5) * DIAMETER * 0.02,
z_dir=normal + Vector(0, 0, 0.6),
)
with BuildSketch(pln):
RectangleRounded(8 * MM, 8 * MM, 1 * MM)
Rectangle(6 * MM, 6 * MM, mode=Mode.SUBTRACT)
RectangleRounded(DIAMETER * 0.08, DIAMETER * 0.08, DIAMETER * 0.01)
Rectangle(DIAMETER * 0.06, DIAMETER * 0.06, mode=Mode.SUBTRACT)
whistle = extrude(until=Until.PREVIOUS, dir=normal + Vector(0, 0, 1))
whistle_flipped = mirror(whistle, about=Plane.XZ)
mirror(whistle, about=Plane.YZ.rotated((0, 0, 22.5)))
mirror(whistle_flipped, about=Plane.YZ.rotated((0, 0, -22.5)))
nuke.part.color = Color("OliveDrab")
nuke.part.label = "nuke"
#
# -------- Final Assembly --------
@ -336,13 +356,9 @@ components = (
+ [copy.copy(middle_screw_head).locate(l) for l in middle_face_screw_locs]
+ [copy.copy(fin_screw).locate(l) for l in fin_screw_locs]
)
if multipart_fins:
if MULTIPART_FINS:
components.append(red_fins)
nuke_assembly = Compound(children=components)
show(
nuke_assembly,
center_grid=True,
names=["nuke_assembly"],
)
show(nuke_assembly, center_grid=True, names=["nuke_assembly"])