def fingers(diameter, inside, amount=1, stem=1): # diameter = diameter of the tool for joint creation # inside = Tolerance in the joint receptacle global DT # Bit diameter tolerance # stem = amount of radius the stem or neck of the joint will have # amount = the amount of fingers xtranslate = -(4 + 2 * (stem - 1)) * (amount - 1) * diameter * DT / 2 finger(diameter, stem=stem) # generate male finger simple.active_name("puzzlem") simple.move(x=xtranslate, y=-0.00002) if amount > 1: # duplicate translate the amount needed (faster than generating new) for i in range(amount - 1): bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked": False, "mode": 'TRANSLATION'}, TRANSFORM_OT_translate={ "value": ((4 + 2 * (stem - 1)) * diameter * DT, 0, 0.0)}) simple.union('puzzle') simple.active_name("fingers") bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN') # Receptacle is made using the silhouette offset from the fingers if inside > 0: bpy.ops.object.silhouete_offset(offset=inside, style='1') simple.active_name('receptacle') simple.move(y=-inside)
def bar(width, thick, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, twist_keep=False, twist_line=False, twist_line_amount=2, which='MF'): # width = length of the bar # thick = thickness of the bar # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # Which M,F, MF, MM, FF global DT if amount == 0: amount = round(thick / ((4 + 2 * (stem - 1)) * diameter * DT)) - 1 bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=width, Simple_length=thick, use_cyclic_u=True, edit_mode=False) simple.active_name('tmprect') fingers(diameter, tolerance, amount, stem=stem) if which == 'MM' or which == 'M' or which == 'MF': simple.rename('fingers', '_tmpfingers') simple.rotate(-math.pi / 2) simple.move(x=width / 2) simple.rename('tmprect', '_tmprect') simple.union('_tmp') simple.active_name("tmprect") twistm('tmprect', thick, diameter, tolerance, twist, tneck, tthick, -math.pi / 2, x=width / 2, twist_keep=twist_keep) twistf('receptacle', thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep) simple.rename('receptacle', '_tmpreceptacle') if which == 'FF' or which == 'F' or which == 'MF': simple.rotate(-math.pi / 2) simple.move(x=-width / 2) simple.rename('tmprect', '_tmprect') simple.difference('_tmp', '_tmprect') simple.active_name("tmprect") if twist_keep: simple.make_active('twist_keep_f') simple.rotate(-math.pi / 2) simple.move(x=-width / 2) simple.remove_multiple("_") # Remove temporary base and holes simple.remove_multiple("fingers") # Remove temporary base and holes if twist_line: joinery.twist_line(thick, tthick, tolerance, tneck, twist_line_amount, width) if twist_keep: simple.duplicate() simple.active_name('tmptwist') simple.difference('tmp', 'tmprect') simple.rename('tmprect', 'Puzzle_bar') simple.remove_multiple("tmp") # Remove temporary base and holes simple.make_active('Puzzle_bar')
def arcbar(length, radius, thick, angle, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, twist_keep=False, which='MF', twist_line=False, twist_line_amount=2): # length is the total width of the segments including 2 * radius and thick # radius = radius of the curve # thick = thickness of the bar # angle = angle of the female part # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # which = which joint to generate, Male Female MaleFemale M, F, MF if which == 'M': which = 'MM' elif which == 'F': which = 'FF' length -= (radius * 2 + thick) # adjust length to include 2x radius + thick # generate base rectangle # Generate male section and join to the base if which == 'MM' or which == 'MF': bar(length, thick, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='M', twist_keep=twist_keep, twist_line=twist_line, twist_line_amount=twist_line_amount) simple.active_name('tmprect') if which == 'FF' or which == 'FM': bar(length, thick, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='F', twist_keep=twist_keep, twist_line=twist_line, twist_line_amount=twist_line_amount) simple.rotate(math.pi) simple.active_name('tmprect') # Generate female section and join to base if which == 'FF' or which == 'MF': arc(radius, thick, angle, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='F') simple.move(x=-length / 2 * 0.998) simple.active_name('tmp_receptacle') simple.union('tmp') simple.active_name('arcBar') simple.remove_multiple('tmp') if which == 'MM': arc(radius, thick, angle, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='M') bpy.ops.transform.mirror(orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False)) simple.move(x=-length / 2 * 0.998) simple.active_name('tmp_receptacle') simple.union('tmp') simple.active_name('arcBar') simple.remove_multiple('tmp') simple.make_active('arcBar')
def arcbararc(length, radius, thick, angle, angleb, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, which='MF', twist_keep=False, twist_line=False, twist_line_amount=2): # length is the total width of the segments including 2 * radius and thick # radius = radius of the curve # thick = thickness of the bar # angle = angle of the female part # angleb = angle of the male part # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # which = which joint to generate, Male Female MaleFemale M, F, MF length -= (radius * 2 + thick) # adjust length to include 2x radius + thick # generate base rectangle bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=length * 1.005, Simple_length=thick, use_cyclic_u=True, edit_mode=False) simple.active_name("tmprect") # Generate male section and join to the base if which == 'M' or which == 'MF': arc(radius, thick, angleb, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='M') simple.move(x=length / 2) simple.active_name('tmp_male') simple.select_multiple('tmp') bpy.ops.object.curve_boolean(boolean_type='UNION') simple.active_name('male') simple.remove_multiple('tmp') simple.rename('male', 'tmprect') # Generate female section and join to base if which == 'F' or which == 'MF': arc(radius, thick, angle, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='F') simple.move(x=-length / 2) simple.active_name('tmp_receptacle') simple.union('tmp') simple.active_name('tmprect') if twist_line: joinery.twist_line(thick, tthick, tolerance, tneck, twist_line_amount, length) if twist_keep: simple.duplicate() simple.active_name('tmptwist') simple.difference('tmp', 'tmprect') simple.active_name('arcBarArc') simple.make_active('arcBarArc')
def rack(mm_per_tooth=0.01, number_of_teeth=11, height=0.012, pressure_angle=0.3488, backlash=0.0, hole_diameter=0.003175, tooth_per_hole=4): simple.deselect() pi = math.pi mm_per_tooth *= 1000 a = mm_per_tooth / pi # addendum t = (a * math.sin(pressure_angle) ) # tooth side is tilted so top/bottom corners move this amount a /= 1000 mm_per_tooth /= 1000 t /= 1000 shapely_gear = Polygon([(-mm_per_tooth * 2 / 4 * 1.001, a - height), (-mm_per_tooth * 2 / 4 * 1.001 - backlash, -a), (-mm_per_tooth * 1 / 4 + backlash - t, -a), (-mm_per_tooth * 1 / 4 + backlash + t, a), (mm_per_tooth * 1 / 4 - backlash - t, a), (mm_per_tooth * 1 / 4 - backlash + t, -a), (mm_per_tooth * 2 / 4 * 1.001 + backlash, -a), (mm_per_tooth * 2 / 4 * 1.001, a - height)]) utils.shapelyToCurve('_tooth', shapely_gear, 0.0) i = number_of_teeth while i > 1: simple.duplicate(x=mm_per_tooth) i -= 1 simple.union('_tooth') simple.move(y=height / 2) if hole_diameter > 0: bpy.ops.curve.simple(align='WORLD', location=(mm_per_tooth / 2, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_radius=hole_diameter / 2, shape='3D', use_cyclic_u=True, edit_mode=False) simple.active_name('_hole') distance = (number_of_teeth - 1) * mm_per_tooth while distance > tooth_per_hole * mm_per_tooth: simple.duplicate(x=tooth_per_hole * mm_per_tooth) distance -= tooth_per_hole * mm_per_tooth simple.difference('_', '_tooth') name = 'rack-' + str(round(mm_per_tooth * 1000, 1)) name += '-PA-' + str(round(math.degrees(pressure_angle), 1)) simple.active_name(name)
def finger(diameter, stem=2): # diameter = diameter of the tool for joint creation # DT = Bit diameter tolerance # stem = amount of radius the stem or neck of the joint will have global DT RESOLUTION = 12 # Data resolution cube_sx = diameter * DT * (2 + stem - 1) cube_ty = diameter * DT cube_sy = 2 * diameter * DT circle_radius = diameter * DT / 2 c1x = cube_sx / 2 c2x = cube_sx / 2 c2y = 3 * circle_radius c1y = circle_radius bpy.ops.curve.simple(align='WORLD', location=(0, cube_ty, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=cube_sx, Simple_length=cube_sy, use_cyclic_u=True, edit_mode=False) bpy.context.active_object.name = "ftmprect" bpy.ops.curve.simple(align='WORLD', location=(c2x, c2y, 0), rotation=(0, 0, 0), Simple_Type='Ellipse', Simple_a=circle_radius, Simple_b=circle_radius, Simple_sides=4, use_cyclic_u=True, edit_mode=False, shape='3D') bpy.context.active_object.name = "ftmpcirc_add" bpy.context.object.data.resolution_u = RESOLUTION bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN') simple.duplicate() simple.mirrorx() simple.union('ftmp') simple.rename('ftmp', '_sum') rc1 = circle_radius bpy.ops.curve.simple(align='WORLD', location=(c1x, c1y, 0), rotation=(0, 0, 0), Simple_Type='Ellipse', Simple_a=circle_radius, Simple_b=rc1, Simple_sides=4, use_cyclic_u=True, edit_mode=False, shape='3D') bpy.context.active_object.name = "_circ_delete" bpy.context.object.data.resolution_u = RESOLUTION bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN') simple.duplicate() simple.mirrorx() simple.union('_circ') simple.difference('_', '_sum') bpy.ops.object.curve_remove_doubles() simple.rename('_sum', "_puzzle")
def twistf(name, length, diameter, tolerance, twist, tneck, tthick, twist_keep=False): # add twist lock to receptacle if twist: joinery.interlock_twist(length, tthick, tolerance, cx=0, cy=0, rotation=0, percentage=tneck) simple.rotate(math.pi / 2) simple.move(y=-tthick / 2 + 2 * diameter + 2 * tolerance) simple.active_name('xtemptwist') if twist_keep: simple.duplicate() simple.active_name('twist_keep_f') simple.make_active(name) simple.active_name('xtemp') simple.union('xtemp') simple.active_name(name)
def t(length, thick, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, combination='MF', base_gender='M', corner=False): if corner: if combination == 'MF': base_gender = 'M' combination = 'f' elif combination == 'F': base_gender = 'F' combination = 'f' elif combination == 'M': base_gender = 'M' combination = 'm' bar(length, thick, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which=base_gender) simple.active_name('tmp') fingers(diameter, tolerance, amount=amount, stem=stem) if combination == 'MF' or combination == 'M' or combination == 'm': simple.make_active('fingers') simple.move(y=thick / 2) simple.duplicate() simple.active_name('tmp') simple.union('tmp') if combination == 'M': simple.make_active('fingers') simple.mirrory() simple.active_name('tmp') simple.union('tmp') if combination == 'MF' or combination == 'F' or combination == 'f': simple.make_active('receptacle') simple.move(y=-thick / 2) simple.duplicate() simple.active_name('tmp') simple.difference('tmp', 'tmp') if combination == 'F': simple.make_active('receptacle') simple.mirrory() simple.active_name('tmp') simple.difference('tmp', 'tmp') simple.remove_multiple('receptacle') simple.remove_multiple('fingers') simple.rename('tmp', 't') simple.make_active('t')
def multiangle(radius, thick, angle, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, combination='MFF'): # length is the total width of the segments including 2 * radius and thick # radius = radius of the curve # thick = thickness of the bar # angle = angle of the female part # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # which = which joint to generate, Male Female MaleFemale M, F, MF r_exterior = radius + thick / 2 r_interior = radius - thick / 2 height = math.sqrt(r_exterior * r_exterior - radius * radius) + r_interior / 4 bpy.ops.curve.simple(align='WORLD', location=(0, height, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=r_interior, Simple_length=r_interior / 2, use_cyclic_u=True, edit_mode=False, shape='3D') simple.active_name('tmp_rect') bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_sides=4, Simple_radius=r_interior, shape='3D', use_cyclic_u=True, edit_mode=False) simple.move(y=radius * math.tan(angle)) simple.active_name('tmpCircle') arc(radius, thick, angle, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='MF') simple.active_name('tmp_arc') if combination == 'MFF': simple.duplicate() simple.mirrorx() elif combination == 'MMF': arc(radius, thick, angle, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='M') simple.active_name('tmp_arc') simple.mirrory() simple.rotate(math.pi / 2) simple.union("tmp_") simple.difference('tmp', 'tmp_') simple.active_name('multiAngle60')
def interlock_twist(length, thickness, finger_play, cx=0, cy=0, rotation=0, percentage=0.5): mortise(length, thickness, finger_play, 0, 0, 0) simple.active_name("_tmp") mortise(length * percentage, thickness, finger_play, 0, 0, math.pi / 2) simple.active_name("_tmp") h = math.hypot(thickness, length * percentage) oangle = math.degrees(math.asin(length * percentage / h)) bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Sector', Simple_startangle=90 + oangle, Simple_endangle=180 - oangle, Simple_radius=h / 2, use_cyclic_u=True, edit_mode=False) simple.active_name("_tmp") bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Sector', Simple_startangle=270 + oangle, Simple_endangle=360 - oangle, Simple_radius=h / 2, use_cyclic_u=True, edit_mode=False) simple.active_name("_tmp") simple.union('_tmp') simple.rotate(rotation) simple.move(x=cx, y=cy) simple.active_name("_groove") simple.remove_doubles()
def tile(diameter, tolerance, tile_x_amount, tile_y_amount, stem=1): global DT diameter = diameter * DT # diameter * DT * (2 + stem - 1) (4 + 2 * (stem - 1)) * diameter width = (tile_x_amount) * (4 + 2 * (stem - 1)) * diameter + diameter height = (tile_y_amount) * (4 + 2 * (stem - 1)) * diameter + diameter print('size:', width, height) fingers(diameter, tolerance, amount=tile_x_amount+2, stem=stem) simple.add_rectangle(width, height) simple.active_name('_base') simple.make_active('fingers') simple.active_name('_fingers') simple.intersect('_') simple.remove_multiple('_fingers') simple.rename('intersection', '_fingers') simple.move(y=height/2) simple.union('_') simple.active_name('_base') simple.remove_doubles() simple.rename('receptacle', '_receptacle') simple.move(y=-height/2) simple.difference('_', '_base') simple.active_name('base') fingers(diameter, tolerance, amount=tile_y_amount, stem=stem) simple.rename('base', '_base') simple.remove_doubles() simple.rename('fingers', '_fingers') simple.rotate(math.pi/2) simple.move(x=-width/2) simple.union('_') simple.active_name('_base') simple.rename('receptacle', '_receptacle') simple.rotate(math.pi/2) simple.move(x=width/2) simple.difference('_', '_base') simple.active_name('tile_ ' + str(tile_x_amount) + '_' + str(tile_y_amount))
def curved_t(length, thick, radius, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, combination='MF', base_gender='M'): bar(length, thick, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which=combination) simple.active_name('tmpbar') bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=3 * radius, Simple_length=thick, use_cyclic_u=True, edit_mode=False) simple.active_name("tmp_rect") if base_gender == 'MF': arc(radius, thick, math.pi / 2, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='M') simple.move(-radius) simple.active_name('tmp_arc') arc(radius, thick, math.pi / 2, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which='F') simple.move(radius) simple.mirrory() simple.active_name('tmp_arc') simple.union('tmp_arc') simple.duplicate() simple.mirrorx() simple.union('tmp_arc') simple.difference('tmp_', 'tmp_arc') else: arc(radius, thick, math.pi / 2, diameter, tolerance, amount=amount, stem=stem, twist=twist, tneck=tneck, tthick=tthick, which=base_gender) simple.active_name('tmp_arc') simple.difference('tmp_', 'tmp_arc') if base_gender == 'M': simple.move(-radius) else: simple.move(radius) simple.duplicate() simple.mirrorx() simple.union('tmp') simple.active_name('curved_t')
def open_curve(line, thick, diameter, tolerance, amount=0, stem=1, twist=False, t_neck=0.5, t_thick=0.01, twist_amount=1, which='MF', twist_keep=False): # puts puzzle connectors at the end of an open curve # optionally puts twist lock connectors at the puzzle connection # optionally puts twist lock connectors along the open curve # line = shapely linestring # thick = thickness of the bar # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # twist_amount = twist amount distributed on the curve not counting the joint twist locks # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # Which M,F, MF, MM, FF coords = list(line.coords) start_angle = joinery.angle(coords[0], coords[1]) + math.pi/2 end_angle = joinery.angle(coords[-1], coords[-2]) + math.pi/2 p_start = coords[0] p_end = coords[-1] print('start angle', start_angle) print('end angle', end_angle) bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=thick*2, Simple_length=thick * 2, use_cyclic_u=True, edit_mode=False, shape='3D') simple.active_name('tmprect') simple.move(y=thick) simple.duplicate() simple.rotate(start_angle) simple.move(x=p_start[0], y=p_start[1]) simple.make_active('tmprect') simple.rotate(end_angle) simple.move(x=p_end[0], y=p_end[1]) simple.union('tmprect') dilated = line.buffer(thick/2) # expand shapely object to thickness utils.shapelyToCurve('tmp_curve', dilated, 0.0) simple.difference('tmp', 'tmp_curve') # truncate curve at both ends with the rectangles fingers(diameter, tolerance, amount, stem=stem) simple.make_active('fingers') simple.rotate(end_angle) simple.move(x=p_end[0], y=p_end[1]) simple.active_name('tmp_fingers') simple.union('tmp_') simple.active_name('tmp_curve') twistm('tmp_curve', thick, diameter, tolerance, twist, t_neck, t_thick, end_angle, x=p_end[0], y=p_end[1], twist_keep=twist_keep) twistf('receptacle', thick, diameter, tolerance, twist, t_neck, t_thick, twist_keep=twist_keep) simple.rename('receptacle', 'tmp') simple.rotate(start_angle+math.pi) simple.move(x=p_start[0], y=p_start[1]) simple.difference('tmp', 'tmp_curve') if twist_keep: simple.make_active('twist_keep_f') simple.rotate(start_angle + math.pi) simple.move(x=p_start[0], y=p_start[1]) if twist_amount > 0 and twist: twist_start = line.length / (twist_amount+1) joinery.distributed_interlock(line, line.length, thick, t_thick, tolerance, twist_amount, tangent=math.pi/2, fixed_angle=0, start=twist_start, end=twist_start, closed=False, type='TWIST', twist_percentage=t_neck) if twist_keep: simple.duplicate() simple.active_name('twist_keep') simple.join_multiple('twist_keep') simple.make_active('interlock') simple.active_name('tmp_twist') simple.difference('tmp', 'tmp_curve') simple.active_name('puzzle_curve')
def mitre(length, thick, angle, angleb, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, which='MF'): # length is the total width of the segments including 2 * radius and thick # radius = radius of the curve # thick = thickness of the bar # angle = angle of the female part # angleb = angle of the male part # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # which = which joint to generate, Male Female MaleFemale M, F, MF # generate base rectangle bpy.ops.curve.simple(align='WORLD', location=(0, -thick / 2, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=length * 1.005 + 4 * thick, Simple_length=thick, use_cyclic_u=True, edit_mode=False, shape='3D') simple.active_name("tmprect") # generate cutout shapes bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=4 * thick, Simple_length=6 * thick, use_cyclic_u=True, edit_mode=False, shape='3D') simple.move(x=2 * thick) simple.rotate(angle) simple.move(x=length / 2) simple.active_name('tmpmitreright') bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Rectangle', Simple_width=4 * thick, Simple_length=6 * thick, use_cyclic_u=True, edit_mode=False, shape='3D') simple.move(x=2 * thick) simple.rotate(angleb) simple.move(x=length / 2) simple.mirrorx() simple.active_name('tmpmitreleft') simple.difference('tmp', 'tmprect') simple.make_active('tmprect') fingers(diameter, tolerance, amount, stem=stem) # Generate male section and join to the base if which == 'M' or which == 'MF': simple.make_active('fingers') simple.duplicate() simple.active_name('tmpfingers') simple.rotate(angle - math.pi / 2) h = thick / math.cos(angle) h /= 2 simple.move(x=length / 2 + h * math.sin(angle), y=-thick / 2) if which == 'M': simple.rename('fingers', 'tmpfingers') simple.rotate(angleb - math.pi / 2) h = thick / math.cos(angleb) h /= 2 simple.move(x=length / 2 + h * math.sin(angleb), y=-thick / 2) simple.mirrorx() simple.union('tmp') simple.active_name('tmprect') # Generate female section and join to base if which == 'MF' or which == 'F': simple.make_active('receptacle') simple.mirrory() simple.duplicate() simple.active_name('tmpreceptacle') simple.rotate(angleb - math.pi / 2) h = thick / math.cos(angleb) h /= 2 simple.move(x=length / 2 + h * math.sin(angleb), y=-thick / 2) simple.mirrorx() if which == 'F': simple.rename('receptacle', 'tmpreceptacle2') simple.rotate(angle - math.pi / 2) h = thick / math.cos(angle) h /= 2 simple.move(x=length / 2 + h * math.sin(angle), y=-thick / 2) simple.difference('tmp', 'tmprect') simple.remove_multiple('receptacle') simple.remove_multiple('fingers') simple.rename('tmprect', 'mitre')
def arc(radius, thick, angle, diameter, tolerance, amount=0, stem=1, twist=False, tneck=0.5, tthick=0.01, twist_keep=False, which='MF'): # radius = radius of the curve # thick = thickness of the bar # angle = angle of the arc # diameter = diameter of the tool for joint creation # tolerance = Tolerance in the joint # amount = amount of fingers in the joint 0 means auto generate # stem = amount of radius the stem or neck of the joint will have # twist = twist lock addition # tneck = percentage the twist neck will have compared to thick # tthick = thicknest of the twist material # which = which joint to generate, Male Female MaleFemale M, F, MF global DT # diameter tolerance for diameter of finger creation if angle == 0: # angle cannot be 0 angle = 0.01 negative = False if angle < 0: # if angle < 0 then negative is true angle = -angle negative = True if amount == 0: amount = round(thick / ((4 + 2 * (stem - 1)) * diameter * DT)) - 1 fingers(diameter, tolerance, amount, stem=stem) twistf('receptacle', thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep) # generate arc bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Segment', Simple_a=radius - thick / 2, Simple_b=radius + thick / 2, Simple_startangle=-0.0001, Simple_endangle=math.degrees(angle), Simple_radius=radius, use_cyclic_u=False, edit_mode=False) bpy.context.active_object.name = "tmparc" simple.rename('fingers', '_tmpfingers') simple.rotate(math.pi) simple.move(x=radius) bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN') simple.rename('tmparc', '_tmparc') if which == 'MF' or which == 'M': simple.union('_tmp') simple.active_name("base") twistm('base', thick, diameter, tolerance, twist, tneck, tthick, math.pi, x=radius) simple.rename('base', '_tmparc') simple.rename('receptacle', '_tmpreceptacle') simple.mirrory() simple.move(x=radius) bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN') simple.rotate(angle) simple.make_active('_tmparc') if which == 'MF' or which == 'F': simple.difference('_tmp', '_tmparc') bpy.context.active_object.name = "PUZZLE_arc" bpy.ops.object.curve_remove_doubles() simple.remove_multiple("_") # Remove temporary base and holes simple.make_active('PUZZLE_arc') if which == 'M': simple.rotate(-angle) simple.mirrory() bpy.ops.object.transform_apply(location=True, rotation=True, scale=False) simple.rotate(-math.pi / 2) simple.move(y=radius) simple.rename('PUZZLE_arc', 'PUZZLE_arc_male') elif which == 'F': simple.mirrorx() simple.move(x=radius) simple.rotate(math.pi / 2) simple.rename('PUZZLE_arc', 'PUZZLE_arc_receptacle') else: simple.move(x=-radius) # bpy.ops.object.transform_apply(location=True, rotation=False, scale=False, properties=False) # if negative: # mirror if angle is negative simple.mirrory()
def gear(mm_per_tooth=0.003, number_of_teeth=5, hole_diameter=0.003175, pressure_angle=0.3488, clearance=0.0, backlash=0.0, rim_size=0.0005, hub_diameter=0.006, spokes=4): simple.deselect() pi = math.pi p = mm_per_tooth * number_of_teeth / pi / 2 # radius of pitch circle c = p + mm_per_tooth / pi - clearance # radius of outer circle b = p * math.cos(pressure_angle) # radius of base circle r = p - (c - p) - clearance # radius of root circle t = mm_per_tooth / 2 - backlash / 2 # tooth thickness at pitch circle k = -gear_iang( b, p ) - t / 2 / p # angle to where involute meets base circle on each side of tooth shapely_gear = Polygon([(0, 0), gear_polar(r, k if r < b else -pi / number_of_teeth), gear_q7(0, r, b, c, k, 1), gear_q7(0.1, r, b, c, k, 1), gear_q7(0.2, r, b, c, k, 1), gear_q7(0.3, r, b, c, k, 1), gear_q7(0.4, r, b, c, k, 1), gear_q7(0.5, r, b, c, k, 1), gear_q7(0.6, r, b, c, k, 1), gear_q7(0.7, r, b, c, k, 1), gear_q7(0.8, r, b, c, k, 1), gear_q7(0.9, r, b, c, k, 1), gear_q7(1.0, r, b, c, k, 1), gear_q7(1.0, r, b, c, k, -1), gear_q7(0.9, r, b, c, k, -1), gear_q7(0.8, r, b, c, k, -1), gear_q7(0.7, r, b, c, k, -1), gear_q7(0.6, r, b, c, k, -1), gear_q7(0.5, r, b, c, k, -1), gear_q7(0.4, r, b, c, k, -1), gear_q7(0.3, r, b, c, k, -1), gear_q7(0.2, r, b, c, k, -1), gear_q7(0.1, r, b, c, k, -1), gear_q7(0.0, r, b, c, k, -1), gear_polar(r, -k if r < b else pi / number_of_teeth)]) utils.shapelyToCurve('tooth', shapely_gear, 0.0) i = number_of_teeth while i > 1: simple.duplicate() simple.rotate(2 * math.pi / number_of_teeth) i -= 1 simple.join_multiple('tooth') simple.active_name('_teeth') bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_radius=r, shape='3D', use_cyclic_u=True, edit_mode=False) simple.active_name('_hub') simple.union('_') simple.active_name('_gear') simple.remove_doubles() if spokes > 0: bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_radius=r - rim_size, shape='3D', use_cyclic_u=True, edit_mode=False) simple.active_name('_hole') simple.difference('_', '_gear') bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_radius=hub_diameter / 2, shape='3D', use_cyclic_u=True, edit_mode=False) simple.active_name('_hub') bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_radius=hole_diameter / 2, shape='3D', use_cyclic_u=True, edit_mode=False) simple.active_name('_hub_hole') simple.difference('_hub', '_hub') simple.join_multiple('_') simple.add_rectangle( r - rim_size - ((hub_diameter - hole_diameter) / 4 + hole_diameter / 2), hub_diameter / 2, center_x=False) simple.move(x=(hub_diameter - hole_diameter) / 4 + hole_diameter / 2) simple.active_name('_spoke') angle = 2 * pi / spokes while spokes > 0: simple.duplicate() simple.rotate(angle) spokes -= 1 simple.union('_spoke') simple.remove_doubles() simple.union('_') else: bpy.ops.curve.simple(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), Simple_Type='Circle', Simple_radius=hole_diameter, shape='3D', use_cyclic_u=True, edit_mode=False) simple.active_name('_hole') simple.difference('_', '_gear') name = 'gear-' + str(round(mm_per_tooth * 1000, 1)) name += 'mm-pitch-' + str(number_of_teeth) name += 'teeth-PA-' + str(round(math.degrees(pressure_angle), 1)) simple.active_name(name)