def gen_bom(m): md = '## Bill of Materials\n\n' md += 'Make sure you have all of the following parts before you begin.\n\n' # vitamins if len(m['vitamins']) > 0: m['vitamins'].sort(key=vitamin_call, reverse=False) md += '### Vitamins\n\n' md += 'Qty | Vitamin | Image\n' md += '--- | --- | ---\n' for v in m['vitamins']: md += str(v['qty']) + ' | ' md += '['+v['title']+']() | ' md += '![](../vitamins/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' md += '\n' # printed parts if len(m['printed']) > 0: m['printed'].sort(key=printed_call, reverse=False) md += '### Printed Parts\n\n' md += 'Qty | Part Name | Image\n' md += '--- | --- | ---\n' for v in m['printed']: md += str(v['qty']) + ' | ' md += '['+v['title']+'](../printedparts/stl/'+ openscad.stl_filename(v['title']) +') | ' md += '![](../printedparts/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' md += '\n' md += '\n' return md
def gen_bom(m): md = '## Bill of Materials\n\n' md += 'Make sure you have all of the following parts before you begin.\n\n' # vitamins if len(m['vitamins']) > 0: m['vitamins'].sort(key=vitamin_call, reverse=False) md += '### Vitamins\n\n' md += 'Qty | Vitamin | Image\n' md += '--- | --- | ---\n' for v in m['vitamins']: md += str(v['qty']) + ' | ' md += '['+v['title']+']() | ' md += '![](../vitamins/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' md += '\n' # cut parts if len(m['cut']) > 0: m['cut'].sort(key=cut_call, reverse=False) md += '### Cut Parts\n\n' md += 'Qty | Part Name | Image\n' md += '--- | --- | ---\n' for v in m['cut']: md += str(v['qty']) + ' | ' md += v['title'] + ' | ' md += '![](../cutparts/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' md += '\n' # printed parts if len(m['printed']) > 0: vol = 0 weight = 0 m['printed'].sort(key=printed_call, reverse=False) md += '### Printed Parts\n\n' md += 'Qty | Part Name | Image\n' md += '--- | --- | ---\n' for v in m['printed']: md += str(v['qty']) + ' | ' md += '['+v['title']+'](../printedparts/stl/'+ openscad.stl_filename(v['title']) +') | ' md += '![](../printedparts/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' if 'plasticWeight' in v: weight += v['qty'] * v['plasticWeight'] vol += v['qty'] * v['plasticVolume'] md += '\n\n' md += '**Plastic Required**\n\n' md += str(round(vol,1))+'cm3, '; md += str(round(weight,2))+'KG, '; md += ' approx: '+str(round(weight * 13,2))+' GBP\n\n'; md += '\n' return md
def gen_assembly(m, a): if len(a['steps']) == 0: return "" md = '## '+a['title'] if a['qty'] > 1: md += ' (x'+str(a['qty'])+')' md += '\n\n' # vitamins if len(a['vitamins']) > 0: a['vitamins'].sort(key=vitamin_call, reverse=False) md += '### Vitamins\n\n' md += 'Qty | Vitamin | Image\n' md += '--- | --- | ---\n' for v in a['vitamins']: md += str(v['qty']) + ' | ' md += '['+v['title']+']() | ' md += '![](../vitamins/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' md += '\n' # printed parts if len(a['printed']) > 0: a['printed'].sort(key=printed_call, reverse=False) md += '### Printed Parts\n\n' md += 'Qty | Part Name | Image\n' md += '--- | --- | ---\n' for v in a['printed']: md += str(v['qty']) + ' | ' md += '['+v['title']+'](../printedparts/stl/'+ openscad.stl_filename(v['title']) +') | ' md += '![](../printedparts/images/'+views.view_filename(v['title']+'_view') + ') | ' md += '\n' md += '\n' # sub-assemblies if len(a['assemblies']) > 0: md += '### Sub-Assemblies\n\n' md += 'Qty | Name \n' md += '--- | --- \n' for v in a['assemblies']: md += str(v['qty']) + ' | ' md += v['title'] md += '\n' md += '\n' # assembly steps if len(a['steps']) > 0: md += '### Assembly Steps\n\n' for step in a['steps']: md += str(step['num']) + '. '+step['desc'] + '\n' for view in step['views']: md += '![](../assemblies/'+machine_dir(m['title'])+'/'+views.view_filename(a['title']+'_step'+str(step['num'])+'_'+view['title'])+')\n' md += '\n' md += '\n' return md
def compile_vitamin(v, dom): temp_name = "temp.scad" # # Make the target directories # target_dir = "../vitamins/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) view_dir = "../vitamins/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # Compile print(" "+v['title']) fn = '../' + v['file'] if (os.path.isfile(fn)): print(" Checking csg hash") h = openscad.get_csg_hash(temp_name, v['call'], [fn]); os.remove(temp_name); hashchanged = ('hash' in v and h != v['hash']) or (not 'hash' in v) # update hash in json v['hash'] = h # STL print(" STL Parts") for part in v['children']: if type(part) is DictType and part['type'] == 'part': stlpath = target_dir + '/' + openscad.stl_filename(part['title']) if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") openscad.render_stl(temp_name, stlpath, part['call'], [fn]) else: print(" STL up to date") # Views print(" Views") for view in v['children']: if type(view) is DictType and view['type'] == 'view': print(" "+view['title']) render_view(v['title'], v['call'], view_dir, view, hashchanged, h, [fn], False) png_name = view_dir + '/' + view_filename(v['title'] + '_' + view['title']) view['png_name'] = png_name node = add_vitamin(v, dom) else: print(" Error: scad file not found: "+v['file'])
def compile_vitamin(v, dom): temp_name = "temp.scad" # # Make the target directories # target_dir = "../vitamins/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) view_dir = "../vitamins/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # Compile print(" " + v['title']) fn = '../' + v['file'] if (os.path.isfile(fn)): print(" Checking csg hash") h = openscad.get_csg_hash(temp_name, v['call'], [fn]) os.remove(temp_name) hashchanged = ('hash' in v and h != v['hash']) or (not 'hash' in v) # update hash in json v['hash'] = h # STL print(" STL Parts") for part in v['children']: if type(part) is DictType and part['type'] == 'part': stlpath = target_dir + '/' + openscad.stl_filename( part['title']) if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") openscad.render_stl(temp_name, stlpath, part['call'], [fn]) else: print(" STL up to date") # Views print(" Views") for view in v['children']: if type(view) is DictType and view['type'] == 'view': print(" " + view['title']) render_view(v['title'], v['call'], view_dir, view, hashchanged, h, [fn], False) png_name = view_dir + '/' + view_filename(v['title'] + '_' + view['title']) view['png_name'] = png_name node = add_vitamin(v, dom) else: print(" Error: scad file not found: " + v['file'])
def gen_bom(m): md = '## Bill of Materials\n\n' md += 'Make sure you have all of the following parts before you begin.\n\n' # vitamins if len(m['vitamins']) > 0: m['vitamins'].sort(key=vitamin_call, reverse=False) md += '### Vitamins\n\n' md += 'Qty | Vitamin | Image\n' md += '--- | --- | ---\n' for v in m['vitamins']: md += str(v['qty']) + ' | ' md += '[' + v['title'] + ']() | ' md += '![](../vitamins/images/' + views.view_filename( v['title'] + '_view') + ') | ' md += '\n' md += '\n' # cut parts if len(m['cut']) > 0: m['cut'].sort(key=cut_call, reverse=False) md += '### Cut Parts\n\n' md += 'Qty | Part Name | Image\n' md += '--- | --- | ---\n' for v in m['cut']: md += str(v['qty']) + ' | ' md += v['title'] + ' | ' md += '![](../cutparts/images/' + views.view_filename( v['title'] + '_view') + ') | ' md += '\n' md += '\n' # printed parts if len(m['printed']) > 0: m['printed'].sort(key=printed_call, reverse=False) md += '### Printed Parts\n\n' md += 'Qty | Part Name | Image\n' md += '--- | --- | ---\n' for v in m['printed']: md += str(v['qty']) + ' | ' md += '[' + v[ 'title'] + '](../printedparts/stl/' + openscad.stl_filename( v['title']) + ') | ' md += '![](../printedparts/images/' + views.view_filename( v['title'] + '_view') + ') | ' md += '\n' md += '\n' md += '\n' return md
def compile_vitamin(v): # # Make the target directories # if not os.path.isdir(config.paths['vitaminsstl']): os.makedirs(config.paths['vitaminsstl']) if not os.path.isdir(config.paths['vitaminsimages2']): os.makedirs(config.paths['vitaminsimages2']) # Compile print(" " + v['title']) fn = os.path.join('..', v['file']) if (os.path.isfile(fn)): print(" Checking csg hash") h = openscad.get_csg_hash(config.paths['tempscad'], v['call']) os.remove(config.paths['tempscad']) hashchanged = ('hash' in v and h != v['hash']) or (not 'hash' in v) # update hash in json v['hash'] = h # STL print(" STL Parts") if 'parts' in v: for part in v['parts']: stlpath = os.path.join(config.paths['vitaminsstl'], openscad.stl_filename(part['title'])) if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") openscad.render_stl(config.paths['tempscad'], stlpath, part['call']) else: print(" STL up to date") # Views print(" Views") for view in v['views']: print(" " + view['title']) render_view(v['title'], v['call'], config.paths['vitaminsimages2'], view, hashchanged, h) else: print(" Error: scad file not found: " + v['file'])
def gen_printing_guide(m, target_dir, guide_template): print(m['title']) if len(m['printed']) == 0: return {}; md = '' md += '# '+m['title'] + '\n' md += '# Printing Guide\n\n' vol = 0 weight = 0 qty = 0 m['printed'].sort(key=printed_call, reverse=False) for v in m['printed']: md += '### '+v['title']+'\n\n' md += 'Metric | Value \n' md += '--- | --- \n' md += 'Quantity | ' + str(v['qty']) + '\n' qty += v['qty'] md += 'STL | ' + '['+v['title']+'](../printedparts/stl/'+ openscad.stl_filename(v['title']) +')\n' if 'plasticWeight' in v: w = v['qty'] * v['plasticWeight'] weight += w vol += v['qty'] * v['plasticVolume'] md += 'Plastic (Kg) | ' + str(round(w,2)) + '\n' md += 'Plastic (cm3) | ' + str(round(v['qty'] * v['plasticVolume'],1)) + '\n' md += 'Approx Plastic Cost | '+str(round(w * 15,2))+' GBP\n'; md += '\n' md += '![](../printedparts/images/'+views.view_filename(v['title']+'_view') + ')\n' md += '\n' if 'markdown' in v and len(v['markdown']) > 0: md += '**Notes**\n\n' for note in v['markdown']: if 'markdown' in note: md += ' * ' + note['markdown'] + '\n' md += '\n\n' md += '\n\n' md += '## Summary\n\n' md += '### Statistics\n\n' md += 'Metric | Value \n' md += '--- | --- \n' md += 'Total Parts | ' + str(qty) + '\n' md += 'Total Plastic (Kg) | ' +str(round(weight,2))+'KG\n' md += 'Total Plastic (cm3) | ' +str(round(vol,1))+'cm3\n' md += 'Approx Plastic Cost | '+str(round(weight * 15,2))+' GBP\n' md += '\n\n' print(" Saving markdown") mdfilename = md_filename(m['title'] +'PrintingGuide') mdpath = target_dir + '/' +mdfilename with open(mdpath,'w') as f: f.write(md) print(" Generating htm") htmfilename = htm_filename(m['title'] +'PrintingGuide') htmpath = target_dir + '/' + htmfilename with open(htmpath, 'w') as f: for line in open(guide_template, "r").readlines(): line = line.replace("{{mdfilename}}", mdfilename) f.write(line) return {'title':m['title'] + ' Printing Guide', 'mdfilename':mdfilename, 'htmfilename':htmfilename}
def printed(): print("Printed Parts") print("-------------") temp_name = "temp.scad" # # Make the target directories # target_dir = "../printedparts/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) # store a list of valid STLs to aid cleanup stlList = [] view_dir = "../printedparts/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # load hardware.json jf = open("hardware.json", "r") jso = json.load(jf) jf.close() # for each machine for m in jso: if type(m) is DictType and m['type'] == 'machine': print(m['title']) pl = m['printed'] for p in pl: print(" " + p['title']) fn = '../' + p['file'] if (os.path.isfile(fn)): stlpath = os.path.join(target_dir, openscad.stl_filename(p['title'])) md5path = os.path.join( target_dir, openscad.stl_filename(p['title']) + '.md5') print(" Checking csg hash") # Get csg hash h = openscad.get_csg_hash(temp_name, p['call']) os.remove(temp_name) # Get old csg hash oldh = "" if os.path.isfile(md5path): with open(md5path, 'r') as f: oldh = f.read() hashchanged = h != oldh # update hash in json p['hash'] = h # save new hash with open(md5path, 'w') as f: f.write(h) # STL print(" STL") if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") info = openscad.render_stl(temp_name, stlpath, p['call']) jsontools.json_merge_missing_keys(p, info) # Slice for weight and volume print(" Slice") if hashchanged or ('plasticWeight' not in p): # Slice part and track volume of plastic required # Estimate KG of plastic from density range: 1.23-1.25 g/cm3 plasticInfo = slic3r.calc_plastic_required(stlpath) jsontools.json_merge_missing_keys(p, plasticInfo) else: print(" GCode up to date") print(" views") # Views for view in p['views']: print(" " + view['title']) render_view(p['title'], p['call'], view_dir, view, hashchanged, h) # Add to stlList stlList.append(stlpath) stlList.append(md5path) else: print(" Error: scad file not found: " + p['file']) # Save changes to json with open('hardware.json', 'w') as f: f.write( json.dumps(jso, sort_keys=False, indent=4, separators=(',', ': '))) # clean-up orphaned stls and checksums print "Checking for outdated STLs..." for f in os.listdir(target_dir): fp = os.path.join(target_dir, f) try: if os.path.isfile(fp) and (fp not in stlList): print "Removing: " + fp os.remove(fp) except Exception, e: print e
def vitamins(): print("Vitamins") print("--------") temp_name = "temp.scad" # # Make the target directories # target_dir = "../vitamins/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) view_dir = "../vitamins/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # load hardware.json jf = open("hardware.json", "r") jso = json.load(jf) jf.close() # for each machine for m in jso: if type(m) is DictType and m['type'] == 'machine': print(m['title']) vl = m['vitamins'] for v in vl: print(" " + v['title']) fn = '../' + v['file'] if (os.path.isfile(fn)): print(" Checking csg hash") h = openscad.get_csg_hash(temp_name, v['call']) os.remove(temp_name) hashchanged = ('hash' in v and h != v['hash']) or (not 'hash' in v) # update hash in json v['hash'] = h # STL print(" STL Parts") if 'parts' in v: for part in v['parts']: stlpath = target_dir + '/' + openscad.stl_filename( part['title']) if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") openscad.render_stl(temp_name, stlpath, part['call']) else: print(" STL up to date") # Views print(" Views") for view in v['views']: print(" " + view['title']) render_view(v['title'], v['call'], view_dir, view, hashchanged, h) else: print(" Error: scad file not found: " + v['file']) # Save changes to json with open('hardware.json', 'w') as f: f.write( json.dumps(jso, sort_keys=False, indent=4, separators=(',', ': '))) return 0
def printed(): print("Printed Parts") print("-------------") temp_name = "temp.scad" # # Make the target directories # target_dir = "../printedparts/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) view_dir = "../printedparts/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # load hardware.json jf = open("hardware.json","r") jso = json.load(jf) jf.close() # for each machine for m in jso: if type(m) is DictType and m['type'] == 'machine': print(m['title']) pl = m['printed'] for p in pl: print(" "+p['title']) fn = '../' + p['file'] if (os.path.isfile(fn)): stlpath = target_dir + '/' + openscad.stl_filename(p['title']) md5path = target_dir + '/' + openscad.stl_filename(p['title']) + '.md5' print(" Checking csg hash") # Get csg hash h = openscad.get_csg_hash(temp_name, p['call']); os.remove(temp_name); # Get old csg hash oldh = "" if os.path.isfile(md5path): with open(md5path,'r') as f: oldh = f.read() hashchanged = h != oldh # update hash in json p['hash'] = h # save new hash with open(md5path,'w') as f: f.write(h) # STL print(" STL") if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") info = openscad.render_stl(temp_name, stlpath, p['call']) jsontools.json_merge_missing_keys(p, info) else: print(" STL up to date") print(" views") # Views for view in p['views']: print(" "+view['title']) render_view(p['title'], p['call'], view_dir, view, hashchanged, h) else: print(" Error: scad file not found: "+p['file']) # Save changes to json with open('hardware.json', 'w') as f: f.write(json.dumps(jso, sort_keys=False, indent=4, separators=(',', ': '))) return 0
def printed(): print("Printed Parts") print("-------------") temp_name = "temp.scad" # # Make the target directories # target_dir = "../printedparts/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) view_dir = "../printedparts/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # load hardware.json jf = open("hardware.json", "r") jso = json.load(jf) jf.close() # for each machine for m in jso: if type(m) is DictType and m['type'] == 'machine': print(m['title']) pl = m['printed'] for p in pl: print(" " + p['title']) fn = '../' + p['file'] if (os.path.isfile(fn)): stlpath = target_dir + '/' + openscad.stl_filename( p['title']) md5path = target_dir + '/' + openscad.stl_filename( p['title']) + '.md5' print(" Checking csg hash") # Get csg hash h = openscad.get_csg_hash(temp_name, p['call']) os.remove(temp_name) # Get old csg hash oldh = "" if os.path.isfile(md5path): with open(md5path, 'r') as f: oldh = f.read() hashchanged = h != oldh # update hash in json p['hash'] = h # save new hash with open(md5path, 'w') as f: f.write(h) # STL print(" STL") if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") info = openscad.render_stl(temp_name, stlpath, p['call']) jsontools.json_merge_missing_keys(p, info) else: print(" STL up to date") print(" views") # Views for view in p['views']: print(" " + view['title']) render_view(p['title'], p['call'], view_dir, view, hashchanged, h) else: print(" Error: scad file not found: " + p['file']) # Save changes to json with open('hardware.json', 'w') as f: f.write( json.dumps(jso, sort_keys=False, indent=4, separators=(',', ': '))) return 0
def vitamins(): print("Vitamins") print("--------") temp_name = "temp.scad" # # Make the target directories # target_dir = "../vitamins/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) view_dir = "../vitamins/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # load hardware.json jf = open("hardware.json","r") jso = json.load(jf) jf.close() # for each machine for m in jso: if type(m) is DictType and m['type'] == 'machine': print(m['title']) vl = m['vitamins'] for v in vl: print(" "+v['title']) fn = '../' + v['file'] if (os.path.isfile(fn)): print(" Checking csg hash") h = openscad.get_csg_hash(temp_name, v['call']); os.remove(temp_name); hashchanged = ('hash' in v and h != v['hash']) or (not 'hash' in v) # update hash in json v['hash'] = h # STL print(" STL Parts") if 'parts' in v: for part in v['parts']: stlpath = target_dir + '/' + openscad.stl_filename(part['title']) if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") openscad.render_stl(temp_name, stlpath, part['call']) else: print(" STL up to date") # Views print(" Views") for view in v['views']: print(" "+view['title']) render_view(v['title'], v['call'], view_dir, view, hashchanged, h) else: print(" Error: scad file not found: "+v['file']) # Save changes to json with open('hardware.json', 'w') as f: f.write(json.dumps(jso, sort_keys=False, indent=4, separators=(',', ': '))) return 0
def printed(): print("Printed Parts") print("-------------") temp_name = "temp.scad" # # Make the target directories # target_dir = "../printedparts/stl" if not os.path.isdir(target_dir): os.makedirs(target_dir) # store a list of valid STLs to aid cleanup stlList = [] view_dir = "../printedparts/images" if not os.path.isdir(view_dir): os.makedirs(view_dir) # load hardware.json jf = open("hardware.json","r") jso = json.load(jf) jf.close() # for each machine for m in jso: if type(m) is DictType and m['type'] == 'machine': print(m['title']) pl = m['printed'] for p in pl: print(" "+p['title']) fn = '../' + p['file'] if (os.path.isfile(fn)): stlpath = os.path.join(target_dir, openscad.stl_filename(p['title'])) md5path = os.path.join(target_dir, openscad.stl_filename(p['title']) + '.md5') print(" Checking csg hash") # Get csg hash h = openscad.get_csg_hash(temp_name, p['call']); os.remove(temp_name); # Get old csg hash oldh = "" if os.path.isfile(md5path): with open(md5path,'r') as f: oldh = f.read() hashchanged = h != oldh # update hash in json p['hash'] = h # save new hash with open(md5path,'w') as f: f.write(h) # STL print(" STL") if hashchanged or (not os.path.isfile(stlpath)): print(" Rendering STL...") info = openscad.render_stl(temp_name, stlpath, p['call']) jsontools.json_merge_missing_keys(p, info) # Slice for weight and volume print(" Slice") if hashchanged or ('plasticWeight' not in p): # Slice part and track volume of plastic required # Estimate KG of plastic from density range: 1.23-1.25 g/cm3 plasticInfo = slic3r.calc_plastic_required(stlpath) jsontools.json_merge_missing_keys(p, plasticInfo) else: print(" GCode up to date") print(" views") # Views for view in p['views']: print(" "+view['title']) render_view(p['title'], p['call'], view_dir, view, hashchanged, h) # Add to stlList stlList.append(stlpath) stlList.append(md5path) else: print(" Error: scad file not found: "+p['file']) # Save changes to json with open('hardware.json', 'w') as f: f.write(json.dumps(jso, sort_keys=False, indent=4, separators=(',', ': '))) # clean-up orphaned stls and checksums print "Checking for outdated STLs..." for f in os.listdir(target_dir): fp = os.path.join(target_dir, f) try: if os.path.isfile(fp) and (fp not in stlList): print "Removing: "+fp os.remove(fp) except Exception, e: print e