Merge branch 'master' into no-examples

This commit is contained in:
Michael Schwarz 2014-12-12 18:07:28 +01:00
commit 88fef813b0
21 changed files with 117 additions and 36 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
*.pyc
*.dxf
*.stl
*.d

View file

@ -1,8 +1,11 @@
INKSCAPE ?= inkscape
OPENSCAD ?= openscad
PYTHON ?= python2
PYTHON_CMD := PYTHONPATH="support:$$PYTHONPATH" $(PYTHON)
# Used by dxf_export/main.sh
export INKSCAPE
export INKSCAPE OPENSCAD
# Run generate_scad.sh to get the names of all OpenSCAD files that should be generated using that same script.
GENERATED_FILES := $(addsuffix .scad,$(basename $(shell ./generate_sources.sh)))
@ -13,34 +16,32 @@ GENERATED_SCAD_FILES := $(filter %.scad, $(GENERATED_FILES))
SVG_FILES := $(shell find src -name '*.svg') $(GENERATED_SVG_FILES)
# Only OpenSCAD files whose names do not start with `_' are compiled to STL.
SCAD_FILES := $(shell find src -name '*.scad') $(GENERATED_SCAD_FILES)
LIBRARY_SCAD_FILES := $(foreach i,$(SCAD_FILES),$(if $(filter _%,$(notdir $(i))),$(i)))
COMPILED_SCAD_FILES := $(filter-out $(LIBRARY_SCAD_FILES),$(SCAD_FILES))
COMPILED_SCAD_FILES := $(foreach i,$(shell find src -name '*.scad') $(GENERATED_SCAD_FILES),$(if $(filter-out _%,$(notdir $(i))),$(i)))
# Makefiles which are generated while compiling to record dependencies.
DEPENDENCY_FILES := $(patsubst %.scad,%.d,$(COMPILED_SCAD_FILES))
# All files that may be generated from the source files.
STL_FILES := $(patsubst %.scad,%.stl,$(COMPILED_SCAD_FILES))
DXF_FILES := $(patsubst %.svg,%.dxf,$(SVG_FILES))
# Everything. Also generates files which aren't compiled to anything else.
all: $(STL_FILES) $(GENERATED_FILES)
all: $(GENERATED_FILES) $(DXF_FILES) $(STL_FILES)
# Everything^-1.
clean:
rm -rf $(DXF_FILES) $(STL_FILES) $(GENERATED_FILES)
rm -rf $(GENERATED_FILES) $(DXF_FILES) $(STL_FILES) $(DEPENDENCY_FILES)
# Needs to be included after target all has been defined.
-include config.mk
# Assume that any compiled OpenSCAD file may depend on any non-compiled OpenSCAD file in the same directory.
$(foreach i,$(COMPILED_SCAD_FILES),$(eval $(i): $(filter $(dir $(i))%,$(LIBRARY_SCAD_FILES) $(DXF_FILES))))
# Include the local configuration file and the dependency files. Needs to be included after the `all' target has been defined.
-include config.mk $(DEPENDENCY_FILES)
# Rule to convert an SVG file to a DXF file.
%.dxf: %.svg
python2 dxf_export $< $@
$(PYTHON_CMD) -m dxf_export $< $@
# Rule to compile an OpenSCAD file to an STL file.
%.stl: %.scad
$(OPENSCAD) -o $@ $<
# Rule to compile an OpenSCAD file to an STL file. We require all DXF files to exist before an OpenSCAD file can be used to generate an STL file. Additional dependencies are read from the included makefiles generated during compiling.
%.stl: %.scad | $(DXF_FILES)
$(PYTHON_CMD) -m openscad $< $@ $*.d
# Rule for automaticlaly generated OpenSCAD files.
$(GENERATED_FILES): generate_sources.sh

2
src/_settings.scad Normal file
View file

@ -0,0 +1,2 @@
plate_height = 2;
struts_height = 1;

6
src/example_1.scad Normal file
View file

