Compare commits

...

10 Commits

  1. 5
      .gitignore
  2. 177
      belt_rivets.py
  3. 91
      coaster.py
  4. 33
      dice.py
  5. 17
      double_laptop_stand.py
  6. 40
      enclosure.py
  7. 61
      light_holder.py
  8. 4
      oil_cap.py
  9. 50
      picture_frame.py
  10. 8
      planter.py
  11. 6
      power_bar_holder.py
  12. 88
      robot_chassis.py
  13. 49
      robot_steering.py
  14. 45
      solder_stand.py
  15. BIN
      svgs/WK.png
  16. 50
      tape_holder.py
  17. 12
      threaded_tool_holder.py
  18. 37
      tool_holder.py
  19. 72
      tool_holder_final.py
  20. 20
      utilities.py
  21. 120
      watch_stand.py
  22. 26
      webcam_stand.py
  23. 133
      xmas_coaster.py

5
.gitignore

@ -1,4 +1,7 @@
*swp *swp
*step *step
*3mf *3mf
*otf
*ttf
*TTF
__pycache__

177
belt_rivets.py

@ -0,0 +1,177 @@
from cadquery import exporters
from cq_warehouse.extensions import Workplane
from cq_warehouse.fastener import *
from cq_warehouse.thread import *
from cqmore.curve import archimedeanSpiral, circle
from cqmore.polygon import regularPolygon, star
from cqmore.polyhedron import polarZonohedra, Polyhedron, superellipsoid
from svg_path import addSvgPath
from svgpathtools import svg2paths
import cadquery as cq
import cqmore
Workplane = cqmore.extend(Workplane)
Workplane.addSvgPath = addSvgPath
# wk_paths, wk_attributes = svg2paths(
# "/home/deck/cad_files/svgs/wk_edited.svg"
# )
inner_radius = 5
outer_radius = 7
thickness = 3.5
rivet_inner_radius = 2
rivet_outer_radius = 3.5
rivet_thickness = 3
belt_width = 39
loop_thickness = 1.83
loop_side_thickness = 5
loop_height = 11.5 + loop_thickness
loop_width = 25
loop_length = belt_width + loop_side_thickness
slide_width_bottom = loop_side_thickness - 3
slide_width_top = loop_side_thickness - 4
logo = Workplane().circle(outer_radius).extrude(thickness)
logo = logo.faces(">Z[0]").circle(inner_radius + 0.9).extrude(thickness, combine="cut")
logo = logo.faces(">Z[0]").circle(inner_radius).extrude(thickness)
logo = (
logo.faces(">Z[1]")
.center(0, 0)
.cylinder(thickness + 2, inner_radius - 1, combine="cut")
)
logo = (
logo.workplane(offset=1.0)
.circle(outer_radius + 4)
.extrude(1)
.workplane(offset=0.5)
.text("WK", 10, 0.8, combine="cut")
)
# wk = Workplane("XY").center(0, 0).addSvgPath(wk_paths[0]).extrude(-2.0)
# logo = logo.union(wk, clean=False)
logo_outer = Workplane().circle(inner_radius + 1).extrude(thickness)
logo_outer = (
logo_outer.faces(">Z[0]").circle(inner_radius).extrude(thickness, combine="cut")
)
logo_outer = logo_outer.workplane(offset=1.0).circle(outer_radius + 4).extrude(1)
cq.exporters.export(logo, "/home/deck/model_files/belt_hole_inner.step")
cq.exporters.export(logo_outer, "/home/deck/model_files/belt_hole_outer.step")
rivet = Workplane().circle(rivet_outer_radius).extrude(rivet_thickness)
rivet = (
rivet.faces(">Z[0]")
.circle(rivet_inner_radius + 1.10)
.extrude(rivet_thickness, combine="cut")
)
rivet = rivet.faces(">Z[0]").circle(rivet_inner_radius - 0.15).extrude(rivet_thickness)
rivet = (
rivet.faces(">Z[1]")
.center(0, 0)
.cylinder(rivet_thickness + 2, rivet_inner_radius - 1, combine="cut")
)
rivet = rivet.workplane(offset=1.0).circle(rivet_outer_radius + 1).extrude(1)
rivet_outer = Workplane().circle(rivet_inner_radius + 0.4).extrude(rivet_thickness)
rivet_outer = (
rivet_outer.faces(">Z[0]")
.circle(rivet_inner_radius)
.extrude(rivet_thickness, combine="cut")
)
rivet_outer = (
rivet_outer.workplane(offset=1.0).circle(rivet_outer_radius + 1).extrude(1)
)
loop = Workplane().box(loop_length, loop_width, loop_height)
loop_cut = Workplane().box(
loop_length - loop_thickness - loop_side_thickness,
loop_width,
loop_height - loop_thickness,
)
loop = loop.cut(loop_cut)
loop_top = loop.faces(">Z[0]").workplane(offset=-1.8).split(keepTop=True)
loop_bottom = loop.faces(">Z[0]").workplane(offset=-1).split(keepBottom=True)
slide_bottom_cut_left = (
Workplane()
.move(-((loop_length / 2) - loop_thickness), 0)
.box(slide_width_bottom, loop_width, 2)
)
slide_bottom_cut_right = (
Workplane()
.move(((loop_length / 2) - loop_thickness), 0)
.box(slide_width_bottom, loop_width, 2)
)
slide_top_cut_left = (
Workplane()
.workplane(offset=-2.8)
.move(-((loop_length / 2) - loop_thickness), 0)
.box(slide_width_top, loop_width, loop_height / 2)
)
slide_top_cut_right = (
Workplane()
.workplane(offset=-2.8)
.move(((loop_length / 2) - loop_thickness), 0)
.box(slide_width_top, loop_width, loop_height / 2)
)
slide_bottom_union_left = (
Workplane()
.workplane(offset=1)
.move(-((loop_length / 2) - loop_thickness), 0)
.box(slide_width_bottom - 0.3, loop_width, 1.8)
)
slide_bottom_union_right = (
Workplane()
.workplane(offset=1)
.move(((loop_length / 2) - loop_thickness), 0)
.box(slide_width_bottom - 0.3, loop_width, 1.8)
)
slide_top_union_left = (
Workplane()
.workplane(offset=-1.8)
.move(-((loop_length / 2) - loop_thickness), 0)
.box(slide_width_top, loop_width, loop_height / 2)
)
slide_top_union_right = (
Workplane()
.workplane(offset=-1.8)
.move(((loop_length / 2) - loop_thickness), 0)
.box(slide_width_top, loop_width, loop_height / 2)
)
loop_bottom = loop_bottom.cut(slide_bottom_cut_left)
loop_bottom = loop_bottom.cut(slide_bottom_cut_right)
loop_bottom = loop_bottom.cut(slide_top_cut_left)
loop_bottom = loop_bottom.cut(slide_top_cut_right)
loop_top = loop_top.union(slide_bottom_union_left)
loop_top = loop_top.union(slide_bottom_union_right)
loop_top = loop_top.union(slide_top_union_left)
loop_top = loop_top.union(slide_top_union_right)
loop_top = (
loop_top.faces(">Z[0]")
.rect(loop_width, loop_height, forConstruction=True)
.vertices()
.hole((rivet_outer_radius * 2) + 1)
)
cq.exporters.export(rivet, "/home/deck/model_files/rivet_inner.step")
cq.exporters.export(rivet_outer, "/home/deck/model_files/rivet_outer.step")
cq.exporters.export(loop_bottom, "/home/deck/model_files/loop_bottom.step")
cq.exporters.export(loop_top, "/home/deck/model_files/loop_top.step")
try:
show_object(rivet_outer)
# show_object(rivet)
# show_object(loop_bottom)
# show_object(loop_top)
except NameError:
pass

