From 466a7a667da16e4257360e43c3d9ccf1d14953c2 Mon Sep 17 00:00:00 2001 From: Chris Palmer Date: Sun, 18 Aug 2019 11:08:44 +0100 Subject: [PATCH] Added platters.py and panels.py to aggregate parts for printing / routing. --- core.scad | 12 ++++++ scripts/make_all.py | 3 ++ scripts/openscad.py | 9 +++-- scripts/panels.py | 33 +++++++++++++++ scripts/plateup.py | 98 +++++++++++++++++++++++++++++++++++++++++++++ scripts/platters.py | 33 +++++++++++++++ scripts/readme.md | 2 + 7 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 scripts/panels.py create mode 100644 scripts/plateup.py create mode 100644 scripts/platters.py diff --git a/core.scad b/core.scad index afe9726..c97ae0c 100644 --- a/core.scad +++ b/core.scad @@ -25,3 +25,15 @@ include // Global functions and modules // use + +module use_stl(name) { //! Import an STL to make a build platter + stl(name); + + import(str("../stls/", name, ".stl")); +} + +module use_dxf(name) { //! Import a DXF to make a build panel + dxf(name); + + import(str("../dxfs/", name, ".dxf")); +} diff --git a/scripts/make_all.py b/scripts/make_all.py index 60a5494..c77659a 100644 --- a/scripts/make_all.py +++ b/scripts/make_all.py @@ -26,6 +26,7 @@ from exports import make_parts from bom import boms from render import render from views import views +from plateup import plateup if __name__ == '__main__': target = None if len(sys.argv) == 1 else sys.argv[1] @@ -33,4 +34,6 @@ if __name__ == '__main__': for part in ['stl', 'dxf']: make_parts(target, part) render(target, part) + plateup(target, part) + views(target) diff --git a/scripts/openscad.py b/scripts/openscad.py index b33e547..3dded6f 100644 --- a/scripts/openscad.py +++ b/scripts/openscad.py @@ -24,11 +24,12 @@ from __future__ import print_function import subprocess, sys -def run(*args): +def run(*args, silent = False): cmd = ["openscad"] + list(args) - for arg in cmd: - print(arg, end=" ") - print() + if not silent: + for arg in cmd: + print(arg, end=" ") + print() with open("openscad.log", "w") as log: rc = subprocess.call(cmd, stdout = log, stderr = log) for line in open("openscad.log", "rt"): diff --git a/scripts/panels.py b/scripts/panels.py new file mode 100644 index 0000000..1ef83e6 --- /dev/null +++ b/scripts/panels.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# +# NopSCADlib Copyright Chris Palmer 2018 +# nop.head@gmail.com +# hydraraptor.blogspot.com +# +# This file is part of NopSCADlib. +# +# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with NopSCADlib. +# If not, see . +# +#! Panelises DXF files so they can be routed together by running scad files found in the ```panels``` directory. + +from __future__ import print_function +import sys + +from plateup import plateup + +if __name__ == '__main__': + if len(sys.argv) > 1: + target = sys.argv[1] + else: + target = None + plateup(target, 'dxf') diff --git a/scripts/plateup.py b/scripts/plateup.py new file mode 100644 index 0000000..54a44f6 --- /dev/null +++ b/scripts/plateup.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +# +# NopSCADlib Copyright Chris Palmer 2018 +# nop.head@gmail.com +# hydraraptor.blogspot.com +# +# This file is part of NopSCADlib. +# +# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with NopSCADlib. +# If not, see . +# + +from __future__ import print_function +import os +import openscad +import sys +import c14n_stl +from set_config import * +from deps import * +from shutil import copyfile + +source_dirs = { "stl" : "platters", "dxf" : "panels" } +target_dirs = { "stl" : "printed", "dxf" : "routed" } + +def plateup(target, part_type): + # + # Make the target directory + # + top_dir = set_config(target) + parts_dir = top_dir + part_type + 's' + target_dir = parts_dir + '/' + target_dirs[part_type] + source_dir = top_dir + source_dirs[part_type] + deps_dir = source_dir + "/deps" + if not os.path.isdir(source_dir): + return + if not os.path.isdir(target_dir): + os.makedirs(target_dir) + if not os.path.isdir(deps_dir): + os.makedirs(deps_dir) + # + # Decide which files to make + # + sources = [file for file in os.listdir(source_dir) if file.endswith('.scad')] + # + # Run OpenSCAD on the source files to make the targets + # + used = [] + for src in sources: + src_file = source_dir + '/' + src + part_file = target_dir + '/' + src[:-4] + part_type + dname = deps_name(deps_dir, src) + changed = check_deps(part_file, dname) + if changed: + print(changed) + openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file) + if part_type == 'stl': + c14n_stl.canonicalise(part_file) + log_name = 'openscad.log' + else: + log_name = 'openscad.echo' + openscad.run("-D$bom=1", "-o", log_name, src_file, silent = True) + # + # Add the files on the BOM to the used list + # + with open(log_name) as file: + for line in file.readlines(): + if line.startswith('ECHO: "~') and line.endswith('.' + part_type + '"\n'): + used.append(line[8:-2]) + # + # Copy file that are not included + # + copied = [] + for file in os.listdir(parts_dir): + if file.endswith('.' + part_type) and not file in used: + src = parts_dir + '/' + file + dst = target_dir + '/' + file + if mtime(src) > mtime(dst): + print("Copying %s to %s" % (src, dst)) + copyfile(src, dst) + copied.append(file) + # + # Remove any cruft + # + targets = [file[:-4] + part_type for file in sources] + for file in os.listdir(target_dir): + if file.endswith('.' + part_type): + if not file in targets and not file in copied: + print("Removing %s" % file) + os.remove(target_dir + '/' + file) diff --git a/scripts/platters.py b/scripts/platters.py new file mode 100644 index 0000000..4a59948 --- /dev/null +++ b/scripts/platters.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# +# NopSCADlib Copyright Chris Palmer 2018 +# nop.head@gmail.com +# hydraraptor.blogspot.com +# +# This file is part of NopSCADlib. +# +# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +# GNU General Public License as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with NopSCADlib. +# If not, see . +# +#! Generates build plates of STL files for efficient printing by running scad files found in the ```platters``` directory. + +from __future__ import print_function +import sys + +from plateup import plateup + +if __name__ == '__main__': + if len(sys.argv) > 1: + target = sys.argv[1] + else: + target = None + plateup(target, 'stl') diff --git a/scripts/readme.md b/scripts/readme.md index 23ff635..bd6e53a 100644 --- a/scripts/readme.md +++ b/scripts/readme.md @@ -12,6 +12,8 @@ They should work with both Python 2 and Python 3. | ```dxfs.py``` | Generates DXF files for all the routed parts listed on the BOM or a specified list. | | ```gallery.py``` | Finds projects and adds them to the gallery. | | ```make_all.py``` | Generates all the files for a project by running ```bom.py```, ```stls.py```, ```dxfs.py```, ```render.py``` and ```views.py```. | +| ```panels.py``` | Panelises DXF files so they can be routed together by running scad files found in the ```panels``` directory. | +| ```platters.py``` | Generates build plates of STL files for efficient printing by running scad files found in the ```platters``` directory. | | ```render.py``` | Renders STL and DXF files to PNG for inclusion in the build instructions. | | ```set_config.py``` | Sets the target configuration for multi-target projects that have variable configurations. | | ```stls.py``` | Generates STL files for all the printed parts listed on the BOM or a specified list. |