diff --git a/readme.md b/readme.md index 398c584..035fe36 100644 --- a/readme.md +++ b/readme.md @@ -5174,8 +5174,12 @@ Simple tube or ring Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing. Assembly instructions can precede the module definition that makes the assembly. -The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view. The resulting flat BOM is shown but -heirachical BOMs are also generated for real projects. +Assembly views shown in the instructions can be large or small and this is deduced by looking at the size of the printed parts involved and if any routed +parts are used. +This heuristic isn't always correct, so the default can be overridden by setting the ```big``` parameter of ```assembly``` to ```true``` or ```false```. + +The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view. +The resulting flat BOM is shown but heirachical BOMs are also generated for real projects. [utils/core/bom.scad](utils/core/bom.scad) Implementation. @@ -5194,7 +5198,7 @@ heirachical BOMs are also generated for real projects. ### Modules | Module | Description | |:--- |:--- | -| ```assembly(name)``` | Name an assembly that will appear on the BOM, there needs to a module named ```_assembly``` to make it | +| ```assembly(name, big = undef)``` | Name an assembly that will appear on the BOM, there needs to a module named ```_assembly``` to make it. ```big``` can force big or small assembly diagrams. | | ```dxf(name)``` | Name a dxf that will appear on the BOM, there needs to a module named ```_dxf``` to make it | | ```explode(d, explode_children = false, offset = [0,0,0])``` | Explode children by specified Z distance or vector ```d```, option to explode grand children | | ```hidden()``` | Make item invisible, except on the BOM | diff --git a/scripts/bom.py b/scripts/bom.py index 8f3f2cf..e69b8cc 100755 --- a/scripts/bom.py +++ b/scripts/bom.py @@ -29,6 +29,7 @@ import openscad from time import * from set_config import * import json +import re def find_scad_file(mname): for filename in os.listdir(source_dir): @@ -48,6 +49,7 @@ def find_scad_file(mname): class BOM: def __init__(self, name): self.name = name + self.big = None self.count = 1 self.vitamins = {} self.printed = {} @@ -60,6 +62,7 @@ class BOM: assemblies[ass] = self.assemblies[ass].count return { "name" : self.name, + "big" : self.big, "count" : self.count, "assemblies" : assemblies, "vitamins" : self.vitamins, @@ -80,11 +83,15 @@ class BOM: else: parts[s] = 1 - def add_assembly(self, ass): + def add_assembly(self, ass, args = []): if ass in self.assemblies: self.assemblies[ass].count += 1 else: - self.assemblies[ass] = BOM(ass) + bom = BOM(ass) + for arg in args: + arg = arg.replace('true', 'True').replace('false', 'False').replace('undef', 'None') + exec('bom.' + arg, locals()) + self.assemblies[ass] = bom def make_name(self, ass): if self.count == 1: @@ -161,17 +168,22 @@ def parse_bom(file = "openscad.log", name = None): main = BOM(name) main.ordered_assemblies = [] stack = [] - + prog = re.compile(r'^(.*)\((.*)\)$') for line in open(file): pos = line.find('ECHO: "~') if pos > -1: s = line[pos + 8 : line.rfind('"')] if s[-1] == '{': ass = s[:-1] + args = [] + match = prog.match(ass) #look for (...) + if match: + ass = match.group(1) + args = match.group(2).split(',') if stack: main.assemblies[stack[-1]].add_assembly(ass) #add to nested BOM stack.append(ass) - main.add_assembly(ass) #add to flat BOM + main.add_assembly(ass, args) #add to flat BOM if ass in main.ordered_assemblies: main.ordered_assemblies.remove(ass) main.ordered_assemblies.insert(0, ass) diff --git a/scripts/views.py b/scripts/views.py index 1a127fc..7770a40 100755 --- a/scripts/views.py +++ b/scripts/views.py @@ -52,22 +52,23 @@ def bom_to_assemblies(bom_dir, 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 b["big"]: + if bom["big"] == None: + big = False + for ass in bom["assemblies"]: + for b in flat_bom: + if b["name"] == ass: + 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 - 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"] + break + bom["big"] = big or bom["routed"] # # Remove the main assembly if it is a shell # diff --git a/utils/core/bom.scad b/utils/core/bom.scad index a3b338e..22ee941 100644 --- a/utils/core/bom.scad +++ b/utils/core/bom.scad @@ -21,8 +21,12 @@ //! Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing. Assembly instructions can precede the module //! definition that makes the assembly. //! -//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view. The resulting flat BOM is shown but -//! heirachical BOMs are also generated for real projects. +//! Assembly views shown in the instructions can be large or small and this is deduced by looking at the size of the printed parts involved and if any routed +//! parts are used. +//! This heuristic isn't always correct, so the default can be overridden by setting the ```big``` parameter of ```assembly``` to ```true``` or ```false```. +//! +//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view. +//! The resulting flat BOM is shown but heirachical BOMs are also generated for real projects. // function bom_mode(n = 1) = $_bom >= n && (is_undef($on_bom) || $on_bom); //! Current BOM mode, 0 = none, 1 = printed and routed parts and assemblies, 2 includes vitamins as well function exploded() = is_undef($exploded_parent) ? $exploded : 0; //! Returns the value of ```$exploded``` if it is defined, else ```0``` @@ -80,10 +84,11 @@ module pose_vflip(exploded = undef) //! Pose an STL or assembly for render children(); -module assembly(name) { //! Name an assembly that will appear on the BOM, there needs to a module named ```_assembly``` to make it - if(bom_mode()) - echo(str("~", name, "_assembly{")); - +module assembly(name, big = undef) { //! Name an assembly that will appear on the BOM, there needs to a module named ```_assembly``` to make it. ```big``` can force big or small assembly diagrams. + if(bom_mode()) { + args = is_undef(big) ? "" : str("(big=", big, ")"); + echo(str("~", name, "_assembly", args, "{")); + } no_pose() if(is_undef($child_assembly)) let($child_assembly = true)