91
coaster.py

@ -8,50 +8,67 @@ xmas_tree_offset = -35
xmas_tree_height = 12 xmas_tree_height = 12
xmas_tree_width = 12 xmas_tree_width = 12
def makeTriangle(self, width, height, x_offset=0, y_offset=0): def makeTriangle(self, width, height, x_offset=0, y_offset=0):
return (self.moveTo(x_offset-(width), y_offset).makePolygon( return (
[ self.moveTo(x_offset - (width), y_offset)
(0,0,0),(width,height,0), (width*2,0,0), .makePolygon(
] [
) (0, 0, 0),
.cutBlind(30) (width, height, 0),
.clean()) (width * 2, 0, 0),
]
)
.cutBlind(30)
.clean()
)
def makeXmasTree(self): def makeXmasTree(self):
return (self.center(0,0) return (
.triangle(xmas_tree_width, xmas_tree_height, y_offset=-(xmas_tree_offset)) self.center(0, 0)
.triangle(xmas_tree_width+3, xmas_tree_height+3, y_offset=-(xmas_tree_offset+8)) .triangle(xmas_tree_width, xmas_tree_height, y_offset=-(xmas_tree_offset))
.triangle(xmas_tree_width+1, xmas_tree_height+13, y_offset=-(xmas_tree_offset+15)) .triangle(
.triangle(xmas_tree_width-2, xmas_tree_height+16, y_offset=-(xmas_tree_offset+20)) xmas_tree_width + 3, xmas_tree_height + 3, y_offset=-(xmas_tree_offset + 8)
.moveTo(0, -(xmas_tree_offset+22)) )
.rect(5,8) .triangle(
.cutBlind(30)) xmas_tree_width + 1,
xmas_tree_height + 13,
y_offset=-(xmas_tree_offset + 15),
)
.triangle(
xmas_tree_width - 2,
xmas_tree_height + 16,
y_offset=-(xmas_tree_offset + 20),
)
.moveTo(0, -(xmas_tree_offset + 22))
.rect(5, 8)
.cutBlind(30)
)
Workplane.triangle = makeTriangle Workplane.triangle = makeTriangle
Workplane.xmasTree = makeXmasTree Workplane.xmasTree = makeXmasTree
polygon = (Workplane() polygon = (
.makePolygon( Workplane()
regularPolygon( .makePolygon(
nSides = 16, regularPolygon(nSides=16, radius=coaster_radius, thetaStart=0, thetaEnd=360)
radius = coaster_radius, )
thetaStart = 0, .extrude(10)
thetaEnd = 360 .xmasTree()
) .workplane()
) )
.extrude(10)
.xmasTree() text_solid = Workplane().text(
.workplane() "David Kerfoot",
) 25,
25,
text_solid = (Workplane() clean=False,
.text("David Kerfoot", combine=False,
25, 25, fontPath="/home/wes/fonts/StackyardPersonalUse-16Dj.ttf",
clean=False, )
combine=False,
fontPath="/home/wes/fonts/StackyardPersonalUse-16Dj.ttf")
)
result = polygon.cut(text_solid) result = polygon.cut(text_solid)

33
dice.py

@ -9,18 +9,20 @@ from cad_utilities.shapes import makeDice
from typing import cast from typing import cast
from cadquery import Face from cadquery import Face
from cqmore import Workplane from cqmore import Workplane
from cqmore.polyhedron import tetrahedron, hexahedron, octahedron, dodecahedron, icosahedron from cqmore.polyhedron import (
tetrahedron,
hexahedron,
octahedron,
dodecahedron,
icosahedron,
)
radius = 20 radius = 20
font_name = 'Arial Black' font_name = "Arial Black"
font_distance = 2 font_distance = 2
detail = 0 detail = 0
dice = (Workplane() dice = Workplane().polyhedron(*icosahedron(radius, detail))
.polyhedron(
*icosahedron(radius, detail)
)
)
faces = dice.faces().vals() faces = dice.faces().vals()
nums = len(faces) nums = len(faces)
@ -31,20 +33,19 @@ for i in range(nums):
text_to_write = "20" text_to_write = "20"
font_size = 8.5 font_size = 8.5
else: else:
text_to_write = str(nums-i) text_to_write = str(nums - i)
font_size = 8.5 font_size = 8.5
texts.add( texts.add(
Workplane(faces[i]) Workplane(faces[i])
.workplane(origin = cast(Face, faces[i]).Center()) .workplane(origin=cast(Face, faces[i]).Center())
.text( .text(
text_to_write, text_to_write,
font_size, font_size,
-font_distance, -font_distance,
fontPath="/home/deck/fonts/SEVESBRG.TTF" fontPath="/home/deck/fonts/SEVESBRG.TTF",
) )
) )
dice = dice.cut(texts) dice = dice.cut(texts)
cq.exporters.export(dice, "/home/deck/model_files/dice.step") cq.exporters.export(dice, "/home/deck/model_files/dice.step")

