-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgenerate_pcbs.py
135 lines (113 loc) · 4.29 KB
/
generate_pcbs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
# Reads the PCB "master", that we edit by hand, and generates 3 output PCBs for
# each of the layers of the sandwich style case. This helps to keep everything
# in sync between the layers. You must have Kicad installed on your system as
# that installs the `pcbnew` module that we use. AFAIK you can't install pcbnew
# via pip.
import sys
import os
import pcbnew
this_dir = os.path.dirname(os.path.realpath(__file__))
master_pcb = os.path.join(this_dir, 'pcb', 'ergoslab.kicad_pcb')
base_pcb = os.path.join(this_dir, 'generated_pcb', 'base', 'base.kicad_pcb')
middle_pcb = os.path.join(this_dir, 'generated_pcb', 'middle',
'middle.kicad_pcb')
top_pcb = os.path.join(this_dir, 'generated_pcb', 'top', 'top.kicad_pcb')
ALL_LAYERS_WIDTH = 50000
NOT_TOP_PLATE_WIDTH = 50010
ALL_LAYERS_TEXT_THICKNESS = 150100
def refill_zones(board):
# thanks https://forum.kicad.info/t/filling-zones-copper-pours-inside-the-python-api/19814/3
filler = pcbnew.ZONE_FILLER(board)
zones = board.Zones()
filler.Fill(zones)
def is_logo(module):
return module.GetReference() == 'CHICKEN'
def is_brace(module):
return module.GetReference().startswith('Brace')
def is_brace_not_for_top(module):
return module.GetReference().startswith('BraceNotTop')
def delete_electronics(board):
for module in board.GetModules():
ref = module.GetReference()
is_mounting_hole = ref.startswith('Mount')
if is_mounting_hole or is_logo(module) or is_brace(module):
continue
board.Delete(module)
def delete_tracks(board):
for t in board.GetTracks():
board.Delete(t)
def generate_base_pcb():
board = pcbnew.LoadBoard(master_pcb)
print('Creating base PCB: %s' % base_pcb)
delete_electronics(board)
for module in board.GetModules():
if is_brace(module):
if is_brace_not_for_top(module):
continue
board.Delete(module)
delete_tracks(board)
for d in board.GetDrawings():
if type(d) is pcbnew.TEXTE_PCB:
if d.GetThickness() == ALL_LAYERS_TEXT_THICKNESS:
continue
if d.GetLayerName() == 'Edge.Cuts':
if type(d) is pcbnew.DRAWSEGMENT:
if d.GetWidth() == NOT_TOP_PLATE_WIDTH or d.GetWidth(
) == ALL_LAYERS_WIDTH:
continue
board.Delete(d)
refill_zones(board)
board.Save(base_pcb)
def generate_middle_pcb():
board = pcbnew.LoadBoard(master_pcb)
print('Creating middle PCB: %s' % middle_pcb)
for d in board.GetDrawings():
if type(d) is pcbnew.TEXTE_PCB:
continue
layer_name = d.GetLayerName()
if layer_name == 'F.SilkS' or layer_name == 'B.SilkS':
continue
if layer_name == 'Edge.Cuts':
if type(d) is pcbnew.DRAWSEGMENT:
if d.GetWidth() == NOT_TOP_PLATE_WIDTH or d.GetWidth(
) == ALL_LAYERS_WIDTH:
continue
board.Delete(d)
refill_zones(board)
board.Save(middle_pcb)
def generate_top_pcb():
board = pcbnew.LoadBoard(master_pcb)
edge_cuts_layer_id = board.GetLayerID('Edge.Cuts')
print('Creating top PCB: %s' % top_pcb)
delete_electronics(board)
for module in board.GetModules():
is_brace_for_top = not is_brace_not_for_top(module)
if is_brace(module) and is_brace_for_top:
continue
ref = module.GetReference()
is_mount_for_top = ref.startswith(
'Mount') and not ref.startswith('MountNotTop')
if is_mount_for_top:
continue
board.Delete(module)
delete_tracks(board)
for d in board.GetDrawings():
if type(d) is pcbnew.TEXTE_PCB:
if d.GetThickness() == ALL_LAYERS_TEXT_THICKNESS:
continue
if d.GetLayerName() == 'Edge.Cuts':
if type(d) is pcbnew.DRAWSEGMENT:
if d.GetWidth() == ALL_LAYERS_WIDTH:
continue
if d.GetLayerName() == 'Eco1.User':
is_for_top_plate = d.GetWidth() != NOT_TOP_PLATE_WIDTH
if is_for_top_plate:
d.SetLayer(edge_cuts_layer_id)
continue
board.Delete(d)
refill_zones(board)
board.Save(top_pcb)
generate_base_pcb()
generate_middle_pcb()
generate_top_pcb()