OpenSCAD Import System: A Proposal
Having recently acquired a 3D printer, I've been diving in to 3D modeling. While Fusion 360 seems to be the leader in that area generally, I've fallen for OpenSCAD. I appreciate its use of code as the primary (read "only") design environment because it mirrors the way I tend to think about problems. This has the added benefits of making parametrized models being a core feature instead of an afterthought, and readable diffs for files under version control with git.
Over the past few days I've been working hard at reaching competency with OpenSCAD and have come to the point where I feel like I'm able to offer an informed perspective on some of its strengths and limitations. The biggest "rough edge" I've run into thus far is dealing with imports.
Note that this is very much a first draft, and that at this point is really more of a "suggestion" than a "proposal". I'm mostly interested in getting the idea down in writing so it can be discussed if anyone else is interested.
Current State & Limitations
OpenSCAD has two provisions for dependency management:
include
and use
. include
includes the entirety of the referenced
file, while use
brings in only modules and functions defined in the global
context of the target file.
use
is the workhorse here, as it allows you to keep your context as clean as
possible while pulling in only the things you need from elsewhere. In contrast,
where include
really shines is in dependency injection: because the contents
of the referenced file is bodily included, it can be used to define a set of
variables to be referened in the including context.
The main limitation of use
is that it brings all modules and functions
from the included context into the including context. For complex libraries,
this could mean quite a large number of objects! This seems to be handled by
others by breaking down libraries into a number of files, each with a narrow
purpose.
Proposal for Improvement
In short, I'd like more granular control over what gets imported. I propose two
new builtins, from
and import
, inspired largely by Python.
import
use
should be deprecated in favor of a new builtin, import
, with the
following behavior:
The .scad
extension should be inferred for the argument if necessary. For
the statement import <foo>
, resolution should occur in the following order:
- the file
foo
in the folder in which the design was opened - the file
foo.scad
in the folder in which the design was opened - the file
foo
in the OpenSCAD library folder - the file
foo.scad
in the OpenSCAD library folder
A means of explicitly including or excluding modules and functions from
import
should be implemented. This could be as simple as ignoring those
beginning with and underscore (i.e., importing only those functions and modules
matching the regex ^[^_].*$
). Alternatively, special variables could be used
to define inclusion/exclusion:
To include only foo
and bar
:
Functionally equivalent would be to exclude baz
::
from
from
effectively be the extended form of import
, allowing the inclusion
of only explicitly specified modules and funtions from the included context.
Given my_library.scad
:
to include only foo
:
to include both foo
and bar
:
Notably, using from
should ignore the usage of the special variables
$export
and $private
described in the previous section. Modules and
functions that are either not included or explicitly excluded from the
import
builtin should be accessible via from
.