17
double_laptop_stand.py

@ -0,0 +1,17 @@
from cadquery import exporters
from cq_warehouse.extensions import Workplane
from cq_warehouse.fastener import *
from cq_warehouse.thread import *
from cqmore.curve import archimedeanSpiral, circle
from cqmore.polygon import regularPolygon, star
from cqmore.polyhedron import polarZonohedra, Polyhedron, superellipsoid
from svg_path import addSvgPath
from svgpathtools import svg2paths
import cadquery as cq
import cqmore
xps_height = 200
xps_width = 300
xps_thickness = 10
pb_width = 330

40
enclosure.py

@ -20,15 +20,15 @@ end_socket_height = 22.6
# the distance from the side of the socket to the edge of the box # the distance from the side of the socket to the edge of the box
# for the socket that powers the relay coil # for the socket that powers the relay coil
end_socket_distance_from_side = 3.47 + 3 # add 3mm for tape end_socket_distance_from_side = 3.47 + 3 # add 3mm for tape
reset_button_dist_from_socket = 5.27 reset_button_dist_from_socket = 5.27
reset_width = 18.7 reset_width = 18.7
reset_height = 35.04 reset_height = 35.04
reset_lip_height = 3.37 # probably not needed reset_lip_height = 3.37 # probably not needed
# parameter definitions # parameter definitions
p_outerWidth = relay_x_size + 15 # Outer width of box enclosure p_outerWidth = relay_x_size + 15 # Outer width of box enclosure
p_outerLength = relay_y_size # Outer length of box enclosure p_outerLength = relay_y_size # Outer length of box enclosure
p_outerHeight = 33.6 + 30 # Outer height of box enclosure p_outerHeight = 33.6 + 30 # Outer height of box enclosure
@ -100,23 +100,29 @@ box = (
.all() .all()
) # splits into two solids ) # splits into two solids
lid = (lid.workplane() lid = (
.rect(socket_width+socket_distance_x, socket_distance_y+(socket_width), lid.workplane()
forConstruction=True) .rect(
.tag("sockets") socket_width + socket_distance_x,
.vertices() socket_distance_y + (socket_width),
.rect(socket_width, socket_width) forConstruction=True,
.cutThruAll()) )
.tag("sockets")
.vertices()
.rect(socket_width, socket_width)
.cutThruAll()
)
bottom = (bottom bottom = (
.faces(">Y") bottom.faces(">Y")
.workplane() .workplane()
.center(0, -end_socket_height+8) .center(0, -end_socket_height + 8)
.rect(end_socket_width, end_socket_height) .rect(end_socket_width, end_socket_height)
.cutBlind("next")) .cutBlind("next")
)
#lid = (lid.center(socket_width-8, socket_distance_y+(socket_width)-3) # lid = (lid.center(socket_width-8, socket_distance_y+(socket_width)-3)
# .rect(reset_height, reset_width) # .rect(reset_height, reset_width)
# .cutThruAll()) # .cutThruAll())

61
light_holder.py

@ -27,27 +27,50 @@ clip_thickness = 15
clip_length = 65 clip_length = 65
clip_width = 60 clip_width = 60
clip_distance_from_sensor = 90 # how far it is from the enclosure clip_distance_from_sensor = 90 # how far it is from the enclosure
result = (Workplane(). result = (
box(outer_len, outer_width, outer_thickness) Workplane().box(outer_len, outer_width, outer_thickness).edges("|Z").fillet(0.9)
.edges("|Z").fillet(0.9)) )
result = result.moveTo(outer_width-recess_width, 0).rect(recess_width, recess_height).extrude(5) result = (
result = result.moveTo(-outer_width+recess_width, 0).rect(recess_width, recess_height).extrude(5) result.moveTo(outer_width - recess_width, 0)
result = result.workplane(offset=-(outer_thickness/2)-0.33).moveTo(-outer_len/2, 0).rect(clip_length/2, clip_width).extrude(outer_thickness) .rect(recess_width, recess_height)
result = result.workplane(offset=-0.33).moveTo(inner_height+(clip_length/2.0)-1, 0).box(clip_width/1.8, clip_width/2.5, outer_thickness).moveTo(outer_len/2+26, 0).cylinder(10, 5/2, combine="cut") .extrude(5)
result = result.moveTo(outer_len/2.4+30, 0).cylinder(10, 12/2, combine="cut") )
result = (
result.moveTo(-outer_width + recess_width, 0)
.rect(recess_width, recess_height)
.extrude(5)
)
result = (
result.workplane(offset=-(outer_thickness / 2) - 0.33)
.moveTo(-outer_len / 2, 0)
.rect(clip_length / 2, clip_width)
.extrude(outer_thickness)
)
result = (
result.workplane(offset=-0.33)
.moveTo(inner_height + (clip_length / 2.0) - 1, 0)
.box(clip_width / 1.8, clip_width / 2.5, outer_thickness)
.moveTo(outer_len / 2 + 26, 0)
.cylinder(10, 5 / 2, combine="cut")
)
result = result.moveTo(outer_len / 2.4 + 30, 0).cylinder(10, 12 / 2, combine="cut")
result = result.faces(">Z[0]").moveTo(-70, 0).rect(10, clip_width).extrude(clip_length) result = result.faces(">Z[0]").moveTo(-70, 0).rect(10, clip_width).extrude(clip_length)
result = (result.faces(">Z[1]").moveTo(0,0) result = (
.rect(outer_len-hole_dist_from_short-hole_diameter*2, result.faces(">Z[1]")
outer_width-hole_dist_from_long-hole_diameter*3, .moveTo(0, 0)
forConstruction=True) .rect(
.vertices().cylinder(outer_thickness*3, hole_diameter/2, combine="cut")) outer_len - hole_dist_from_short - hole_diameter * 2,
outer_width - hole_dist_from_long - hole_diameter * 3,
forConstruction=True,
)
.vertices()
.cylinder(outer_thickness * 3, hole_diameter / 2, combine="cut")
)
cq.exporters.export(result, "/home/deck/model_files/light_holder.step") cq.exporters.export(result, "/home/deck/model_files/light_holder.step")

