|
# created with Alibre Script Genie by Stephen S. Mitchell, https://github.com/stephensmitchell |
|
def printTraceBack(): |
|
import traceback |
|
print('--------------') |
|
print(traceback.format_exc()) |
|
print('--------------') |
|
def show_error(msg): |
|
print('ERROR:', msg) |
|
def show_info(msg): |
|
print(msg) |
|
def safe_try(func): |
|
try: |
|
func() |
|
except: |
|
printTraceBack() |
|
show_error('Script failed') |
|
def main(): |
|
import math |
|
Units.Current = UnitTypes.Millimeters |
|
Win = Windows() |
|
opts = [] |
|
opts.append(['Part Name', WindowsInputTypes.String, 'L_Bracket']) |
|
opts.append(['Extrude Width (mm)', WindowsInputTypes.Real, 40.0]) |
|
opts.append(['Base Leg Length (mm)', WindowsInputTypes.Real, 80.0]) |
|
opts.append(['Vertical Leg Height (mm)', WindowsInputTypes.Real, 60.0]) |
|
opts.append(['Thickness (mm)', WindowsInputTypes.Real, 8.0]) |
|
opts.append(['Hole Diameter (mm)', WindowsInputTypes.Real, 6.0]) |
|
opts.append(['Base Hole Count', WindowsInputTypes.Integer, 2]) |
|
opts.append(['Base Hole Edge Offset (mm)', WindowsInputTypes.Real, 15.0]) |
|
opts.append(['Base Hole Spacing (mm)', WindowsInputTypes.Real, 30.0]) |
|
opts.append(['Flange Hole Count', WindowsInputTypes.Integer, 2]) |
|
opts.append(['Flange Hole Edge Offset (mm)', WindowsInputTypes.Real, 15.0]) |
|
opts.append(['Flange Hole Spacing (mm)', WindowsInputTypes.Real, 25.0]) |
|
opts.append(['Add Fillet?', WindowsInputTypes.Boolean, True]) |
|
opts.append(['Fillet Radius (mm)', WindowsInputTypes.Real, 1.0]) |
|
vals = Win.OptionsDialog('L-Bracket With Through Holes', opts) |
|
if vals is None: |
|
show_info('Cancelled') |
|
return |
|
name = str(vals[0]) |
|
width = float(vals[1]) |
|
base_len = float(vals[2]) |
|
vert_h = float(vals[3]) |
|
t = float(vals[4]) |
|
hole_d = float(vals[5]) |
|
base_n = int(vals[6]) |
|
base_off = float(vals[7]) |
|
base_pitch = float(vals[8]) |
|
flange_n = int(vals[9]) |
|
flange_off = float(vals[10]) |
|
flange_pitch = float(vals[11]) |
|
do_fillet = bool(vals[12]) |
|
fillet_r = float(vals[13]) |
|
|
|
if name == '': |
|
raise Exception('Part Name cannot be empty') |
|
if width <= 0 or base_len <= 0 or vert_h <= 0 or t <= 0: |
|
raise Exception('Width/Base/Height/Thickness must be > 0') |
|
if hole_d <= 0: |
|
raise Exception('Hole Diameter must be > 0') |
|
if hole_d >= t: |
|
raise Exception('Hole Diameter must be less than Thickness (through-holes are placed in the legs)') |
|
if base_n < 0 or flange_n < 0: |
|
raise Exception('Hole counts must be >= 0') |
|
if base_n == 1: |
|
base_pitch = 0.0 |
|
if flange_n == 1: |
|
flange_pitch = 0.0 |
|
if base_n > 1 and base_pitch <= 0: |
|
raise Exception('Base Hole Spacing must be > 0 when Base Hole Count > 1') |
|
if flange_n > 1 and flange_pitch <= 0: |
|
raise Exception('Flange Hole Spacing must be > 0 when Flange Hole Count > 1') |
|
if base_off < 0 or flange_off < 0: |
|
raise Exception('Edge offsets must be >= 0') |
|
if do_fillet and fillet_r < 0: |
|
raise Exception('Fillet radius must be >= 0') |
|
|
|
# Layout checks (in sketch coordinates on the YZ plane): |
|
# We build an L profile with inner corner at (0,0). |
|
# Base leg runs in +Z, vertical leg runs in +Y, thickness is t. |
|
# Holes are circles inside the legs: |
|
# - Base holes along Z, centered at Y = t/2 |
|
# - Flange holes along Y, centered at Z = t/2 |
|
base_clear_min = base_off + hole_d/2.0 |
|
base_clear_max = base_len - (hole_d/2.0) |
|
if base_n > 0: |
|
last_z = base_off + (base_n - 1) * base_pitch |
|
if base_clear_min > base_clear_max: |
|
raise Exception('Base leg too small for holes/offset/diameter') |
|
if last_z + hole_d/2.0 > base_len: |
|
raise Exception('Base holes exceed base length; reduce count/spacing/offset or increase base length') |
|
if base_off - hole_d/2.0 < t: |
|
# keep holes out of the corner block region (the vertical leg occupies Z < t above Y > t) |
|
# This is a conservative guard; you can relax it if desired. |
|
pass |
|
|
|
flange_clear_min = flange_off + hole_d/2.0 |
|
flange_clear_max = vert_h - (hole_d/2.0) |
|
if flange_n > 0: |
|
last_y = flange_off + (flange_n - 1) * flange_pitch |
|
if flange_clear_min > flange_clear_max: |
|
raise Exception('Vertical leg too small for holes/offset/diameter') |
|
if last_y + hole_d/2.0 > vert_h: |
|
raise Exception('Flange holes exceed height; reduce count/spacing/offset or increase height') |
|
|
|
P = Part(name) |
|
yz = P.GetPlane('YZ-Plane') |
|
sk = P.AddSketch('Profile_YZ', yz) |
|
|
|
# L-profile polyline (in sketch 2D coords): (Z, Y) style layout |
|
# Points: (0,0)->(0,vert_h)->(t,vert_h)->(t,t)->(base_len,t)->(base_len,0)->(0,0) |
|
sk.AddLines([0,0, 0,vert_h, |
|
0,vert_h, t,vert_h, |
|
t,vert_h, t,t, |
|
t,t, base_len,t, |
|
base_len,t, base_len,0, |
|
base_len,0, 0,0], False) |
|
|
|
# Base holes (centers at Y=t/2, Z=base_off + i*pitch) |
|
if base_n > 0: |
|
cy = t/2.0 |
|
for i in range(base_n): |
|
cz = base_off + float(i)*base_pitch |
|
# ensure hole is in the base region (Y <= t) |
|
sk.AddCircle(cz, cy, hole_d, False) |
|
|
|
# Flange holes (centers at Z=t/2, Y=flange_off + i*pitch) |
|
if flange_n > 0: |
|
cz = t/2.0 |
|
for i in range(flange_n): |
|
cy = flange_off + float(i)*flange_pitch |
|
# ensure hole is in the vertical region (Z <= t) |
|
sk.AddCircle(cz, cy, hole_d, False) |
|
|
|
P.AddExtrudeBoss('Bracket', sk, width, False) |
|
|
|
if do_fillet and fillet_r > 0: |
|
try: |
|
edges = P.GetEdges() |
|
P.AddFillet('GlobalFillet', edges, fillet_r, False) |
|
except: |
|
show_info('Fillet skipped (edge list/feature may vary).') |
|
|
|
P.Regenerate() |
|
show_info('Created: ' + name) |
|
show_info('Width=%.3f Base=%.3f Height=%.3f Thick=%.3f' % (width, base_len, vert_h, t)) |
|
show_info('Holes: base=%d flange=%d dia=%.3f' % (base_n, flange_n, hole_d)) |
|
|
|
safe_try(main) |