Added usage messages to all the scripts and documented multiple configuration

projects.
This commit is contained in:
Chris Palmer 2020-03-11 23:09:03 +00:00
parent a8422a6aa6
commit 23a64f238d
14 changed files with 124 additions and 23 deletions

View File

@ -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
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.
### 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>```.

View File

@ -189,8 +189,12 @@ def parse_bom(file = "openscad.log", name = None):
print(line[:-1])
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):
bom_dir = set_config(target) + "bom"
bom_dir = set_config(target, usage) + "bom"
if assembly:
bom_dir += "/accessories"
if not os.path.isdir(bom_dir):
@ -239,11 +243,24 @@ def boms(target = None, assembly = None):
print("done")
if __name__ == '__main__':
args = len(sys.argv)
if args > 1:
if args > 2:
boms(sys.argv[1], sys.argv[2])
if len(sys.argv) > 3: usage()
if len(sys.argv) == 3:
target, assembly = sys.argv[1], sys.argv[2]
else:
boms(sys.argv[1])
if len(sys.argv) == 2:
if sys.argv[1][-9:] == "_assembly":
target, assembly = None, sys.argv[1]
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)

View File

@ -113,5 +113,5 @@ if __name__ == '__main__':
if len(sys.argv) == 2:
canonicalise(sys.argv[1])
else:
print("usage: c14n_stl file")
print("\nusage:\n\t c14n_stl file - Canonicalise an STL file created by OpenSCAD.")
sys.exit(1)

View File

@ -26,6 +26,7 @@ from __future__ import print_function
import os
from tests import do_cmd
import argparse
dir = 'scripts'
@ -74,4 +75,5 @@ They should work with both Python 2 and Python 3.
if __name__ == '__main__':
argparse.ArgumentParser().parse_args()
doc_scripts()

View File

@ -46,11 +46,21 @@ def bom_to_parts(target_dir, part_type, assembly = None):
part_files.append(last_word[:-4] + '.' + part_type)
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):
#
# 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
#
top_dir = set_config(target)
top_dir = set_config(target, lambda: usage(part_type))
target_dir = top_dir + part_type + 's'
deps_dir = top_dir + "deps"
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")
else:
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
sys.exit(1)
usage(part_type)
times.print_times()

View File

@ -30,6 +30,7 @@ import re
from shutil import copyfile
from tests import update_image
import sys
import argparse
project_dirs = ['../..', 'examples']
target_dir = 'gallery'
@ -39,7 +40,6 @@ def gallery(force):
if not os.path.isdir(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))
with open(output_name, 'wt') as output_file:
print("# A gallery of projects made with NopSCADlib", file = output_file)
@ -78,4 +78,8 @@ def gallery(force):
if __name__ == '__main__':
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)

View File

@ -27,9 +27,17 @@ from bom import boms
from render import render
from views import views
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 len(sys.argv) > 2: usage()
target = None if len(sys.argv) == 1 else sys.argv[1]
set_config(target, usage)
boms(target)
for part in ['stl', 'dxf']:
make_parts(target, part)

View File

@ -25,9 +25,15 @@ import sys
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 len(sys.argv) > 2: usage()
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = None
plateup(target, 'dxf')
plateup(target, 'dxf', usage)

View File

@ -31,11 +31,11 @@ from shutil import copyfile
source_dirs = { "stl" : "platters", "dxf" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed" }
def plateup(target, part_type):
def plateup(target, part_type, usage = None):
#
# Make the target directory
#
top_dir = set_config(target)
top_dir = set_config(target, usage)
parts_dir = top_dir + part_type + 's'
target_dir = parts_dir + '/' + target_dirs[part_type]
source_dir = top_dir + source_dirs[part_type]

View File

@ -25,9 +25,15 @@ import sys
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 len(sys.argv) > 2: usage()
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = None
plateup(target, 'stl')
plateup(target, 'stl', usage)

View File

@ -30,11 +30,15 @@ from tests import do_cmd, update_image, colour_scheme, background
from deps import mtime
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):
#
# 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):
os.makedirs(target_dir)
#
@ -71,6 +75,7 @@ def render(target, type):
if __name__ == '__main__':
init()
if len(sys.argv) > 2: usage()
target = sys.argv[1] if len(sys.argv) > 1 else None
render(target, 'stl')
render(target, 'dxf')

View File

@ -45,20 +45,27 @@ def valid_targets_string():
return result
def set_config(target):
def set_config(target, usage = None):
if target and target[:1] == '-' and usage: usage()
targets = valid_targets()
if not target:
if not targets:
return ""
print("Must specify a configuration: " + valid_targets_string())
if usage:
usage()
sys.exit(1)
if not targets:
print("Not a muli-configuration project (no config_<target>.scad files found)")
if usage:
usage()
sys.exit(1)
if not target in targets:
print(target + " is not a configuration, avaliable configurations are: " + valid_targets_string())
if usage:
usage()
sys.exit(1)
fname = source_dir + "/target.scad"
@ -75,10 +82,13 @@ def set_config(target):
f. write(text);
return target + "/"
def usage():
print("\nusage:\n\tset_config config_name")
sys.exit(1)
if __name__ == '__main__':
args = len(sys.argv)
if args == 2:
set_config(sys.argv[1])
set_config(sys.argv[1], usage)
else:
print("usage: set_config config_name")
sys.exit(1)
usage()

View File

@ -85,6 +85,10 @@ def depluralise(name):
def is_plural(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):
scad_dir = "tests"
deps_dir = scad_dir + "/deps"
@ -96,6 +100,7 @@ def tests(tests):
doc_name = "readme.md"
index = {}
bodies = {}
done = []
times.read_times()
options.check_options(deps_dir)
#
@ -114,6 +119,7 @@ def tests(tests):
for scad in scads:
base_name = scad[:-5]
if not tests or base_name in tests:
done.append(base_name)
print(base_name)
cap_name = base_name[0].capitalize() + base_name[1:]
base_name = base_name.lower()
@ -234,6 +240,14 @@ def tests(tests):
body += ['\n<a href="#top">Top</a>']
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:
print('# NopSCADlib', file = doc_file)
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())
if __name__ == '__main__':
for arg in sys.argv[1:]:
if arg[:1] == '-': usage()
tests(sys.argv[1:])

View File

@ -97,12 +97,16 @@ def titalise(name):
cap_next = c == ' '
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):
done_assemblies = []
#
# Make the target directory
#
top_dir = set_config(target)
top_dir = set_config(target, usage)
target_dir = top_dir + 'assemblies'
deps_dir = top_dir + "deps"
bom_dir = top_dir + "bom"
@ -396,4 +400,7 @@ if __name__ == '__main__':
else:
target, assemblies = None, sys.argv[1:]
for a in assemblies:
if a[-9:] != "_assembly": usage()
views(target, assemblies)