4
oil_cap.py

@ -8,8 +8,8 @@ import itertools as it
from cad_utilities.shapes import makeTriangle from cad_utilities.shapes import makeTriangle
cone = cq.Solid.makeCone(8/2, 1, 28) cone = cq.Solid.makeCone(8 / 2, 1, 28)
result = Workplane().circle(8.3/2).extrude(30).cut(cone) result = Workplane().circle(8.3 / 2).extrude(30).cut(cone)
cq.exporters.export(result, "/home/deck/model_files/oil_cap.step") cq.exporters.export(result, "/home/deck/model_files/oil_cap.step")

50
picture_frame.py

@ -7,47 +7,55 @@ import functools as fnc
import itertools as it import itertools as it
picture_height = 178.3 picture_height = 178.3
length = picture_height+5 length = picture_height + 5
picture_length = 4.2 picture_length = 4.2
width = picture_length + 10 width = picture_length + 10
picture_width = 127 picture_width = 127
height = picture_width + 10 height = picture_width + 10
triangle_size = 25 triangle_size = 25
triangle_width = width+15 triangle_width = width + 15
def makeTriangle(self, width, height, x_offset=0, y_offset=0): def makeTriangle(self, width, height, x_offset=0, y_offset=0):
return (self.moveTo(x_offset-(width), y_offset).makePolygon( return self.moveTo(x_offset - (width), y_offset).makePolygon(
[ [
(width, height, 0), (width*2, 0, 0), (width*2, width*2, 0), (width, height, 0),
] (width * 2, 0, 0),
)) (width * 2, width * 2, 0),
]
)
def add_triangle(plane, width, height, offset): def add_triangle(plane, width, height, offset):
return plane.triangle(width, height, y_offset=offset) return plane.triangle(width, height, y_offset=offset)
Workplane.triangle = makeTriangle Workplane.triangle = makeTriangle
result = Workplane("front").box(length, width, height) result = Workplane("front").box(length, width, height)
result = result.workplane().box(length-20, width, height-15, True, "cut") result = result.workplane().box(length - 20, width, height - 15, True, "cut")
result = result.workplane().box(length-2, picture_length, picture_width+2, True, "cut") result = result.workplane().box(
length - 2, picture_length, picture_width + 2, True, "cut"
)
result = result.faces("<X[4]").workplane(0, True).rect(width, height).cutBlind(1) result = result.faces("<X[4]").workplane(0, True).rect(width, height).cutBlind(1)
result = (result.faces("<X[0]") result = (
.workplane() result.faces("<X[0]")
.rect(width, height) .workplane()
.extrude(triangle_size*0.5) .rect(width, height)
.faces("<Z[4]") .extrude(triangle_size * 0.5)
.workplane() .faces("<Z[4]")
.triangle(triangle_size , triangle_size, 0, -(triangle_size)) .workplane()
.extrude(triangle_width) .triangle(triangle_size, triangle_size, 0, -(triangle_size))
.faces("<Z[1]") .extrude(triangle_width)
.workplane() .faces("<Z[1]")
.triangle(triangle_size,triangle_size, 0, -(triangle_size)) .workplane()
.extrude(triangle_width)) .triangle(triangle_size, triangle_size, 0, -(triangle_size))
.extrude(triangle_width)
)
cq.exporters.export(result, "/home/deck/model_files/small_frame.step") cq.exporters.export(result, "/home/deck/model_files/small_frame.step")

8
planter.py

