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,
|
||||
"assemblies": [
|
||||
{
|
||||
"name": "mains_in_assembly",
|
||||
"count": 1,
|
||||
"assemblies": [
|
||||
{
|
||||
"name": "feet_assembly",
|
||||
"count": 1,
|
||||
"assemblies": [
|
||||
{
|
||||
"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
|
||||
[
|
||||
{
|
||||
"name": "base_assembly",
|
||||
"count": 1,
|
||||
"assemblies": {},
|
||||
"vitamins": {
|
||||
"insert(F1BM3): Heatfit insert M3": 2
|
||||
},
|
||||
"printed": {
|
||||
"socket_box.stl": 1
|
||||
},
|
||||
"routed": {}
|
||||
},
|
||||
"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.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):
|
||||
assemblies = {}
|
||||
for ass in self.assemblies:
|
||||
assemblies[ass] = self.assemblies[ass].count
|
||||
return {
|
||||
"name" : self.name,
|
||||
"count" : self.count,
|
||||
"assemblies" : assemblies,
|
||||
"vitamins" : self.vitamins,
|
||||
"printed" : self.printed,
|
||||
|
@ -167,6 +159,7 @@ class BOM:
|
|||
|
||||
def parse_bom(file = "openscad.log", name = None):
|
||||
main = BOM(name)
|
||||
main.ordered_assemblies = []
|
||||
stack = []
|
||||
|
||||
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
|
||||
stack.append(ass)
|
||||
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:
|
||||
if s[0] == '}':
|
||||
if s[1:] != stack[-1]:
|
||||
|
@ -227,14 +223,15 @@ def boms(target = None, assembly = None):
|
|||
if assembly == "main_assembly":
|
||||
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:
|
||||
bom = main.assemblies[ass]
|
||||
print(bom.make_name(ass) + ":", file=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:
|
||||
json.dump(main.assemblies[assembly].data(main), outfile, indent = 4)
|
||||
json.dump(data, outfile, indent = 4)
|
||||
|
||||
print("done")
|
||||
|
||||
|
|
|
@ -35,45 +35,43 @@ import blurb
|
|||
import bom
|
||||
import shutil
|
||||
from colorama import Fore
|
||||
import copy
|
||||
|
||||
def is_assembly(s):
|
||||
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):
|
||||
global flat_bom
|
||||
#
|
||||
# Make a list of all the parts in the BOM
|
||||
#
|
||||
bom = {}
|
||||
bom_file = bom_dir + "/bom.json"
|
||||
with open(bom_file) as json_file:
|
||||
bom = json.load(json_file)
|
||||
flat_bom = []
|
||||
add_assembly(flat_bom, bom, bounds_map)
|
||||
flat_bom = json.load(json_file)
|
||||
#
|
||||
# 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]
|
||||
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
||||
flat_bom = flat_bom[:-1]
|
||||
|
@ -278,49 +276,49 @@ def views(target, do_assemblies = None):
|
|||
printed = ass["printed"]
|
||||
if printed:
|
||||
print('### 3D Printed parts', file = doc_file)
|
||||
i = 0
|
||||
for p in printed:
|
||||
keys = sorted(list(printed.keys()))
|
||||
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 = '')
|
||||
if (i % 3) == 2 or i == len(printed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||
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('\n', file = doc_file)
|
||||
i += 1
|
||||
print('\n', file = doc_file)
|
||||
|
||||
routed = ass["routed"]
|
||||
if routed:
|
||||
print("### CNC Routed parts", file = doc_file)
|
||||
i = 0
|
||||
for r in routed:
|
||||
keys = sorted(list(routed.keys()))
|
||||
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 = '')
|
||||
if (i % 3) == 2 or i == len(routed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||
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('\n', file = doc_file)
|
||||
i += 1
|
||||
print('\n', file = doc_file)
|
||||
|
||||
sub_assemblies = ass["assemblies"]
|
||||
if sub_assemblies:
|
||||
print("### Sub-assemblies", file = doc_file)
|
||||
i = 0
|
||||
for a in sub_assemblies:
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', a["count"], a["name"]), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(sub_assemblies) - 1:
|
||||
keys = sorted(list(sub_assemblies.keys()))
|
||||
for i in range(len(keys)):
|
||||
a = keys[i]
|
||||
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
|
||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||
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('\n', file = doc_file)
|
||||
i += 1
|
||||
print('\n', file = doc_file)
|
||||
|
||||
small = not ass["big"]
|
||||
|
|
Loading…
Reference in New Issue