Sheet Metal Feature Iteration

Sheet metal shops are a fantastic fit for our platform because of the formulaic nature of sheet metal costing. We provide values like cut length, punch hit count, hole setups, thickness, etc. that allow for effective formulaic high level pricing. Now with feature iteration, you can use the information stored within each bend, feature, and manufacturability feedback instance to calculate runtimes, prices, part complexity, etc.

In this article, we will break down each feature and feedback type extracted from our sheet metal interrogation, as well as provide examples of how to use them in your pricing formulas. The cheat sheet below contains all the high level information you will need to get started. For more specifics on what each feature and feedback instance represents, check out our sheet metal interrogation article.

Cheat Sheet

sheet_metal = analyze_sheet_metal()  # request interrogation

for bend in get_features(sheet_metal, name='bend'):  # iterate thru bends
  # the below four lines demonstrate how to access bend information
  bend.properties.angle
  bend.properties.radius
  bend.properties.length
  bend.properties.k_factor
  if is_close(bend.properties.angle, 90):  # check bend angle using is_close helper
    do_something = 1
  else:
    do_something_else = 1

# iterate through other forming features
for offset in get_features(sheet_metal, name='offset'):
  # has same properties as bend, but also offset height
  offset.properties.offset_height
  do_something_with_offsets = 1

for open_hem in get_features(sheet_metal, name='open_hem'):
  do_something_with_hems = 1

for feature in get_features(sheet_metal):  # iterate thru features
  feature.name
  feature.properties
  if feature.name == 'countersink':
    # access information with dot notation into properties
    feature.properties.depth
    feature.properties.major_diameter
    do_something_with_countersink = 1

for feedback in get_feedback(sheet_metal):  # iterate thru feedback
  feedback.name
  feedback.level
  feedback.properties
  if feedback.name == 'cut_near_bend':
    # access information with dot notation into properties
    feedback.properties.dist
    feedback.properties.distance_ratio
    do_something_with_cut_near_bend = 1

# get count of feature type by using len() and specifying name
num_countersinks = len(get_features(sheet_metal, name='countersink'))