@ -53,10 +53,10 @@ gandalf_paths, gandalf_attributes = svg2paths("/home/deck/cad_files/svgs/gandalf
tolkien_paths, tolkien_attributes = svg2paths("/home/deck/cad_files/svgs/tolkien.svg") tolkien_paths, tolkien_attributes = svg2paths("/home/deck/cad_files/svgs/tolkien.svg")
svgs_to_render = [ svgs_to_render = [
(gondor_paths, (95.03, -100, 0), "cut", "YZ"), (gondor_paths, (95.03, -100, 0), "cut", "YZ"),
(gondor_paths, (-99, 93.02, 0), "cut", "XZ"), (gondor_paths, (-99, 93.02, 0), "cut", "XZ"),
(tolkien_paths, (-93.03, -14.5, 85), "cut", "YZ"), (tolkien_paths, (-93.03, -14.5, 85), "cut", "YZ"),
(tolkien_paths, (-14.5, -95.0, 85), "cut", "XZ"), (tolkien_paths, (-14.5, -95.0, 85), "cut", "XZ"),
] ]
if RENDER_TREES: if RENDER_TREES:

6
power_bar_holder.py

@ -12,8 +12,10 @@ holder_height = 4
holder_width = 1 holder_width = 1
post_height = 10 post_height = 10
result = Workplane().box(holder_length, holder_height, holder_width).edges("|Z").fillet(0.9) result = (
Workplane().box(holder_length, holder_height, holder_width).edges("|Z").fillet(0.9)
)
result = result.workplane(offset=4.5).cylinder(post_height, post_width/2) result = result.workplane(offset=4.5).cylinder(post_height, post_width / 2)
cq.exporters.export(result, "/home/deck/model_files/power_holder_new.step") cq.exporters.export(result, "/home/deck/model_files/power_holder_new.step")

88
robot_chassis.py

@ -0,0 +1,88 @@
from cadquery import exporters
from cq_warehouse.extensions import Workplane
from cq_warehouse.fastener import *
from cq_warehouse.thread import *
from cqmore.curve import archimedeanSpiral, circle
from cqmore.polygon import regularPolygon, star
from cqmore.polyhedron import polarZonohedra, Polyhedron, superellipsoid
from svg_path import addSvgPath
from svgpathtools import svg2paths
import cadquery as cq
import cqmore
from cq_gears import (
SpurGear,
Worm,
HerringboneGear,
RackGear,
HerringboneRackGear,
BevelGear,
BevelGearPair,
)
turn_width = 5
turn_length = 150
turn_height = 45
servo_diameter = 4.6
servo_height = 12
screw_diameter = 3.2
screw_head_diameter = 5.6
spur_gear = SpurGear(module=1.0, teeth_number=19, width=5.0, bore_d=5.0)
drive_result = cq.Workplane("XY").gear(spur_gear)
drive_result = drive_result.cylinder(turn_length, turn_width)
turn_shaft_height = 10
turn_shaft_width = 8
turn_result = cq.Workplane("XY").box(turn_length, turn_height, turn_width)
turn_result = (
turn_result.faces(">Z[0]")
.workplane()
.move(-(turn_length / 3.5), 0)
.rect(
32.2 - (screw_head_diameter * 2) + 4,
37.9 - (screw_head_diameter * 2) + 4,
forConstruction=True,
)
.vertices()
.cskHole(screw_diameter, screw_head_diameter, 83, depth=None)
)
turn_result = (
turn_result.faces(">Z[0]")
.workplane()
.move((turn_length / 3.5), 0)
.rect(
32.2 - (screw_head_diameter * 2) + 4,
37.9 - (screw_head_diameter * 2) + 4,
forConstruction=True,
)
.vertices()
.cskHole(screw_diameter, screw_head_diameter, 83, depth=None)
)
turn_result = (
turn_result.faces(">Z[0]")
.workplane(offset=5)
.center(0, 0)
.cylinder(turn_shaft_height, turn_shaft_width / 2)
)
turn_result = (
turn_result.faces(">Z[1]")
.workplane(offset=(turn_shaft_height - (servo_height / 2)))
.center(0, 0)
.cylinder(servo_height, servo_diameter / 2, combine="cut")
)
try:
show_object(turn_result)
except NameError:
pass
cq.exporters.export(turn_result, "/home/deck/model_files/robot_turn_part.step")

49
robot_steering.py

@ -0,0 +1,49 @@
from cadquery import exporters
from cq_warehouse.extensions import Workplane
from cq_warehouse.fastener import *
from cq_warehouse.thread import *
from cqmore.polygon import regularPolygon, star
import cadquery as cq
import cqmore
bottom_radius = 5
inner_screw_nsides = 6
Workplane = cqmore.extend(Workplane)
simple = False
screw = ButtonHeadScrew(
size="M4-0.7", fastener_type="iso7380_1", length=10 * MM, simple=simple
)
nut_result = (
Workplane()
.makePolygon(star(outerRadius=bottom_radius, innerRadius=bottom_radius, n=8))
.extrude(5)
)
scaled_screw = screw.scale(1.01)
screw_result = (
Workplane()
# .makePolygon(star(outerRadius=bottom_radius, innerRadius=13, n=8))
# .extrude(8)
.union(scaled_screw)
)
nut_result = nut_result.workplane(offset=3).threadedHole(screw, 5.5, simple=simple)
box = Workplane().box(190, 100, 100)
box = box.workplane(offset=0).move(10, 0).box(190, 90, 90, combine="cut")
box = box.workplane(offset=0).move(50, 0).hole(7)
try:
show_object(scaled_screw)
# show_object(box)
# show_object(nut_result)
except NameError:
pass
cq.exporters.export(screw_result, "/home/deck/model_files/robot_turn_part.step")

45
solder_stand.py

@ -9,24 +9,41 @@ import itertools as it
height = 30 height = 30
width = 94 width = 94
length = 130 length = 130
stand_height=23 stand_height = 23
socket_radius = 10.7/2 socket_radius = 10.7 / 2
result = Workplane().box(length, width, height).edges("|Z").fillet(0.9) result = Workplane().box(length, width, height).edges("|Z").fillet(0.9)
result = result.workplane(offset=5).box(length-5, width-20, height, combine="cut") result = result.workplane(offset=5).box(length - 5, width - 20, height, combine="cut")
result = (result.workplane(offset=10).moveTo(0, -(width/2)+5) result = (
.box(length=length, width=0.85, height=stand_height, combine="cut")) result.workplane(offset=10)
.moveTo(0, -(width / 2) + 5)
result = (result.workplane(offset=10).moveTo(0, (width/2)-5) .box(length=length, width=0.85, height=stand_height, combine="cut")
.box(length=length, width=0.85, height=stand_height, combine="cut")) )
result = result.faces(">X[3]").workplane().moveTo(-25,-5).sphere(socket_radius, combine="cut") result = (
result = result.faces(">X[1]").box(12.5,5.5,7.5, combine="cut") result.workplane(offset=10)
.moveTo(0, (width / 2) - 5)
result = result.faces(">X[0]").center(15, -10).text("Danger!", 8.5, -1.6, fontPath="/home/wes/fonts/StackyardPersonalUse-16Dj.ttf") .box(length=length, width=0.85, height=stand_height, combine="cut")
)
result = (
result.faces(">X[3]")
.workplane()
.moveTo(-25, -5)
.sphere(socket_radius, combine="cut")
)
result = result.faces(">X[1]").box(12.5, 5.5, 7.5, combine="cut")
result = (
result.faces(">X[0]")
.center(15, -10)
.text(
"Danger!", 8.5, -1.6, fontPath="/home/wes/fonts/StackyardPersonalUse-16Dj.ttf"
)
)
cq.exporters.export(result, "/home/deck/model_files/solder_stand.step") cq.exporters.export(result, "/home/deck/model_files/solder_stand.step")

BIN
svgs/WK.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

50
tape_holder.py

@ -11,24 +11,26 @@ import itertools as it
def makeTriangle(self, width, height, x_offset=0, y_offset=0): def makeTriangle(self, width, height, x_offset=0, y_offset=0):
return (self.move(x_offset, y_offset).makePolygon( return self.move(x_offset, y_offset).makePolygon(
[ [(height / 2, width * 20, -width), (0, width, 0), (width, height, 0)]
(height/2, width*20, -width), (0, width, 0), (width, height, 0) )
]
))
def add_triangle(plane, width, height, offset): def add_triangle(plane, width, height, offset):
return plane.triangle(width, height, y_offset=offset) return plane.triangle(width, height, y_offset=offset)
Workplane.triangle = makeTriangle Workplane.triangle = makeTriangle
# must be 17 mm wide # must be 17 mm wide
# gap must be at least 4 mm # gap must be at least 4 mm
holder_dim = (18, 30, 30) holder_dim = (18, 30, 30)
holder_slot_dim = (holder_dim[0] + holder_dim[0]*0.65, holder_slot_dim = (
holder_dim[1]-holder_dim[1]*0.2, holder_dim[0] + holder_dim[0] * 0.65,
holder_dim[1]-holder_dim[1]*0.865) # should be around 4mm holder_dim[1] - holder_dim[1] * 0.2,
holder_dim[1] - holder_dim[1] * 0.865,
) # should be around 4mm
pole_dim = (18, 10) pole_dim = (18, 10)
lip_dim = (pole_dim[0], 15) lip_dim = (pole_dim[0], 15)
@ -38,20 +40,30 @@ print(holder_slot_dim)
result = Workplane().box(*holder_dim) result = Workplane().box(*holder_dim)
result = result.workplane().moveTo(0, -5).box(*holder_slot_dim, True, "cut") result = result.workplane().moveTo(0, -5).box(*holder_slot_dim, True, "cut")
result = (result.faces(">Z").workplane() result = (
.moveTo(0, (holder_dim[0]) - 8) result.faces(">Z")
.rect(*pole_dim).extrude(pole_length)) .workplane()
.moveTo(0, (holder_dim[0]) - 8)
.rect(*pole_dim)
.extrude(pole_length)
)
support_width = 10 support_width = 10
result = result.faces(">Y[1]").workplane().triangle(support_width, result = (
support_width, result.faces(">Y[1]")
-support_width/2, .workplane()
-holder_dim[0]).extrude(15) .triangle(support_width, support_width, -support_width / 2, -holder_dim[0])
.extrude(15)
)
result = (result.faces(">Z[3]").center(0, pole_length-lip_dim[0]/4).workplane() result = (
.moveTo(0, lip_dim[1]) result.faces(">Z[3]")
.rect(*lip_dim).extrude(pole_dim[0]/4)) .center(0, pole_length - lip_dim[0] / 4)
.workplane()
.moveTo(0, lip_dim[1])
.rect(*lip_dim)
.extrude(pole_dim[0] / 4)
)
cq.exporters.export(result, "/home/deck/cad_files/tape_holder.step") cq.exporters.export(result, "/home/deck/cad_files/tape_holder.step")

12
threaded_tool_holder.py

@ -31,21 +31,21 @@ screw_result = (
.union(scaled_screw) .union(scaled_screw)
) )
nut_result = nut_result.workplane(offset=9.4).threadedHole( nut_result = nut_result.workplane(offset=9.3).threadedHole(screw, 13, simple=simple)
screw, 13, simple=simple
)
box = Workplane().box(190, 100, 100) box = Workplane().box(190, 100, 100)
box = box.workplane(offset=0).move(10, 0).box(190, 90, 90, combine="cut") box = box.workplane(offset=0).move(10, 0).box(190, 90, 90, combine="cut")
box = box.workplane(offset=0).move(50, 0).hole(7) box = box.workplane(offset=0).move(50, 0).hole(7)
try: try:
#show_object(screw_result) # show_object(screw_result)
#show_object(box) # show_object(box)
show_object(nut_result) show_object(nut_result)
except NameError: except NameError:
pass pass
cq.exporters.export(screw_result, "/home/deck/model_files/threaded_tool_holder_screw.step") cq.exporters.export(
screw_result, "/home/deck/model_files/threaded_tool_holder_screw.step"
)
cq.exporters.export(nut_result, "/home/deck/model_files/threaded_tool_holder_nut.step") cq.exporters.export(nut_result, "/home/deck/model_files/threaded_tool_holder_nut.step")
cq.exporters.export(box, "/home/deck/model_files/threaded_tool_holder_box.step") cq.exporters.export(box, "/home/deck/model_files/threaded_tool_holder_box.step")

