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 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 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 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 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 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()