Restored explode lines to yellow.
Now keeps track of STL bounds and uses them to force a large assembly view when large.
1
.gitignore
vendored
@ -6,6 +6,7 @@ tests/bom/
|
||||
*.deps
|
||||
*.log
|
||||
*.html
|
||||
bounds.json
|
||||
times.txt
|
||||
*_diff.png
|
||||
*.echo
|
||||
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@ -71,12 +71,12 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||
|
||||
### Assembly instructions
|
||||
![base_assembly](assemblies/base_assembly_tn.png)
|
||||
![base_assembly](assemblies/base_assembly.png)
|
||||
|
||||
1. Remove the support material from under the insert lugs.
|
||||
2. Place the inserts into the holes in the lugs and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
|
||||
![base_assembled](assemblies/base_assembled_tn.png)
|
||||
![base_assembled](assemblies/base_assembled.png)
|
||||
|
||||
[Top](#TOP)
|
||||
|
||||
@ -108,11 +108,11 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||
|
||||
### Assembly instructions
|
||||
![feet_assembly](assemblies/feet_assembly_tn.png)
|
||||
![feet_assembly](assemblies/feet_assembly.png)
|
||||
|
||||
* Attach the four feet using 10mm M3 dome screws, washers above and below and nyloc nuts
|
||||
|
||||
![feet_assembled](assemblies/feet_assembled_tn.png)
|
||||
![feet_assembled](assemblies/feet_assembled.png)
|
||||
|
||||
[Top](#TOP)
|
||||
|
||||
@ -141,7 +141,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||
|
||||
### Assembly instructions
|
||||
![mains_in_assembly](assemblies/mains_in_assembly_tn.png)
|
||||
![mains_in_assembly](assemblies/mains_in_assembly.png)
|
||||
|
||||
1. Solder wires to the IEC terminals: -
|
||||
* Use wire rated for 13A, e.g. 1.5mm<sup>2</sup>, the easiest source is stripping 13A rated flex.
|
||||
@ -151,7 +151,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
1. Cover the the joints with heatshrink sleeving and shrink it with a hot air gun.
|
||||
1. Attach the IEC inlet using two 12mm M3 countersunk cap screws, washers and nyloc nuts on the back.
|
||||
|
||||
![mains_in_assembled](assemblies/mains_in_assembled_tn.png)
|
||||
![mains_in_assembled](assemblies/mains_in_assembled.png)
|
||||
|
||||
[Top](#TOP)
|
||||
|
||||
@ -181,7 +181,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||
|
||||
### Assembly instructions
|
||||
![main_assembly](assemblies/main_assembly_tn.png)
|
||||
![main_assembly](assemblies/main_assembly.png)
|
||||
|
||||
![inside](docs/inside_small.jpg)
|
||||
|
||||
@ -194,6 +194,6 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
1. Crimp appropriate ferrules to the three wires and connect them to the 13A socket.
|
||||
1. Screw the socket onto the top of the case using two 20mm M3 countersunk cap screws.
|
||||
|
||||
![main_assembled](assemblies/main_assembled_tn.png)
|
||||
![main_assembled](assemblies/main_assembled.png)
|
||||
|
||||
[Top](#TOP)
|
||||
|
@ -85,6 +85,8 @@ class STL:
|
||||
sys.exit(1)
|
||||
|
||||
def write(self, fname):
|
||||
mins = [float('inf'), float('inf'), float('inf')]
|
||||
maxs = [float('-inf'), float('-inf'), float('-inf')]
|
||||
with open(fname,"wt") as f:
|
||||
print('solid OpenSCAD_Model', file=f)
|
||||
for facet in self.facets:
|
||||
@ -92,13 +94,18 @@ class STL:
|
||||
print(' outer loop', file=f)
|
||||
for vertex in facet.vertices:
|
||||
print(' vertex %s %s %s' % (vertex.x, vertex.y, vertex.z), file=f)
|
||||
for i in range(3):
|
||||
ordinate = vertex.key[i]
|
||||
if ordinate > maxs[i]: maxs[i] = ordinate
|
||||
if ordinate < mins[i]: mins[i] = ordinate
|
||||
print(' endloop', file=f)
|
||||
print(' endfacet', file=f)
|
||||
print('endsolid OpenSCAD_Model', file=f)
|
||||
return mins, maxs
|
||||
|
||||
def canonicalise(fname):
|
||||
stl = STL(fname)
|
||||
stl.write(fname)
|
||||
return stl.write(fname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) == 2:
|
||||
|
@ -28,6 +28,7 @@ from set_config import *
|
||||
import time
|
||||
import times
|
||||
from deps import *
|
||||
import json
|
||||
|
||||
def bom_to_parts(target_dir, part_type, assembly = None):
|
||||
#
|
||||
@ -70,6 +71,16 @@ def make_parts(target, part_type, parts = None):
|
||||
print("Removing %s" % file)
|
||||
os.remove(target_dir + '/' + file)
|
||||
#
|
||||
# Read existing STL bounds
|
||||
#
|
||||
if part_type == 'stl':
|
||||
bounds_fname = target_dir + '/bounds.json'
|
||||
try:
|
||||
with open(bounds_fname) as json_file:
|
||||
bounds_map = json.load(json_file)
|
||||
except:
|
||||
bounds_map = {}
|
||||
#
|
||||
# Find all the scad files
|
||||
#
|
||||
lib_dir = os.environ['OPENSCADPATH'] + '/NopSCADlib'
|
||||
@ -104,13 +115,16 @@ def make_parts(target, part_type, parts = None):
|
||||
dname = deps_name(deps_dir, filename)
|
||||
changed = check_deps(mtime(part_file), dname)
|
||||
changed = times.check_have_time(changed, part)
|
||||
if part_type == 'stl' and not changed and not part in bounds_map:
|
||||
changed = "No bounds"
|
||||
if changed:
|
||||
print(changed)
|
||||
t = time.time()
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
|
||||
times.add_time(part, t)
|
||||
if part_type == 'stl':
|
||||
c14n_stl.canonicalise(part_file)
|
||||
bounds = c14n_stl.canonicalise(part_file)
|
||||
bounds_map[part] = bounds
|
||||
targets.remove(part)
|
||||
os.remove(part_maker_name)
|
||||
#
|
||||
@ -120,6 +134,12 @@ def make_parts(target, part_type, parts = None):
|
||||
if line[:7] == 'ECHO: "' and line[-6:] == '.' + part_type + '"\n':
|
||||
used.append(line[7:-2])
|
||||
#
|
||||
# Write new bounds file
|
||||
#
|
||||
if part_type == 'stl':
|
||||
with open(bounds_fname, 'w') as outfile:
|
||||
json.dump(bounds_map, outfile, indent = 4)
|
||||
#
|
||||
# List the ones we didn't find
|
||||
#
|
||||
if targets:
|
||||
|
@ -39,17 +39,26 @@ from colorama import Fore
|
||||
def is_assembly(s):
|
||||
return s[-9:] == '_assembly' or s[-11:] == '_assemblies'
|
||||
|
||||
def add_assembly(flat_bom, bom):
|
||||
def add_assembly(flat_bom, bom, bounds_map):
|
||||
if not bom in flat_bom:
|
||||
big = False
|
||||
for ass in bom["assemblies"]:
|
||||
add_assembly(flat_bom, ass)
|
||||
if ass["routed"]:
|
||||
add_assembly(flat_bom, ass, bounds_map)
|
||||
if ass["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(bom)
|
||||
|
||||
def bom_to_assemblies(bom_dir):
|
||||
def bom_to_assemblies(bom_dir, bounds_map):
|
||||
global flat_bom
|
||||
#
|
||||
# Make a list of all the parts in the BOM
|
||||
@ -59,7 +68,7 @@ def bom_to_assemblies(bom_dir):
|
||||
with open(bom_file) as json_file:
|
||||
bom = json.load(json_file)
|
||||
flat_bom = []
|
||||
add_assembly(flat_bom, bom)
|
||||
add_assembly(flat_bom, bom, bounds_map)
|
||||
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]
|
||||
@ -90,11 +99,15 @@ def views(target, do_assemblies = None):
|
||||
os.makedirs(target_dir)
|
||||
if not os.path.isdir(deps_dir):
|
||||
os.makedirs(deps_dir)
|
||||
|
||||
times.read_times(target_dir)
|
||||
bounds_fname = top_dir + 'stls/bounds.json'
|
||||
with open(bounds_fname) as json_file:
|
||||
bounds_map = json.load(json_file)
|
||||
#
|
||||
# Find all the assemblies
|
||||
#
|
||||
assemblies = bom_to_assemblies(bom_dir)
|
||||
assemblies = bom_to_assemblies(bom_dir, bounds_map)
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.png'):
|
||||
assembly = file[:-4].replace('_assembled', '_assembly')
|
||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
@ -34,9 +34,9 @@ module no_pose() let($posed = true) children(); //! Force ch
|
||||
module explode(d, explode_children = false, offset = [0,0,0]) { //! Explode children by specified Z distance or vector ```d```, option to explode grand children
|
||||
v = is_list(d) ? d : [0, 0, d];
|
||||
o = is_list(offset) ? offset : [0, 0, offset];
|
||||
if($exploded && is_undef($exploded_parent)) {
|
||||
if($exploded && is_undef($exploded_parent) && norm(v)) {
|
||||
translate(o) // Draw the line first in case the child is transparent
|
||||
hull() {
|
||||
color("yellow") hull() {
|
||||
sphere(0.2);
|
||||
|
||||
translate(v * $exploded)
|
||||
|
@ -45,20 +45,18 @@ module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specifi
|
||||
vitamin(str("nut(", type[0], arg(nyloc, false, "nyloc"), arg(brass, false, "brass"), arg(nylon, false, "nylon"),
|
||||
"): Nut M", nut_size(type), " ", desc));
|
||||
|
||||
if(exploded() && nyloc)
|
||||
cylinder(r = 0.2, h = 10);
|
||||
explode(nyloc ? 10 : 0)
|
||||
color(brass ? brass_colour : nylon ? grey30: grey70) {
|
||||
linear_extrude(height = thickness)
|
||||
difference() {
|
||||
circle(outer_rad, $fn = 6);
|
||||
|
||||
color(brass ? brass_colour : nylon ? grey30: grey70) translate_z((exploded() && nyloc) ? 10 : 0) {
|
||||
linear_extrude(height = thickness)
|
||||
difference() {
|
||||
circle(outer_rad, $fn = 6);
|
||||
|
||||
circle(hole_rad);
|
||||
}
|
||||
if(nyloc)
|
||||
translate_z(-eps)
|
||||
rounded_cylinder(r = outer_rad * cos(30) , h = nyloc_thickness, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
|
||||
}
|
||||
circle(hole_rad);
|
||||
}
|
||||
if(nyloc)
|
||||
translate_z(-eps)
|
||||
rounded_cylinder(r = outer_rad * cos(30) , h = nyloc_thickness, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
|
||||
}
|
||||
if($children)
|
||||
translate_z(thickness)
|
||||
children();
|
||||
|