37
tool_holder.py

@ -15,24 +15,29 @@ base_thickness = 7
height = 2.5 height = 2.5
result = (cq.Workplane().moveTo(-top_rect_len+2, 0) result = (
.box(sides_width, bottom_rect_len, height) cq.Workplane()
.edges("|Z").fillet(1.25)) .moveTo(-top_rect_len + 2, 0)
.box(sides_width, bottom_rect_len, height)
.edges("|Z")
result = (result.faces(">Z[0]").circle(1.5) .fillet(1.25)
)
result = (
result.faces(">Z[0]").circle(1.5).workplane().circle(sides_width - 1).loft().clean()
)
result = result.faces(">Z[0]").box(
bottom_rect_len * 6, bottom_rect_len * 2, base_thickness
)
result = (
result.faces(">Z")
.workplane() .workplane()
.circle(sides_width-1) .rect(bottom_rect_len * 5, bottom_rect_len * 1, forConstruction=True)
.loft()
.clean())
result = result.faces(">Z[0]").box(bottom_rect_len*6, bottom_rect_len*2, base_thickness)
result = (result
.faces(">Z").workplane()
.rect(bottom_rect_len*5, bottom_rect_len*1, forConstruction=True)
.vertices() .vertices()
.cboreHole(4,8,7, depth=None)) .cboreHole(4, 8, 7, depth=None)
)
cq.exporters.export(result, "/home/deck/cad_files/power_bar_holder.step") cq.exporters.export(result, "/home/deck/cad_files/power_bar_holder.step")

72
tool_holder_final.py

