From 8d37e124e2887c8f0dd5de72b879ee1fc56db125 Mon Sep 17 00:00:00 2001 From: jeff <1105041+jeff-dh@users.noreply.github.com> Date: Wed, 2 Jun 2021 18:06:24 +0200 Subject: [PATCH] added ImplicitCAD support (#134) --- solid/config.py | 6 ++- solid/core/builtins.implicit | 33 ++++++++++++++++ solid/core/scad_render.py | 10 +++-- solid/examples/14-implicitCAD.py | 62 ++++++++++++++++++++++++++++++ solid/extensions/access_syntax.py | 9 +++-- solid/extensions/bosl2/__init__.py | 4 ++ 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 solid/core/builtins.implicit create mode 100644 solid/examples/14-implicitCAD.py diff --git a/solid/config.py b/solid/config.py index ed9963ef..7d47f3b1 100644 --- a/solid/config.py +++ b/solid/config.py @@ -2,10 +2,14 @@ from pathlib import Path import os import platform +import sys class Config: def __init__(self): - self.builtins_file = Path(__file__).absolute().parent / "core/builtins.openscad" + self.use_implicit_builtins = "--implicit" in sys.argv + + builtins_suffix = ".openscad" if not self.use_implicit_builtins else ".implicit" + self.builtins_file = Path(__file__).absolute().parent / ("core/builtins" + builtins_suffix) self.enable_pickle_cache = True self.pickle_cache_dir = self.get_pickle_cache_dir() diff --git a/solid/core/builtins.implicit b/solid/core/builtins.implicit new file mode 100644 index 00000000..1308ee90 --- /dev/null +++ b/solid/core/builtins.implicit @@ -0,0 +1,33 @@ +module sphere(r=default, d=default, $fn=default); +module cube(size=default, center=default, r=default); +module square(size=default, center=default, r=default); +module cylinder(r=default, h=default, r1=default, r2=default, + $fn=default, center=default); +module circle(r=default, $fn=default); +module polygon(points, paths=default, r=default); + +module union(r=default); +module difference(r=default); +module intersection(r=default); + +module translate(v); +module scale(v); +module rotate(a=default, v=default); + +module linear_extrude(height=default, + center=default, + twist=default, + scale=default, + translate=default, + r=default); + +module pack(size, sep=default); +module shell(w); + +module rotate_extrude(angle=default, + r=default, + translate=default, + rotate=default); + +module unit(unit); + diff --git a/solid/core/scad_render.py b/solid/core/scad_render.py index 6f90d097..4edd2df6 100644 --- a/solid/core/scad_render.py +++ b/solid/core/scad_render.py @@ -48,14 +48,16 @@ def _write_to_file(out_string, filename=None, outdir=''): outfile = filename if not outfile: + suffix = ".scad" if not config.use_implicit_builtins else ".escad" + #try to get the filename of the calling module import __main__ if hasattr(__main__, "__file__"): #not called from a terminal calling_file = Path(__main__.__file__).absolute() - outfile = calling_file.with_suffix(".scad") + outfile = calling_file.with_suffix(suffix) else: - outfile = "expsolid_out.scad" + outfile = "expsolid_out" + suffix outpath = Path(outdir) if not outpath.exists(): @@ -74,9 +76,9 @@ def get_include_string(): continue if v[1]: - strings.append(f"use <{k}>") + strings.append(f"use <{k}>;") else: - strings.append(f"include <{k}>") + strings.append(f"include <{k}>;") s = "\n".join(strings) s += "\n\n" if s else '' diff --git a/solid/examples/14-implicitCAD.py b/solid/examples/14-implicitCAD.py new file mode 100644 index 00000000..3472b97a --- /dev/null +++ b/solid/examples/14-implicitCAD.py @@ -0,0 +1,62 @@ +# ====================================================== +# = add relative path to the solid package to sys.path = +# ====================================================== +import sys +from pathlib import Path +solidPath = Path(__file__).absolute().parent.parent.parent.as_posix() +sys.path.append(solidPath) +#================================================== + +# run extopenscad with -r 2 to get proper results: +# extopenscad -r 2 examples/14-implicitCAD.scad + +# this is the same example as 06-functions.py but with nice smooth implicitCAD +# roundings.... + +# this is how you activate the "implicit mode" of ExpSolid +# I couldn't figure out a nicer way to set a parameter which can be accessed +# during the import routine of exp_solid +# +# alternatively you can call the whole script with the --implicit parameter: +# python3 examples/14-implicitCAD.py --implicit + +import sys +sys.argv.append("--implicit") + +from solid import * + +def wheel(): + return cylinder(r=35, h=15, center=True).rotate(0, 90, 0) + +def axle(): + a = cylinder(r=10, h=130, center=True).\ + rotate(0, 90, 0) + + w1 = wheel().left(67) + w2 = wheel().right(67) + + return w1 + w2 + a + +def torso(): + bottom = cube(100, 250, 50, center=True, r=10) + top = cube(80, 100, 60, center=True, r=10) + + window_cube = cube(200, 55 ,50, center=True, r=10).down(10) + top = difference(r=10) ( + top, + (union(r=10) (window_cube, window_cube.rotate(0, 0, 90))) + ) + + return union(r=10)(bottom, top.up(50)) + +def car(): + t = torso() + + front_axle = axle().down(20).back(80) + + rear_axle = front_axle.forward(160) + + return union(r=3)(t, front_axle, rear_axle) + +car().save_as_scad() + diff --git a/solid/extensions/access_syntax.py b/solid/extensions/access_syntax.py index c75eaa1c..80dcd05d 100644 --- a/solid/extensions/access_syntax.py +++ b/solid/extensions/access_syntax.py @@ -2,6 +2,7 @@ from . import convenience from ..core.utils import escape_openscad_identifier from ..core.object_base import ObjectBase +from ..config import config __nothing__ = None @@ -15,9 +16,11 @@ """ #builtin transformations -_cascading_builtins = ("union difference intersection intersection_for translate " +\ - "scale rotate mirror resize color offset hull render " +\ - "linear_extrude rotate_extrude projection surface").split(" ") +_cascading_builtins = ("union difference intersection translate " +\ + "scale rotate linear_extrude rotate_extrude").split(" ") +if not config.use_implicit_builtins: + _cascading_builtins += ("intersection_for mirror resize color offset hull render " +\ + "projection surface").split(" ") def add_builtin_to_object_base(name): #get the builtin diff --git a/solid/extensions/bosl2/__init__.py b/solid/extensions/bosl2/__init__.py index 51fe0dfa..4be36fc6 100644 --- a/solid/extensions/bosl2/__init__.py +++ b/solid/extensions/bosl2/__init__.py @@ -1,3 +1,7 @@ +from ... import config +if config.use_implicit_builtins: + raise Exception("ExpSolid: unfortunately ImplicitCAD can't handle bosl2...") + #load the libs from std from . import std from . import constants