zellhalter_v2.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import cadquery as cq
  2. from cadquery.occ_impl.exporters import ExportTypes
  3. from ocp_vscode import show, show_object
  4. ###### Parameter #####
  5. cells_per_row = 8
  6. rows = 2
  7. cell_diam = 18.44
  8. cell_length = 65
  9. dist_to_ground = 66.9
  10. space_all = 140
  11. space_single = space_all / (cells_per_row - 1)
  12. space_rows = 33.7
  13. dist_segments = 57.5
  14. strip_width = 10.4
  15. print_height = 15
  16. wall_thick = 1.7
  17. eps = 0.15
  18. hole_diam = 2.4
  19. hole_depth = 10
  20. board_connector_length = dist_to_ground + wall_thick
  21. lip_width = 1.5
  22. lip_thick = 1.5
  23. injection_mould = False
  24. ############
  25. cell_locs = [(x * space_single, y * space_rows) for x in range(0, cells_per_row) for y in range(0, rows)]
  26. strip_locs = [(-cell_diam/4, y * space_rows) for y in range(0, rows)]
  27. connector_locs = [(x * space_single * 2, (y + 0.5) * space_rows) for x in range(0, int(cells_per_row/2)) for y in range(0, rows-1)]
  28. cell_edge = cell_diam/2 - 1.5
  29. board_con_locs_with_rot = [
  30. ((-.5 * space_single, -cell_edge), 0),
  31. ((-.5 * space_single, space_rows + cell_edge), 180),
  32. ((1.5 * space_single, space_rows - cell_edge), 0),
  33. ((5.5 * space_single, cell_edge), 180),
  34. ((5.5 * space_single, space_rows - cell_edge), 0),
  35. ]
  36. # Zellkreise
  37. cell_base = (
  38. cq.Workplane()
  39. .pushPoints(cell_locs)
  40. .eachpoint(
  41. lambda loc: (
  42. cq.Workplane()
  43. .circle(cell_diam/2 + eps + wall_thick)
  44. .extrude(print_height)
  45. .val()
  46. .located(loc)
  47. )
  48. )
  49. )
  50. # Ausschnitt für die Zellen
  51. cell_cutout = (
  52. cq.Workplane()
  53. .pushPoints(cell_locs)
  54. .eachpoint(
  55. lambda loc: (
  56. cq.Workplane()
  57. .circle(cell_diam/2 + eps)
  58. .extrude(print_height-wall_thick)
  59. .val()
  60. .located(loc)
  61. )
  62. )
  63. )
  64. # Ausschnitt für die Lötfahne
  65. strips_cut = (
  66. cq.Workplane()
  67. .pushPoints(strip_locs)
  68. .eachpoint(
  69. lambda loc: (
  70. cq.Workplane().workplane(offset=print_height-2*wall_thick)
  71. .rect(space_all + cell_diam/2+wall_thick, strip_width, centered=(False, True))
  72. .extrude(wall_thick*2)
  73. # Dreieckiger Ausschnitt für besseres bridging
  74. .faces("<Z")
  75. .workplane()
  76. .rect(space_all + cell_diam/2+wall_thick, strip_width, centered=(False, True))
  77. .workplane(offset=wall_thick*2)
  78. .rect(space_all + cell_diam/2+wall_thick, eps, centered=(False, True))
  79. .loft()
  80. .val()
  81. .located(loc)
  82. )
  83. )
  84. )
  85. strips_wall = (
  86. cq.Workplane()
  87. .pushPoints(strip_locs)
  88. .eachpoint(
  89. lambda loc: (
  90. cq.Workplane()
  91. .rect(space_all+ 2*wall_thick, strip_width + 2*wall_thick, centered=(False, True))
  92. .extrude(print_height)
  93. .val()
  94. .located(loc)
  95. )
  96. )
  97. )
  98. base_cutout = (
  99. cell_base.union(strips_wall)
  100. .cut(cell_cutout)
  101. .cut(strips_cut)
  102. )#.faces("<Z").chamfer(wall_thick/4)
  103. connectors = (
  104. cq.Workplane()
  105. .pushPoints(connector_locs)
  106. .eachpoint(
  107. lambda loc: (
  108. cq.Workplane().workplane(offset=wall_thick)
  109. .rect(wall_thick, space_rows - cell_diam - wall_thick, centered=(False, True))
  110. .extrude(print_height-wall_thick)
  111. .val()
  112. .located(loc)
  113. )
  114. )
  115. )
  116. base_connected = base_cutout.union(connectors)
  117. connector_width = hole_diam + wall_thick*1.5
  118. board_con = (
  119. cq.Workplane()
  120. .rect(connector_width, connector_width)
  121. .extrude(board_connector_length)
  122. .faces("+Y")
  123. .edges("|Z")
  124. .chamfer(wall_thick)
  125. .faces(">Z")
  126. .workplane()
  127. .circle(hole_diam/2)
  128. .cutBlind(-hole_depth)
  129. )
  130. if not injection_mould:
  131. board_con = (
  132. board_con
  133. .faces("<Z")
  134. .workplane()
  135. .rect(connector_width+lip_width, connector_width)
  136. .extrude(lip_width)
  137. )
  138. board_con_outside = (
  139. cq.Workplane()
  140. .rect(connector_width + 2 * eps, connector_width + 2 * eps)
  141. .extrude(print_height)
  142. )
  143. board_con_hull = (
  144. cq.Workplane()
  145. .rect(connector_width + 2 * (wall_thick + eps), connector_width + 2 * (wall_thick + eps))
  146. .extrude(print_height)
  147. .edges("|Z")
  148. .chamfer(wall_thick)
  149. )
  150. base_connected = base_connected.rotateAboutCenter((1,0,0), 180)
  151. con_placed = []
  152. for location, angle in board_con_locs_with_rot:
  153. # Connector nur für Visualisierung
  154. con = board_con.translate(location)
  155. con = con.rotateAboutCenter((0,0,1), angle)
  156. # Ausschnitt für den Connector
  157. chamfer_face = "-Y" if angle >= 180 else "+Y"
  158. con_outside = board_con_outside.faces(chamfer_face).edges("|Z").chamfer(wall_thick)
  159. con_outside = con_outside.translate(location)
  160. con_placed.append(con)
  161. # Verdickte Hülle für den Connector
  162. hull = board_con_hull.translate(location).cut(cell_base).cut(strips_cut)
  163. base_connected = base_connected.union(hull)
  164. if injection_mould:
  165. base_connected = base_connected.union(con)
  166. else:
  167. base_connected = base_connected.cut(con_outside)
  168. # Begrenzungsbox für den gesamten Zellhalter (sonst schneidet man den nächsten Halter)
  169. boundary_box = (
  170. base_connected.workplane(centerOption="CenterOfBoundBox")
  171. .box(1000, dist_segments, 1000,combine=False)
  172. )
  173. base_connected = base_connected.intersect(boundary_box)
  174. show_object(base_connected)
  175. show_object(con_placed)
  176. with open(r"zellhalter_v2_base.step", "w") as fp:
  177. cq.exporters.exportShape(base_connected, ExportTypes.STEP, fp)
  178. if not injection_mould:
  179. with open(r"zellhalter_v2_connector.step", "w") as fp:
  180. cq.exporters.exportShape(board_con, ExportTypes.STEP, fp)