@ -22,34 +22,52 @@ magnet_slot_offset = 10
second_slot_offset = -25 second_slot_offset = -25
result = Workplane("front").box(length, width, height) result = Workplane("front").box(length, width, height)
result = result.workplane().center(0, -bottom_thickness).workplane().box(length-wall_width, result = (
width-wall_width, result.workplane()
height-wall_width, .center(0, -bottom_thickness)
True, .workplane()
"cut") .box(length - wall_width, width - wall_width, height - wall_width, True, "cut")
)
result = (result.faces(">Z").workplane(0, True)
.moveTo(0, first_magnet_position).rect(magnet_width,
magnet_height).cutBlind(magnet_thickness))
result = (result.faces(">Z").workplane(0, True)
.moveTo(0, magnet_slot_offset).rect(magnet_width,
magnet_height).cutBlind(magnet_thickness)
.faces(">Z")
.moveTo(0, magnet_slot_offset)
.rect(magnet_width, magnet_height).extrude(2))
result = (result.faces(">Z").workplane(0, True)
.moveTo(0, second_magnet_position).rect(magnet_width,
magnet_height).cutBlind(magnet_thickness))
result = (result.faces(">Z").workplane(0, True)
.moveTo(0, second_magnet_position+second_slot_offset).rect(magnet_width,
magnet_height).cutBlind(magnet_thickness)
.faces(">Z")
.moveTo(0, second_magnet_position+second_slot_offset)
.rect(magnet_width, magnet_height).extrude(2))
result = (
result.faces(">Z")
.workplane(0, True)
.moveTo(0, first_magnet_position)
.rect(magnet_width, magnet_height)
.cutBlind(magnet_thickness)
)
result = (
result.faces(">Z")
.workplane(0, True)
.moveTo(0, magnet_slot_offset)
.rect(magnet_width, magnet_height)
.cutBlind(magnet_thickness)
.faces(">Z")
.moveTo(0, magnet_slot_offset)
.rect(magnet_width, magnet_height)
.extrude(2)
)
result = (
result.faces(">Z")
.workplane(0, True)
.moveTo(0, second_magnet_position)
.rect(magnet_width, magnet_height)
.cutBlind(magnet_thickness)
)
result = (
result.faces(">Z")
.workplane(0, True)
.moveTo(0, second_magnet_position + second_slot_offset)
.rect(magnet_width, magnet_height)
.cutBlind(magnet_thickness)
.faces(">Z")
.moveTo(0, second_magnet_position + second_slot_offset)
.rect(magnet_width, magnet_height)
.extrude(2)
)
cq.exporters.export(result, "/home/deck/cad_files/tool_holder.step") cq.exporters.export(result, "/home/deck/cad_files/tool_holder.step")

20
utilities.py

@ -6,11 +6,17 @@ import cadquery as cq
import functools as fnc import functools as fnc
import itertools as it import itertools as it
def makeTriangle(self, width, height, x_offset=0, y_offset=0): def makeTriangle(self, width, height, x_offset=0, y_offset=0):
return (self.moveTo(x_offset-(width), y_offset).makePolygon( return (
[ self.moveTo(x_offset - (width), y_offset)
(0,0,0),(width,height,0), (width*2,0,0), .makePolygon(
] [
) (0, 0, 0),
.cutBlind(30) (width, height, 0),
.clean()) (width * 2, 0, 0),
]
)
.cutBlind(30)
.clean()
)

120
watch_stand.py

@ -0,0 +1,120 @@
from cadquery import exporters
from cq_warehouse.extensions import Workplane
from cq_warehouse.fastener import *
from cq_warehouse.thread import *
from cqmore.curve import archimedeanSpiral, circle
from cqmore.polygon import regularPolygon, star
from cqmore.polyhedron import polarZonohedra, Polyhedron, superellipsoid
from svg_path import addSvgPath
from svgpathtools import svg2paths
import cadquery as cq
import cqmore
base_diameter = 100
base_radius = base_diameter / 2
stand_diameter = 38
stand_radius = stand_diameter / 1.5
clock_diameter = 35
clock_radius = clock_diameter / 2
winding_knob_dist = clock_radius
band_width = 21
band_diameter = 55
band_radius = band_diameter / 2
first_circle_height = 175 # how tall the horizontal circle part will be
Workplane = cqmore.extend(Workplane)
Workplane.addSvgPath = addSvgPath
stand_base = Workplane("ZY")
holder_part = Workplane("XY")
simple = False
screw = ButtonHeadScrew(
size="M16-2", fastener_type="iso7380_1", length=20 * MM, simple=simple
)
thread_scaled_screw = screw.scale(0.5)
scaled_screw = screw.scale(1.00)
small_scaled_screw = scaled_screw.scale(0.5)
stand_base = stand_base.cylinder(first_circle_height, stand_radius)
stand_base = (
stand_base.workplane(offset=-70)
.move(0, 21)
.box(20, 25, 20)
.workplane(offset=-69)
.transformed((90, 0, 0), (0, 0, 0))
.threadedHole(screw, 34, simple=simple, fit="Loose")
)
stand_base = stand_base.faces(">X[0]").sphere(base_radius*1.5)
stand_base = stand_base.workplane(offset=base_radius*2).box(
base_diameter * 2, base_radius * 3, base_radius * 3, combine="cut"
)
stand_base = (
stand_base.workplane(offset=base_radius - 5)
.rect(base_radius*1.5, base_radius*1.5, forConstruction=True)
.vertices()
.cylinder(9, 6, combine="cut")
)
holder_angle_offset = 67
clock_paths, clock_attributes = svg2paths("/home/deck/cad_files/svgs/clock.svg")
svgs_to_render = [(clock_paths, (-50, -125, 46), "cut", "XY")]
holder_part = (
holder_part.workplane(offset=2)
.makePolygon(
regularPolygon(
nSides=12,
radius=band_radius,
thetaStart=holder_angle_offset,
thetaEnd=360 + holder_angle_offset,
)
)
.extrude(band_width)
)
holder_part = holder_part.faces(">Z[0]").cylinder(5, 8).union(small_scaled_screw)
if True:
image_objects = []
for svg_paths, translate_offsets, combine, planes in svgs_to_render:
image_objects.append(
Workplane(planes)
.center(0, 75)
.addSvgPath(svg_paths[0])
.extrude(-2.0)
.translate(translate_offsets)
)
for image_object in image_objects:
image_object = image_object.val().scale(0.5)
if combine == "cut":
holder_part = holder_part.cut(image_object, clean=False)
if combine == "union":
holder_part = holder_part.union(image_object, clean=False)
cq.exporters.export(stand_base, "/home/deck/model_files/watch_stand_base.step")
cq.exporters.export(scaled_screw, "/home/deck/model_files/watch_stand_screw.step")
cq.exporters.export(
small_scaled_screw, "/home/deck/model_files/watch_stand_screw_small.step"
)
cq.exporters.export(holder_part, "/home/deck/model_files/watch_stand_holder.step")
try:
show_object(stand_base)
# show_object(cut_polygon)
#show_object(holder_part)
except NameError:
pass

