Printed parts, dxfs and subassemblies now listed alphabetically.
JSON BOM now simplified and in required order.
This commit is contained in:
parent
8d49f2b564
commit
774bdbe2cd
|
@ -1,64 +1,69 @@
|
||||||
{
|
[
|
||||||
"name": "main_assembly",
|
{
|
||||||
"count": 1,
|
"name": "base_assembly",
|
||||||
"assemblies": [
|
"count": 1,
|
||||||
{
|
"assemblies": {},
|
||||||
"name": "mains_in_assembly",
|
"vitamins": {
|
||||||
"count": 1,
|
"insert(F1BM3): Heatfit insert M3": 2
|
||||||
"assemblies": [
|
},
|
||||||
{
|
"printed": {
|
||||||
"name": "feet_assembly",
|
"socket_box.stl": 1
|
||||||
"count": 1,
|
},
|
||||||
"assemblies": [
|
"routed": {}
|
||||||
{
|
|
||||||
"name": "base_assembly",
|
|
||||||
"count": 1,
|
|
||||||
"assemblies": [],
|
|
||||||
"vitamins": {
|
|
||||||
"insert(F1BM3): Heatfit insert M3": 2
|
|
||||||
},
|
|
||||||
"printed": {
|
|
||||||
"socket_box.stl": 1
|
|
||||||
},
|
|
||||||
"routed": {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vitamins": {
|
|
||||||
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 8,
|
|
||||||
"screw(M3_dome_screw, 10): Screw M3 dome x 10mm": 4,
|
|
||||||
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 4
|
|
||||||
},
|
|
||||||
"printed": {
|
|
||||||
"foot.stl": 4
|
|
||||||
},
|
|
||||||
"routed": {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vitamins": {
|
|
||||||
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
|
|
||||||
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
|
|
||||||
": Wire brown 30/0.25mm strands, length 150mm - not shown": 2,
|
|
||||||
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 3,
|
|
||||||
"iec(IEC_inlet_atx): IEC inlet for ATX": 1,
|
|
||||||
"screw(M3_cs_cap_screw, 12): Screw M3 cs cap x 12mm": 2,
|
|
||||||
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 2,
|
|
||||||
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 2
|
|
||||||
},
|
|
||||||
"printed": {},
|
|
||||||
"routed": {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vitamins": {
|
|
||||||
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
|
|
||||||
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
|
|
||||||
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 5,
|
|
||||||
": Ferrule for 1.5mm^2 wire - not shown": 3,
|
|
||||||
"mains_socket(Contactum): Mains socket 13A": 1,
|
|
||||||
"screw(M3_cs_cap_screw, 20): Screw M3 cs cap x 20mm": 2,
|
|
||||||
"jack_4mm_shielded(\"blue\", 3, \"royalblue\"): 4mm shielded jack socket blue": 2,
|
|
||||||
"jack_4mm_shielded(\"brown\", 3, \"sienna\"): 4mm shielded jack socket brown": 1,
|
|
||||||
"jack_4mm_shielded(\"green\", 3): 4mm shielded jack socket green": 2
|
|
||||||
},
|
},
|
||||||
"printed": {},
|
{
|
||||||
"routed": {}
|
"name": "feet_assembly",
|
||||||
}
|
"count": 1,
|
||||||
|
"assemblies": {
|
||||||
|
"base_assembly": 1
|
||||||
|
},
|
||||||
|
"vitamins": {
|
||||||
|
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 8,
|
||||||
|
"screw(M3_dome_screw, 10): Screw M3 dome x 10mm": 4,
|
||||||
|
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 4
|
||||||
|
},
|
||||||
|
"printed": {
|
||||||
|
"foot.stl": 4
|
||||||
|
},
|
||||||
|
"routed": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mains_in_assembly",
|
||||||
|
"count": 1,
|
||||||
|
"assemblies": {
|
||||||
|
"feet_assembly": 1
|
||||||
|
},
|
||||||
|
"vitamins": {
|
||||||
|
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
|
||||||
|
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
|
||||||
|
": Wire brown 30/0.25mm strands, length 150mm - not shown": 2,
|
||||||
|
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 3,
|
||||||
|
"iec(IEC_inlet_atx): IEC inlet for ATX": 1,
|
||||||
|
"screw(M3_cs_cap_screw, 12): Screw M3 cs cap x 12mm": 2,
|
||||||
|
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 2,
|
||||||
|
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 2
|
||||||
|
},
|
||||||
|
"printed": {},
|
||||||
|
"routed": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "main_assembly",
|
||||||
|
"count": 1,
|
||||||
|
"assemblies": {
|
||||||
|
"mains_in_assembly": 1
|
||||||
|
},
|
||||||
|
"vitamins": {
|
||||||
|
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
|
||||||
|
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
|
||||||
|
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 5,
|
||||||
|
": Ferrule for 1.5mm^2 wire - not shown": 3,
|
||||||
|
"mains_socket(Contactum): Mains socket 13A": 1,
|
||||||
|
"screw(M3_cs_cap_screw, 20): Screw M3 cs cap x 20mm": 2,
|
||||||
|
"jack_4mm_shielded(\"blue\", 3, \"royalblue\"): 4mm shielded jack socket blue": 2,
|
||||||
|
"jack_4mm_shielded(\"brown\", 3, \"sienna\"): 4mm shielded jack socket brown": 1,
|
||||||
|
"jack_4mm_shielded(\"green\", 3): 4mm shielded jack socket green": 2
|
||||||
|
},
|
||||||
|
"printed": {},
|
||||||
|
"routed": {}
|
||||||
|
}
|
||||||
|
]
|
|
@ -54,21 +54,13 @@ class BOM:
|
||||||
self.routed = {}
|
self.routed = {}
|
||||||
self.assemblies = {}
|
self.assemblies = {}
|
||||||
|
|
||||||
def data(self, main, count = 1):
|
|
||||||
return {
|
|
||||||
"name" : self.name,
|
|
||||||
"count" : count,
|
|
||||||
"assemblies" : [main.assemblies[ass].data(main, self.assemblies[ass].count) for ass in self.assemblies],
|
|
||||||
"vitamins" : self.vitamins,
|
|
||||||
"printed" : self.printed,
|
|
||||||
"routed" : self.routed
|
|
||||||
}
|
|
||||||
|
|
||||||
def flat_data(self):
|
def flat_data(self):
|
||||||
assemblies = {}
|
assemblies = {}
|
||||||
for ass in self.assemblies:
|
for ass in self.assemblies:
|
||||||
assemblies[ass] = self.assemblies[ass].count
|
assemblies[ass] = self.assemblies[ass].count
|
||||||
return {
|
return {
|
||||||
|
"name" : self.name,
|
||||||
|
"count" : self.count,
|
||||||
"assemblies" : assemblies,
|
"assemblies" : assemblies,
|
||||||
"vitamins" : self.vitamins,
|
"vitamins" : self.vitamins,
|
||||||
"printed" : self.printed,
|
"printed" : self.printed,
|
||||||
|
@ -167,6 +159,7 @@ class BOM:
|
||||||
|
|
||||||
def parse_bom(file = "openscad.log", name = None):
|
def parse_bom(file = "openscad.log", name = None):
|
||||||
main = BOM(name)
|
main = BOM(name)
|
||||||
|
main.ordered_assemblies = []
|
||||||
stack = []
|
stack = []
|
||||||
|
|
||||||
for line in open(file):
|
for line in open(file):
|
||||||
|
@ -179,6 +172,9 @@ def parse_bom(file = "openscad.log", name = None):
|
||||||
main.assemblies[stack[-1]].add_assembly(ass) #add to nested BOM
|
main.assemblies[stack[-1]].add_assembly(ass) #add to nested BOM
|
||||||
stack.append(ass)
|
stack.append(ass)
|
||||||
main.add_assembly(ass) #add to flat BOM
|
main.add_assembly(ass) #add to flat BOM
|
||||||
|
if ass in main.ordered_assemblies:
|
||||||
|
main.ordered_assemblies.remove(ass)
|
||||||
|
main.ordered_assemblies.insert(0, ass)
|
||||||
else:
|
else:
|
||||||
if s[0] == '}':
|
if s[0] == '}':
|
||||||
if s[1:] != stack[-1]:
|
if s[1:] != stack[-1]:
|
||||||
|
@ -227,14 +223,15 @@ def boms(target = None, assembly = None):
|
||||||
if assembly == "main_assembly":
|
if assembly == "main_assembly":
|
||||||
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
|
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
|
||||||
|
|
||||||
for ass in sorted(main.assemblies):
|
for ass in main.assemblies:
|
||||||
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
|
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
|
||||||
bom = main.assemblies[ass]
|
bom = main.assemblies[ass]
|
||||||
print(bom.make_name(ass) + ":", file=f)
|
print(bom.make_name(ass) + ":", file=f)
|
||||||
bom.print_bom(False, f)
|
bom.print_bom(False, f)
|
||||||
|
|
||||||
|
data = [main.assemblies[ass].flat_data() for ass in main.ordered_assemblies]
|
||||||
with open(bom_dir + "/bom.json", 'w') as outfile:
|
with open(bom_dir + "/bom.json", 'w') as outfile:
|
||||||
json.dump(main.assemblies[assembly].data(main), outfile, indent = 4)
|
json.dump(data, outfile, indent = 4)
|
||||||
|
|
||||||
print("done")
|
print("done")
|
||||||
|
|
||||||
|
|
|
@ -35,45 +35,43 @@ import blurb
|
||||||
import bom
|
import bom
|
||||||
import shutil
|
import shutil
|
||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
import copy
|
|
||||||
|
|
||||||
def is_assembly(s):
|
def is_assembly(s):
|
||||||
return s[-9:] == '_assembly' or s[-11:] == '_assemblies'
|
return s[-9:] == '_assembly' or s[-11:] == '_assemblies'
|
||||||
|
|
||||||
def add_assembly(flat_bom, bom, bounds_map):
|
|
||||||
for b in flat_bom:
|
|
||||||
if b["name"] == bom["name"]:
|
|
||||||
b["count"] += bom["count"]
|
|
||||||
return b
|
|
||||||
big = False
|
|
||||||
for ass in bom["assemblies"]:
|
|
||||||
b = add_assembly(flat_bom, ass, bounds_map)
|
|
||||||
if b["big"]:
|
|
||||||
big = True
|
|
||||||
if not big:
|
|
||||||
for stl in bom["printed"]:
|
|
||||||
bounds = bounds_map[stl]
|
|
||||||
width = bounds[1][0] - bounds[0][0]
|
|
||||||
depth = bounds[1][1] - bounds[0][1]
|
|
||||||
if max(width, depth) > 80:
|
|
||||||
big = True
|
|
||||||
break
|
|
||||||
|
|
||||||
bom["big"] = big or bom["routed"]
|
|
||||||
flat_bom.append(copy.deepcopy(bom))
|
|
||||||
return bom
|
|
||||||
|
|
||||||
def bom_to_assemblies(bom_dir, bounds_map):
|
def bom_to_assemblies(bom_dir, bounds_map):
|
||||||
global flat_bom
|
global flat_bom
|
||||||
#
|
#
|
||||||
# Make a list of all the parts in the BOM
|
# Make a list of all the parts in the BOM
|
||||||
#
|
#
|
||||||
bom = {}
|
|
||||||
bom_file = bom_dir + "/bom.json"
|
bom_file = bom_dir + "/bom.json"
|
||||||
with open(bom_file) as json_file:
|
with open(bom_file) as json_file:
|
||||||
bom = json.load(json_file)
|
flat_bom = json.load(json_file)
|
||||||
flat_bom = []
|
#
|
||||||
add_assembly(flat_bom, bom, bounds_map)
|
# Decide if we need big or small assembly pictures
|
||||||
|
#
|
||||||
|
for bom in flat_bom:
|
||||||
|
big = False
|
||||||
|
for ass in bom["assemblies"]:
|
||||||
|
for b in flat_bom:
|
||||||
|
if b["name"] == ass:
|
||||||
|
if not "big" in b:
|
||||||
|
print(ass, bom["name"])
|
||||||
|
if b["big"]:
|
||||||
|
big = True
|
||||||
|
break
|
||||||
|
if not big:
|
||||||
|
for stl in bom["printed"]:
|
||||||
|
bounds = bounds_map[stl]
|
||||||
|
width = bounds[1][0] - bounds[0][0]
|
||||||
|
depth = bounds[1][1] - bounds[0][1]
|
||||||
|
if max(width, depth) > 80:
|
||||||
|
big = True
|
||||||
|
break
|
||||||
|
bom["big"] = big or bom["routed"]
|
||||||
|
#
|
||||||
|
# Remove the main assembly if it is a shell
|
||||||
|
#
|
||||||
ass = flat_bom[-1]
|
ass = flat_bom[-1]
|
||||||
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
||||||
flat_bom = flat_bom[:-1]
|
flat_bom = flat_bom[:-1]
|
||||||
|
@ -278,49 +276,49 @@ def views(target, do_assemblies = None):
|
||||||
printed = ass["printed"]
|
printed = ass["printed"]
|
||||||
if printed:
|
if printed:
|
||||||
print('### 3D Printed parts', file = doc_file)
|
print('### 3D Printed parts', file = doc_file)
|
||||||
i = 0
|
keys = sorted(list(printed.keys()))
|
||||||
for p in printed:
|
for i in range(len(keys)):
|
||||||
|
p = keys[i]
|
||||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p], p), file = doc_file, end = '')
|
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p], p), file = doc_file, end = '')
|
||||||
if (i % 3) == 2 or i == len(printed) - 1:
|
if (i % 3) == 2 or i == len(printed) - 1:
|
||||||
n = (i % 3) + 1
|
n = (i % 3) + 1
|
||||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||||
for j in range(n):
|
for j in range(n):
|
||||||
part = list(printed.keys())[i - n + j + 1]
|
part = keys[i - n + j + 1]
|
||||||
print('| ![%s](stls/%s) %s' % (part, part.replace('.stl','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
print('| ![%s](stls/%s) %s' % (part, part.replace('.stl','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||||
print('\n', file = doc_file)
|
print('\n', file = doc_file)
|
||||||
i += 1
|
|
||||||
print('\n', file = doc_file)
|
print('\n', file = doc_file)
|
||||||
|
|
||||||
routed = ass["routed"]
|
routed = ass["routed"]
|
||||||
if routed:
|
if routed:
|
||||||
print("### CNC Routed parts", file = doc_file)
|
print("### CNC Routed parts", file = doc_file)
|
||||||
i = 0
|
keys = sorted(list(routed.keys()))
|
||||||
for r in routed:
|
for i in range(len(keys)):
|
||||||
|
r = keys[i]
|
||||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r], r), file = doc_file, end = '')
|
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r], r), file = doc_file, end = '')
|
||||||
if (i % 3) == 2 or i == len(routed) - 1:
|
if (i % 3) == 2 or i == len(routed) - 1:
|
||||||
n = (i % 3) + 1
|
n = (i % 3) + 1
|
||||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||||
for j in range(n):
|
for j in range(n):
|
||||||
part = list(routed.keys())[i - n + j + 1]
|
part = keys[i - n + j + 1]
|
||||||
print('| ![%s](dxfs/%s) %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
print('| ![%s](dxfs/%s) %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||||
print('\n', file = doc_file)
|
print('\n', file = doc_file)
|
||||||
i += 1
|
|
||||||
print('\n', file = doc_file)
|
print('\n', file = doc_file)
|
||||||
|
|
||||||
sub_assemblies = ass["assemblies"]
|
sub_assemblies = ass["assemblies"]
|
||||||
if sub_assemblies:
|
if sub_assemblies:
|
||||||
print("### Sub-assemblies", file = doc_file)
|
print("### Sub-assemblies", file = doc_file)
|
||||||
i = 0
|
keys = sorted(list(sub_assemblies.keys()))
|
||||||
for a in sub_assemblies:
|
for i in range(len(keys)):
|
||||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', a["count"], a["name"]), file = doc_file, end = '')
|
a = keys[i]
|
||||||
if (i % 3) == 2 or i == len(sub_assemblies) - 1:
|
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
|
||||||
|
if (i % 3) == 2 or i == len(keys) - 1:
|
||||||
n = (i % 3) + 1
|
n = (i % 3) + 1
|
||||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||||
for j in range(n):
|
for j in range(n):
|
||||||
a = sub_assemblies[i - n + j + 1]["name"].replace('_assembly', '_assembled')
|
a = keys[i - n + j + 1].replace('_assembly', '_assembled')
|
||||||
print('| ![%s](assemblies/%s) %s' % (a, a + '_tn.png', '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
print('| ![%s](assemblies/%s) %s' % (a, a + '_tn.png', '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||||
print('\n', file = doc_file)
|
print('\n', file = doc_file)
|
||||||
i += 1
|
|
||||||
print('\n', file = doc_file)
|
print('\n', file = doc_file)
|
||||||
|
|
||||||
small = not ass["big"]
|
small = not ass["big"]
|
||||||
|
|
Loading…
Reference in New Issue