# get count of feedback type by using len() and specifying name
num_cut_near_bend = len(get_feedback(sheet_metal, name='cut_near_bend'))
Feature Reference
Name Properties
bend area, angle, length, k_factor, radius
bend_relief area, width, length
curl area, angle, length, k_factor, radius
counterbore area, depth, diameter, volume
countersink area, depth, major_diameter, minor_diameter, semi_angle, volume
cutout_feature area, cut_length, requires_piercing
drilled_hole area, depth, diameter, volume
embossment area, depth
offset area, angle, length, offset_height, k_factor, radius
open_hem area, angle, length, k_factor, radius
punch_multi_hit_feature area, cut_length
circular_punch cut_length, radius
obround_punch cut_length, side_length, side_width, radius
rectangular_punch cut_length, side_length, side_width
slot_punch cut_length, side_length, radius
square_punch cut_length, side_length
tear_drop area, angle, length, k_factor, radius
Feedback Reference
Name Level Properties (short description)
captive_part complete_exclusion n/a
close_countersink_bores manufacturing_issue dist, distance_ratio (traversal/thickness)
close_cutouts manufacturing_issue dist, distance_ratio (traversal/thickness)
countersink_bore_to_edge manufacturing_issue dist, distance_ratio (traversal/thickness)
curl_near_bend manufacturing_issue dist, distance_ratio (traversal/thickness)
cut_near_bend manufacturing_issue dist, distance_ratio (traversal/thickness)
cutout_to_edge manufacturing_issue dist, distance_ratio (traversal/thickness)
different_bend_directions cost_driver n/a
hem_near_bend manufacturing_issue dist, distance_ratio (traversal/thickness)
large_bend_radius manufacturing_issue ratio (radius/thickness)
machining_required manufacturing_issue n/a
neg_bend_allowance complete_exclusion radius, thickness
no_bend_relief manufacturing_issue n/a
no_corner_relief manufacturing_issue n/a
non_standard_bend_angle cost_driver angle
shallow_bend_relief manufacturing_issue ratio ((depth-radius)/thickness)
short_bend manufacturing_issue ratio (length/radius)
short_hem_return manufacturing_issue ratio (distance/thickness)
small_bend_radius manufacturing_issue ratio (radius/thickness)
small_cut manufacturing_issue dist (size of cut)
small_radius manufacturing_issue radius
thin_bend_relief manufacturing_issue ratio (width/thickness)
tight_curl manufacturing_issue ratio (radius/thickness)
tight_hem manufacturing_issue ratio (diameter/thickness
unfolding_issue complete_exclusion n/a

Examples

Basic

Below describes a way to add price for the appearance of certain types of features and feedback on a part. This operation could serve as a supplement to your standard marking and forming operations to encapsulate added costs for specific features. Checkout our custom interrogations article to find out how to customize your manufacturability feedback outputs.

units_in()

sheet_metal = analyze_sheet_metal()

close_cutout_cost = var('Close cutout cost', 0.25, '$ per close cutout found', currency)
cut_near_bend_cost = var('Cut near bend cost', 2.50, '$ per cut near bend found', currency)
curl_cost = var('Curl Cost', 5.0, '$ per curl found', currency)
hem_cost = var('Hem Cost', 5.0, '$ per hem found', currency)

total_close_cutout_cost = len(get_feedback(sheet_metal, name='close_cutouts')) * close_cutout_cost
total_cut_near_bend_cost = len(get_feedback(sheet_metal, name='cut_near_bend')) * cut_near_bend_cost
total_curl_cost = len(get_features(sheet_metal, name='curl')) * curl_cost
hem_count = len(get_features(sheet_metal, name='open_hem')) + len(get_features(sheet_metal, name='tear_drop'))
total_hem_cost = hem_count * hem_cost

PRICE = (total_close_cutout_cost + total_cut_near_bend_cost + total_curl_cost + total_hem_cost) * part.qty
DAYS = 0

Advanced

Below describes an advanced method to cost out a forming operation based on the characteristics of bends in the part. The operation below will start each bend with a base setup time and runtime, and will then increment these times based on added geometric complexity, such as non-90 degree angle bends, long bends, or large radius bends.

# collects bend runtime and bend setup time based on the characteristics of bends in the part
# there is a base bend runtime and setup time, and based on things like angle, length, radius
# the times will increment

units_in()
sheet_metal = analyze_sheet_metal()

setup_time = var('setup_time', 0, 'Setup time in hours', number, frozen=False)
runtime = var('runtime', 0, 'Runtime in hours', number, frozen=False)

# establish base setup time and time increments in minutes
base_bend_setup_time = 6
st_increment = 3

# establish base runtime and time increments in seconds
base_bend_runtime = 30
rt_increment = 15

# establish geometric thresholds for incrementing times
# in inches
medium_radius = 2.0
large_radius = 4.0
medium_length = 20
large_length = 40

# first track standard bends
# if bend angle is not 90, up tick, and if bend length and radius fall within gaps, increment times
total_bend_run = 0
total_bend_setup = 0
for bend in get_features(sheet_metal, name='bend'):
    # start with base times
    bend_st = base_bend_setup_time
    bend_rt = base_bend_runtime

    # increment for angle if necessary
    if not is_close(bend.properties.angle, 90):
        bend_rt += rt_increment
        bend_st += st_increment

    # if radius is medium or large, increment
    r = bend.properties.radius
    is_rad_medium = medium_radius <= r < large_radius or is_close(r, medium_radius)
    is_rad_large = r >= large_radius or is_close(r, large_radius)
    if is_rad_medium:
        bend_rt += rt_increment
        bend_st += st_increment
    elif is_rad_large:
        bend_rt += rt_increment * 2
        bend_st += st_increment * 2

    l = bend.properties.length
    is_length_medium = medium_length <= l < large_length or is_close(l, medium_length)
    is_length_large = l >= large_length or is_close(l, large_length)
    if is_length_medium:
        bend_rt += rt_increment
        bend_st += st_increment
    elif is_length_large:
        bend_rt += rt_increment * 2
        bend_st += st_increment * 2

    total_bend_run += bend_rt
    total_bend_setup += bend_st

# establish final times as a sum of all above
# convert times to hours
setup_time.update(total_bend_setup / 60)
setup_time.freeze()
runtime.update(total_bend_run / 3600)
runtime.freeze()

rate = var('Rate', 50, '$/hr', currency)

PRICE = setup_time * rate + runtime * part.qty * rate
DAYS = 0

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us