26
webcam_stand.py

@ -0,0 +1,26 @@
from cadquery import exporters
from cq_warehouse.extensions import Workplane
from cq_warehouse.fastener import *
from cq_warehouse.thread import *
from cqmore.curve import archimedeanSpiral, circle
from cqmore.polygon import regularPolygon, star
from cqmore.polyhedron import polarZonohedra, Polyhedron, superellipsoid
from svg_path import addSvgPath
from svgpathtools import svg2paths
import cadquery as cq
import cqmore
Workplane = cqmore.extend(Workplane)
result = (
Workplane()
.makePolygon(regularPolygon(nSides=3, radius=35, thetaStart=0, thetaEnd=360))
.extrude(50)
)
try:
show_object(result)
except NameError:
pass
cq.exporters.export(result, "/home/deck/model_files/webcam_stand.step")

133
xmas_coaster.py

@ -9,85 +9,88 @@ from cad_utilities.shapes import makeTriangle
coaster_radius = 50 coaster_radius = 50
def add_triangle(plane, width, height, offset): def add_triangle(plane, width, height, offset):
return plane.triangle(width, height, y_offset=offset) return plane.triangle(width, height, y_offset=offset)
def addXmas(self, offsets): def addXmas(self, offsets):
xmas_tree_offset = -25 xmas_tree_offset = -25
xmas_tree_height = 8 xmas_tree_height = 8
xmas_tree_width = 6 xmas_tree_width = 6
w_off, h_off, y_off = offsets w_off, h_off, y_off = offsets
return self.triangle(xmas_tree_width+(choice([-1,1])*w_off), return self.triangle(
xmas_tree_height+(choice([-1,1])*h_off), xmas_tree_width + (choice([-1, 1]) * w_off),
y_offset=-(xmas_tree_offset+(y_off))) xmas_tree_height + (choice([-1, 1]) * h_off),
y_offset=-(xmas_tree_offset + (y_off)),
)
def makeXmasTree(self): def makeXmasTree(self):
xmas_tree_offset = -25 xmas_tree_offset = -25
xmas_tree_height = 8 xmas_tree_height = 8
xmas_tree_width = 6 xmas_tree_width = 6
offsets = [(0,0,0)] + [tuple(randint(1, 5) for _ in range(4)) for _ in range(3)] offsets = [(0, 0, 0)] + [tuple(randint(1, 5) for _ in range(4)) for _ in range(3)]
print(offsets) print(offsets)
offsets_added = list(it.accumulate(offsets, lambda t1, t2: list(a+b for a,b in zip(t1, t2)))) offsets_added = list(
it.accumulate(offsets, lambda t1, t2: list(a + b for a, b in zip(t1, t2)))
last_y = offsets_added[-1][2] )
#offsets = [(0,0,0), (3,2,6), (4,11,13), (4,13,16)] last_y = offsets_added[-1][2]
tree = fnc.reduce(addXmas, offsets_added, self.center(0,0)) # offsets = [(0,0,0), (3,2,6), (4,11,13), (4,13,16)]
return (tree tree = fnc.reduce(addXmas, offsets_added, self.center(0, 0))
.moveTo(0, -(xmas_tree_offset+last_y))
.rect(2,5) return tree.moveTo(0, -(xmas_tree_offset + last_y)).rect(2, 5).cutThruAll()
.cutThruAll())
Workplane.triangle = makeTriangle Workplane.triangle = makeTriangle
Workplane.xmasTree = makeXmasTree Workplane.xmasTree = makeXmasTree
polygon = (Workplane() polygon = (
.makePolygon( Workplane()
regularPolygon( .makePolygon(
nSides = 16, regularPolygon(nSides=16, radius=coaster_radius, thetaStart=0, thetaEnd=360)
radius = coaster_radius, )
thetaStart = 0, .extrude(7, clean=True, combine=True, taper=15)
thetaEnd = 360 .xmasTree()
) )
)
.extrude(7, clean=True, combine=True, taper=15)
.xmasTree()
)
result = (polygon.workplane()
.text("Wes",
10, 40,
clean=True,
combine="cut",
fontPath="/home/wes/fonts/TiltNeon-Regular-VariableFont_XROT,YROT.ttf")
)
result = (result.faces("<Z").workplane()
.rect(50, 50, forConstruction=True)
.vertices()
.circle(5)
.extrude(-2, combine="cut"))
result = (result.faces(">Z").workplane()
.makePolygon(
regularPolygon(
nSides = 10,
radius = coaster_radius-5,
thetaStart = 0,
thetaEnd = 360
),
forConstruction=True
)
.vertices()
.circle(2)
.extrude(5))
cq.exporters.export(result, "/home/deck/cad_files/coaster.step") result = polygon.workplane().text(
"Wes",
10,
40,
clean=True,
combine="cut",
fontPath="/home/wes/fonts/TiltNeon-Regular-VariableFont_XROT,YROT.ttf",
)
result = (
result.faces("<Z")
.workplane()
.rect(50, 50, forConstruction=True)
.vertices()
.circle(5)
.extrude(-2, combine="cut")
)
result = (
result.faces(">Z")
.workplane()
.makePolygon(
regularPolygon(
nSides=10, radius=coaster_radius - 5, thetaStart=0, thetaEnd=360
),
forConstruction=True,
)
.vertices()
.circle(2)
.extrude(5)
)
cq.exporters.export(result, "/home/deck/cad_files/coaster.step")

Loading…
Cancel
Save