@ -0,0 +1,6 @@
include <_settings.scad>
render(convexity = 10) {
linear_extrude(plate_height)
import("example.dxf", layer = "text");
}

14
src/example_2.scad Normal file
View file

@ -0,0 +1,14 @@
include <_settings.scad>
render(convexity = 10) {
union() {
linear_extrude(plate_height)
difference() {
import("example.dxf", layer = "base");
import("example.dxf", layer = "text");
}
linear_extrude(struts_height)
import("example.dxf", layer = "struts");
}
}

View file

View file

@ -1,15 +1,6 @@
import sys, os, xml.etree.ElementTree, subprocess, tempfile, contextlib, shutil
import better_dxf_outlines
@contextlib.contextmanager
def TemporaryDirectory():
dir = tempfile.mkdtemp()
try:
yield dir
finally:
shutil.rmtree(dir)
import sys, os, xml.etree.ElementTree, shutil
from lib import util
from . import better_dxf_outlines
def _export_dxf(in_path, out_path):
@ -28,13 +19,6 @@ def _get_inkscape_layer_count(svg_path):
return len(layers)
def _command(args):
process = subprocess.Popen(args)
process.wait()
assert not process.returncode
def _inkscape(svg_path, verbs):
def iter_args():
yield os.environ['INKSCAPE']
@ -45,7 +29,7 @@ def _inkscape(svg_path, verbs):
yield svg_path
_command(list(iter_args()))
util.command(list(iter_args()))
def _unfuck_svg_document(temp_svg_path):
@ -82,7 +66,7 @@ def _unfuck_svg_document(temp_svg_path):
def main(in_path, out_path):
with TemporaryDirectory() as temp_dir:
with util.TemporaryDirectory() as temp_dir:
temp_svg_path = os.path.join(temp_dir, 'temp.svg')
shutil.copyfile(in_path, temp_svg_path)

0
support/lib/__init__.py Normal file
View file

36
support/lib/util.py Normal file
View file

@ -0,0 +1,36 @@
import contextlib, subprocess, tempfile, shutil, re, os
@contextlib.contextmanager
def TemporaryDirectory():
dir = tempfile.mkdtemp()
try:
yield dir
finally:
shutil.rmtree(dir)
def command(args):
process = subprocess.Popen(args)
process.wait()
assert not process.returncode
def bash_escape_string(string):
return "'{}'".format(re.sub("'", "'\"'\"'", string))
def write_file(path, data):
temp_path = path + '~'
with open(temp_path, 'wb') as file:
file.write(data)
os.rename(temp_path, path)
def read_file(path):
with open(path, 'rb') as file:
return file.read()

View file

View file

@ -0,0 +1,37 @@
import os, sys
from lib import util
def _openscad(in_path, out_path, deps_path):
util.command([os.environ['OPENSCAD'], '-o', out_path, '-d', deps_path, in_path])
def _write_dependencies(path, target, dependencies):
util.write_file(path, '{}: {}\n'.format(target, ' '.join(dependencies)).encode())
def main(in_path, out_path, deps_path):
cwd = os.getcwd()
def relpath(path):
return os.path.relpath(path, cwd)
with util.TemporaryDirectory() as temp_dir:
temp_deps_path = os.path.join(temp_dir, 'deps')
temp_mk_path = os.path.join(temp_dir, 'mk')
temp_files_path = os.path.join(temp_dir, 'files')
_openscad(in_path, out_path, temp_deps_path)
mk_content = '%:; echo "$@" >> {}'.format(util.bash_escape_string(temp_files_path))
util.write_file(temp_mk_path, mk_content.encode())
util.command(['make', '-s', '-B', '-f', temp_mk_path, '-f', temp_deps_path])
deps = set(map(relpath, util.read_file(temp_files_path).decode().splitlines()))
ignored_files = set(map(relpath, [temp_deps_path, temp_mk_path, in_path, out_path]))
_write_dependencies(deps_path, relpath(out_path), deps - ignored_files)
main(*sys.argv[1:])