Added usage messages to all the scripts and documented multiple configuration
projects.
This commit is contained in:
parent
a8422a6aa6
commit
23a64f238d
|
@ -233,3 +233,13 @@ Vitamins are only ever previewed, so they are optimised to draw quickly in F5 an
|
||||||
In OpenCSG 3D difference and intersection are relatively slow and the negative volumes interfere with nearby objects when they are composed into assemblies. For this reason as much
|
In OpenCSG 3D difference and intersection are relatively slow and the negative volumes interfere with nearby objects when they are composed into assemblies. For this reason as much
|
||||||
as possible is done by unioning primitives and extruded 2D shapes. Any 3D differences or intersections are wrapped in ```render()``` so that CGAL will compute a polyhedron
|
as possible is done by unioning primitives and extruded 2D shapes. Any 3D differences or intersections are wrapped in ```render()``` so that CGAL will compute a polyhedron
|
||||||
that is cached and reused. This will be very slow the first time it renders but very fast afterwards.
|
that is cached and reused. This will be very slow the first time it renders but very fast afterwards.
|
||||||
|
|
||||||
|
### Multiple configurations
|
||||||
|
|
||||||
|
Some parametric designs might have several configurations, for example a 3D printer with different size options. If several configurations need to be supported at the
|
||||||
|
same time multiple sets of BOMS, STLS and DXFs need to be generated in separate diectories. NopSCADlib supports this by having multiple configuration files named
|
||||||
|
```config_<target_name>.scad```. All the scripts take an optional first parameter that selects one of these config files by specifying ```target_name```.
|
||||||
|
|
||||||
|
The target config file is selected by generating ```target.scad``` that includes ```config_<target_name>.scad```.
|
||||||
|
The rest of the project includes ```target.scad``` to use the configuration.
|
||||||
|
Additionally all the generated file directories (assemblies, bom, stls, dxfs, etc. are placed in a sub-directory called ```<target_name>```.
|
||||||
|
|
|
@ -189,8 +189,12 @@ def parse_bom(file = "openscad.log", name = None):
|
||||||
print(line[:-1])
|
print(line[:-1])
|
||||||
return main
|
return main
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\tbom [target_config] [<accessory_name>_assembly] - Generate BOMs for a project or an accessory to a project.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def boms(target = None, assembly = None):
|
def boms(target = None, assembly = None):
|
||||||
bom_dir = set_config(target) + "bom"
|
bom_dir = set_config(target, usage) + "bom"
|
||||||
if assembly:
|
if assembly:
|
||||||
bom_dir += "/accessories"
|
bom_dir += "/accessories"
|
||||||
if not os.path.isdir(bom_dir):
|
if not os.path.isdir(bom_dir):
|
||||||
|
@ -239,11 +243,24 @@ def boms(target = None, assembly = None):
|
||||||
print("done")
|
print("done")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = len(sys.argv)
|
if len(sys.argv) > 3: usage()
|
||||||
if args > 1:
|
|
||||||
if args > 2:
|
if len(sys.argv) == 3:
|
||||||
boms(sys.argv[1], sys.argv[2])
|
target, assembly = sys.argv[1], sys.argv[2]
|
||||||
else:
|
else:
|
||||||
boms(sys.argv[1])
|
if len(sys.argv) == 2:
|
||||||
|
if sys.argv[1][-9:] == "_assembly":
|
||||||
|
target, assembly = None, sys.argv[1]
|
||||||
else:
|
else:
|
||||||
boms();
|
target, assembly = sys.argv[1], None
|
||||||
|
else:
|
||||||
|
target, assembly = None, None
|
||||||
|
|
||||||
|
if assembly:
|
||||||
|
if assembly[-9:] != "_assembly": usage()
|
||||||
|
|
||||||
|
try:
|
||||||
|
boms(target, assembly)
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
sys.exit(1)
|
||||||
|
|
|
@ -113,5 +113,5 @@ if __name__ == '__main__':
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
canonicalise(sys.argv[1])
|
canonicalise(sys.argv[1])
|
||||||
else:
|
else:
|
||||||
print("usage: c14n_stl file")
|
print("\nusage:\n\t c14n_stl file - Canonicalise an STL file created by OpenSCAD.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -26,6 +26,7 @@ from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from tests import do_cmd
|
from tests import do_cmd
|
||||||
|
import argparse
|
||||||
|
|
||||||
dir = 'scripts'
|
dir = 'scripts'
|
||||||
|
|
||||||
|
@ -74,4 +75,5 @@ They should work with both Python 2 and Python 3.
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
argparse.ArgumentParser().parse_args()
|
||||||
doc_scripts()
|
doc_scripts()
|
||||||
|
|
|
@ -46,11 +46,21 @@ def bom_to_parts(target_dir, part_type, assembly = None):
|
||||||
part_files.append(last_word[:-4] + '.' + part_type)
|
part_files.append(last_word[:-4] + '.' + part_type)
|
||||||
return part_files
|
return part_files
|
||||||
|
|
||||||
|
def usage(t):
|
||||||
|
print("\nusage:\n\t%ss [target_config] [<name1>.%s] ... [<nameN>.%s] - Generate specified %s files or all if none specified." % ( t, t, t, t.upper()))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def make_parts(target, part_type, parts = None):
|
def make_parts(target, part_type, parts = None):
|
||||||
#
|
#
|
||||||
|
# Check list of parts is the correct type
|
||||||
|
#
|
||||||
|
if parts:
|
||||||
|
for p in parts:
|
||||||
|
if not p.endswith('.' + part_type): usage(part_type)
|
||||||
|
#
|
||||||
# Make the target directory
|
# Make the target directory
|
||||||
#
|
#
|
||||||
top_dir = set_config(target)
|
top_dir = set_config(target, lambda: usage(part_type))
|
||||||
target_dir = top_dir + part_type + 's'
|
target_dir = top_dir + part_type + 's'
|
||||||
deps_dir = top_dir + "deps"
|
deps_dir = top_dir + "deps"
|
||||||
if not os.path.isdir(target_dir):
|
if not os.path.isdir(target_dir):
|
||||||
|
@ -142,5 +152,5 @@ def make_parts(target, part_type, parts = None):
|
||||||
print(part, "is not a", part_type, "file")
|
print(part, "is not a", part_type, "file")
|
||||||
else:
|
else:
|
||||||
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
|
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
|
||||||
sys.exit(1)
|
usage(part_type)
|
||||||
times.print_times()
|
times.print_times()
|
||||||
|
|
|
@ -30,6 +30,7 @@ import re
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
from tests import update_image
|
from tests import update_image
|
||||||
import sys
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
project_dirs = ['../..', 'examples']
|
project_dirs = ['../..', 'examples']
|
||||||
target_dir = 'gallery'
|
target_dir = 'gallery'
|
||||||
|
@ -39,7 +40,6 @@ def gallery(force):
|
||||||
if not os.path.isdir(target_dir):
|
if not os.path.isdir(target_dir):
|
||||||
os.makedirs(target_dir)
|
os.makedirs(target_dir)
|
||||||
|
|
||||||
|
|
||||||
paths = sorted([pdir + '/' + i for pdir in project_dirs for i in os.listdir(pdir) if os.path.isdir(pdir + '/' + i + '/assemblies')], key = lambda s: os.path.basename(s))
|
paths = sorted([pdir + '/' + i for pdir in project_dirs for i in os.listdir(pdir) if os.path.isdir(pdir + '/' + i + '/assemblies')], key = lambda s: os.path.basename(s))
|
||||||
with open(output_name, 'wt') as output_file:
|
with open(output_name, 'wt') as output_file:
|
||||||
print("# A gallery of projects made with NopSCADlib", file = output_file)
|
print("# A gallery of projects made with NopSCADlib", file = output_file)
|
||||||
|
@ -78,4 +78,8 @@ def gallery(force):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
init()
|
init()
|
||||||
gallery(force = len(sys.argv) > 1 and sys.argv[1] == '-f')
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("-f", help = "run make_all in each project to force update", action="store_true")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
gallery(force = args.f)
|
||||||
|
|
|
@ -27,9 +27,17 @@ from bom import boms
|
||||||
from render import render
|
from render import render
|
||||||
from views import views
|
from views import views
|
||||||
from plateup import plateup
|
from plateup import plateup
|
||||||
|
from set_config import set_config
|
||||||
|
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\tmake_all [target_config] - Make all the manufacturing files and readme for a project.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) > 2: usage()
|
||||||
target = None if len(sys.argv) == 1 else sys.argv[1]
|
target = None if len(sys.argv) == 1 else sys.argv[1]
|
||||||
|
set_config(target, usage)
|
||||||
boms(target)
|
boms(target)
|
||||||
for part in ['stl', 'dxf']:
|
for part in ['stl', 'dxf']:
|
||||||
make_parts(target, part)
|
make_parts(target, part)
|
||||||
|
|
|
@ -25,9 +25,15 @@ import sys
|
||||||
|
|
||||||
from plateup import plateup
|
from plateup import plateup
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\tpanels [target_config] - Aggregate DXF files for routing together.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) > 2: usage()
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
target = sys.argv[1]
|
target = sys.argv[1]
|
||||||
else:
|
else:
|
||||||
target = None
|
target = None
|
||||||
plateup(target, 'dxf')
|
plateup(target, 'dxf', usage)
|
||||||
|
|
|
@ -31,11 +31,11 @@ from shutil import copyfile
|
||||||
source_dirs = { "stl" : "platters", "dxf" : "panels" }
|
source_dirs = { "stl" : "platters", "dxf" : "panels" }
|
||||||
target_dirs = { "stl" : "printed", "dxf" : "routed" }
|
target_dirs = { "stl" : "printed", "dxf" : "routed" }
|
||||||
|
|
||||||
def plateup(target, part_type):
|
def plateup(target, part_type, usage = None):
|
||||||
#
|
#
|
||||||
# Make the target directory
|
# Make the target directory
|
||||||
#
|
#
|
||||||
top_dir = set_config(target)
|
top_dir = set_config(target, usage)
|
||||||
parts_dir = top_dir + part_type + 's'
|
parts_dir = top_dir + part_type + 's'
|
||||||
target_dir = parts_dir + '/' + target_dirs[part_type]
|
target_dir = parts_dir + '/' + target_dirs[part_type]
|
||||||
source_dir = top_dir + source_dirs[part_type]
|
source_dir = top_dir + source_dirs[part_type]
|
||||||
|
|
|
@ -25,9 +25,15 @@ import sys
|
||||||
|
|
||||||
from plateup import plateup
|
from plateup import plateup
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\tplatters [target_config] - Aggregate STL files for printing together.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) > 2: usage()
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
target = sys.argv[1]
|
target = sys.argv[1]
|
||||||
else:
|
else:
|
||||||
target = None
|
target = None
|
||||||
plateup(target, 'stl')
|
plateup(target, 'stl', usage)
|
||||||
|
|
|
@ -30,11 +30,15 @@ from tests import do_cmd, update_image, colour_scheme, background
|
||||||
from deps import mtime
|
from deps import mtime
|
||||||
from colorama import init
|
from colorama import init
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def render(target, type):
|
def render(target, type):
|
||||||
#
|
#
|
||||||
# Make the target directory
|
# Make the target directory
|
||||||
#
|
#
|
||||||
target_dir = set_config(target) + type + 's'
|
target_dir = set_config(target, usage) + type + 's'
|
||||||
if not os.path.isdir(target_dir):
|
if not os.path.isdir(target_dir):
|
||||||
os.makedirs(target_dir)
|
os.makedirs(target_dir)
|
||||||
#
|
#
|
||||||
|
@ -71,6 +75,7 @@ def render(target, type):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
init()
|
init()
|
||||||
|
if len(sys.argv) > 2: usage()
|
||||||
target = sys.argv[1] if len(sys.argv) > 1 else None
|
target = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
render(target, 'stl')
|
render(target, 'stl')
|
||||||
render(target, 'dxf')
|
render(target, 'dxf')
|
||||||
|
|
|
@ -45,20 +45,27 @@ def valid_targets_string():
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def set_config(target):
|
def set_config(target, usage = None):
|
||||||
|
if target and target[:1] == '-' and usage: usage()
|
||||||
targets = valid_targets()
|
targets = valid_targets()
|
||||||
if not target:
|
if not target:
|
||||||
if not targets:
|
if not targets:
|
||||||
return ""
|
return ""
|
||||||
print("Must specify a configuration: " + valid_targets_string())
|
print("Must specify a configuration: " + valid_targets_string())
|
||||||
|
if usage:
|
||||||
|
usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not targets:
|
if not targets:
|
||||||
print("Not a muli-configuration project (no config_<target>.scad files found)")
|
print("Not a muli-configuration project (no config_<target>.scad files found)")
|
||||||
|
if usage:
|
||||||
|
usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not target in targets:
|
if not target in targets:
|
||||||
print(target + " is not a configuration, avaliable configurations are: " + valid_targets_string())
|
print(target + " is not a configuration, avaliable configurations are: " + valid_targets_string())
|
||||||
|
if usage:
|
||||||
|
usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
fname = source_dir + "/target.scad"
|
fname = source_dir + "/target.scad"
|
||||||
|
@ -75,10 +82,13 @@ def set_config(target):
|
||||||
f. write(text);
|
f. write(text);
|
||||||
return target + "/"
|
return target + "/"
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\tset_config config_name")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = len(sys.argv)
|
args = len(sys.argv)
|
||||||
if args == 2:
|
if args == 2:
|
||||||
set_config(sys.argv[1])
|
set_config(sys.argv[1], usage)
|
||||||
else:
|
else:
|
||||||
print("usage: set_config config_name")
|
usage()
|
||||||
sys.exit(1)
|
|
||||||
|
|
|
@ -85,6 +85,10 @@ def depluralise(name):
|
||||||
def is_plural(name):
|
def is_plural(name):
|
||||||
return name != depluralise(name)
|
return name != depluralise(name)
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\ttests [test_name1] ... [test_nameN] - Run specified tests or all tests in none specified.");
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def tests(tests):
|
def tests(tests):
|
||||||
scad_dir = "tests"
|
scad_dir = "tests"
|
||||||
deps_dir = scad_dir + "/deps"
|
deps_dir = scad_dir + "/deps"
|
||||||
|
@ -96,6 +100,7 @@ def tests(tests):
|
||||||
doc_name = "readme.md"
|
doc_name = "readme.md"
|
||||||
index = {}
|
index = {}
|
||||||
bodies = {}
|
bodies = {}
|
||||||
|
done = []
|
||||||
times.read_times()
|
times.read_times()
|
||||||
options.check_options(deps_dir)
|
options.check_options(deps_dir)
|
||||||
#
|
#
|
||||||
|
@ -114,6 +119,7 @@ def tests(tests):
|
||||||
for scad in scads:
|
for scad in scads:
|
||||||
base_name = scad[:-5]
|
base_name = scad[:-5]
|
||||||
if not tests or base_name in tests:
|
if not tests or base_name in tests:
|
||||||
|
done.append(base_name)
|
||||||
print(base_name)
|
print(base_name)
|
||||||
cap_name = base_name[0].capitalize() + base_name[1:]
|
cap_name = base_name[0].capitalize() + base_name[1:]
|
||||||
base_name = base_name.lower()
|
base_name = base_name.lower()
|
||||||
|
@ -234,6 +240,14 @@ def tests(tests):
|
||||||
body += ['\n<a href="#top">Top</a>']
|
body += ['\n<a href="#top">Top</a>']
|
||||||
body += ["\n---"]
|
body += ["\n---"]
|
||||||
|
|
||||||
|
for test in done:
|
||||||
|
if test in tests:
|
||||||
|
tests.remove(test)
|
||||||
|
if tests:
|
||||||
|
for test in tests:
|
||||||
|
print(Fore.MAGENTA + "Could not find a test called", test, Fore.WHITE)
|
||||||
|
usage()
|
||||||
|
|
||||||
with open(doc_name, "wt") as doc_file:
|
with open(doc_name, "wt") as doc_file:
|
||||||
print('# NopSCADlib', file = doc_file)
|
print('# NopSCADlib', file = doc_file)
|
||||||
print('''\
|
print('''\
|
||||||
|
@ -279,4 +293,6 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||||
do_cmd('codespell -L od readme.md'.split())
|
do_cmd('codespell -L od readme.md'.split())
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
if arg[:1] == '-': usage()
|
||||||
tests(sys.argv[1:])
|
tests(sys.argv[1:])
|
||||||
|
|
|
@ -97,12 +97,16 @@ def titalise(name):
|
||||||
cap_next = c == ' '
|
cap_next = c == ' '
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("\nusage:\n\t views [target_config] [<name1>_assembly] ... [<nameN>_assembly] - Create assembly images and readme.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def views(target, do_assemblies = None):
|
def views(target, do_assemblies = None):
|
||||||
done_assemblies = []
|
done_assemblies = []
|
||||||
#
|
#
|
||||||
# Make the target directory
|
# Make the target directory
|
||||||
#
|
#
|
||||||
top_dir = set_config(target)
|
top_dir = set_config(target, usage)
|
||||||
target_dir = top_dir + 'assemblies'
|
target_dir = top_dir + 'assemblies'
|
||||||
deps_dir = top_dir + "deps"
|
deps_dir = top_dir + "deps"
|
||||||
bom_dir = top_dir + "bom"
|
bom_dir = top_dir + "bom"
|
||||||
|
@ -396,4 +400,7 @@ if __name__ == '__main__':
|
||||||
else:
|
else:
|
||||||
target, assemblies = None, sys.argv[1:]
|
target, assemblies = None, sys.argv[1:]
|
||||||
|
|
||||||
|
for a in assemblies:
|
||||||
|
if a[-9:] != "_assembly": usage()
|
||||||
|
|
||||||
views(target, assemblies)
|
views(target, assemblies)
|
||||||
|
|
Loading…
Reference in New Issue