# buildSCAD
An interpreter for OpenSCAD that emits OCC objects, wrapped with build123d.
## Rationale
Today's 3D programs can import STEP models, thus can deal with "real"
curves and solids instead of mesh approximations.
Unfortunately, the CGAL 3D package used by OpenSCAD is mesh-based. Owch.
On the other hand, OpenSCAD is somewhat widely used for creating
parameterized models algorithmically. Sites like Thingiverse or Printables
contain quite a few models built with it.
This package translates OpenSCAD to "real" 3D models.
## Approach
The OpenSCAD code is parsed into a syntax tree and interpreted on the fly
when a "module" (in OpenSCAD terms) is called.
The result is an OCC Solid (or sketch if 2D), wrapped with build123d,
and can be used just like any other object.
### Functional replacements
If a module cannot be implemented in build123d/OCC, most likely because it
uses ``hull`` or ``minkowsky``, often the most expedient fix is to write a
replacement in Python.
To use this feature, simply add a function with the desired name to the
environment you pass to ``process``, or pre-load a Python file.
In order to read global variables, functions may access the current
environment via the contextvar ``buildscad.env``.
## Limitations
This tool started off as a proof of concept. A lot of methods and some
support functions are not implemented yet, though the grammar itself
should be complete.
Variables whose name start with a '$' are usable. However, they cannot be
passed to functions as keywords. Instead, $-prefixed keywords get passed to
called functions in the environment so that functions implemented in Python
don't have to deal with them.
Corollary: Don't even think of creating a six-sided polygon by using
``circle(r=2, $fn=6``) with this code.
Speed could probably be improved; on the other hand, let's face it,
OpenSCAD's mesh rendering can be slow as molasses too.
The ``minkowski`` and ``hull`` operators don't exist in build123d.
Implementing them is *way* out of scope for this project.
``undef`` is evaluated as ``None``.
## Differences to OpenSCAD
### Evaluation Order
Our parser delays evaluation of variables until they're needed.
In other words, this …
::
bar = foo(123);
function foo(x) = x;
… works just fine.
### Variable handling
Unknown variables (i.e. those that are never assigned to) cause an error.
As in OpenSCAD, unfilled parameters are "undef", i.e.
function xx(a,b) = b;
echo(xx(1));
does emit "ECHO: undef".
### Value redefinition
Updating a variable will emit a warning but not change the value.
### Included Files
Variables declared in include files can be overridden in the main code, as in OpenSCAD.
However, values from included files don't filter back to the main code.
### Invalid Values
OpenSCAD tends to return `undef` whenever it doesn't understand something,
which typically results in any numer of follow-up warnings.
We don't do that. Errors raise exceptions.
## Testing
The subdirectory ``tests/models`` includes various OpenSCAD files, with
accompanying Python code.
The models in these files are built in three ways:
* directly by OpenSCAD
* by emulating OpenSCAD
* by Python code
The test builder calls the ``work`` function (Python) / module (OpenSCAD).
If that doesn't exist, top-level objects (OpenSCAD) / variables (Python) are used.
The following special constants are recognized:
* tolerance
The maximum difference (volume) between the various models. The default
is 0.001 but anything that depends on OpenSCAD's ``$fn`` probably
requires looser constraints.
* volume
The volume (in mm³) that the model is supposed to have.
* skip
Skip this test when auto-running.
* no\_add
When set to `True`, do not add the various volumes. This is a workaround
for an OCC bug which causes an endless loop.
Setting this flag causes this testcase to only compare volumes and bounding
boxes, which is not as accurate.
* trace
Log (some) calls to build123.
If the Python part only contains constants, it must declare `work=None`.
Otherwise the test code assumes that you wrote e.g. ``Sphere(42)`` without
assigning the result to anything, and thus refuses to accept the testcase.
If you want to test a functional result against OpenSCAD, the best way is
to create a `Box(result,1,1)` object.
### Viewing tests
``examples/test_viewer.py`` can be opened with CQ-Editor to compare models
visually.
### Test Traces
If the testcase sets ``tracing=True``, the actual `build123d` calls will be
logged and the STL file from OpenSCAD will not be deleted.
This is mainly useful for generating a test case for bug reports that
doesn't depend on this code.
Trace support is still somewhat incomplete.
## TODO
To fix:
* linear\_extrude with scaling
* linear\_extrude with scaling and twist
* polyhedrons
* use/include from a library (via envvar OPENSCADPATH)
Implement a lot of functions.
Improve error reporting.
Test working with 2D.
An option to generate a build123d script instead of the actual objects would
be nice.
Raw data
{
"_id": null,
"home_page": null,
"name": "buildscad",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "buildscad, cadquery, build123d",
"author": null,
"author_email": "Matthias Urlichs <matthias@urlichs.de>",
"download_url": "https://files.pythonhosted.org/packages/77/62/fbc4d8f8ef8953cd267182ec726dd31977831c145eadab9c7e77e1023742/buildscad-0.4.1.tar.gz",
"platform": null,
"description": "# buildSCAD\n\nAn interpreter for OpenSCAD that emits OCC objects, wrapped with build123d.\n\n\n## Rationale\n\nToday's 3D programs can import STEP models, thus can deal with \"real\"\ncurves and solids instead of mesh approximations.\n\nUnfortunately, the CGAL 3D package used by OpenSCAD is mesh-based. Owch.\n\nOn the other hand, OpenSCAD is somewhat widely used for creating\nparameterized models algorithmically. Sites like Thingiverse or Printables\ncontain quite a few models built with it.\n\nThis package translates OpenSCAD to \"real\" 3D models.\n\n\n## Approach\n\nThe OpenSCAD code is parsed into a syntax tree and interpreted on the fly\nwhen a \"module\" (in OpenSCAD terms) is called.\n\nThe result is an OCC Solid (or sketch if 2D), wrapped with build123d,\nand can be used just like any other object.\n\n\n### Functional replacements\n\nIf a module cannot be implemented in build123d/OCC, most likely because it\nuses ``hull`` or ``minkowsky``, often the most expedient fix is to write a\nreplacement in Python.\n\nTo use this feature, simply add a function with the desired name to the\nenvironment you pass to ``process``, or pre-load a Python file.\n\nIn order to read global variables, functions may access the current\nenvironment via the contextvar ``buildscad.env``.\n\n## Limitations\n\nThis tool started off as a proof of concept. A lot of methods and some\nsupport functions are not implemented yet, though the grammar itself\nshould be complete.\n\nVariables whose name start with a '$' are usable. However, they cannot be\npassed to functions as keywords. Instead, $-prefixed keywords get passed to\ncalled functions in the environment so that functions implemented in Python\ndon't have to deal with them.\n\nCorollary: Don't even think of creating a six-sided polygon by using\n``circle(r=2, $fn=6``) with this code.\n\nSpeed could probably be improved; on the other hand, let's face it,\nOpenSCAD's mesh rendering can be slow as molasses too.\n\nThe ``minkowski`` and ``hull`` operators don't exist in build123d.\nImplementing them is *way* out of scope for this project.\n\n``undef`` is evaluated as ``None``.\n\n\n## Differences to OpenSCAD\n\n### Evaluation Order\n\nOur parser delays evaluation of variables until they're needed.\n\nIn other words, this \u2026\n\n::\n\tbar = foo(123);\n\tfunction foo(x) = x;\n\n\u2026 works just fine.\n\n\n### Variable handling\n\nUnknown variables (i.e. those that are never assigned to) cause an error.\nAs in OpenSCAD, unfilled parameters are \"undef\", i.e.\n\n\tfunction xx(a,b) = b;\n\techo(xx(1));\n\ndoes emit \"ECHO: undef\".\n\n\n### Value redefinition\n\nUpdating a variable will emit a warning but not change the value.\n\n\n### Included Files\n\nVariables declared in include files can be overridden in the main code, as in OpenSCAD.\nHowever, values from included files don't filter back to the main code.\n\n### Invalid Values\n\nOpenSCAD tends to return `undef` whenever it doesn't understand something,\nwhich typically results in any numer of follow-up warnings.\n\nWe don't do that. Errors raise exceptions.\n\n## Testing\n\nThe subdirectory ``tests/models`` includes various OpenSCAD files, with\naccompanying Python code.\n\nThe models in these files are built in three ways:\n\n* directly by OpenSCAD\n* by emulating OpenSCAD\n* by Python code\n\nThe test builder calls the ``work`` function (Python) / module (OpenSCAD).\nIf that doesn't exist, top-level objects (OpenSCAD) / variables (Python) are used.\n\nThe following special constants are recognized:\n\n* tolerance\n\n The maximum difference (volume) between the various models. The default\n is 0.001 but anything that depends on OpenSCAD's ``$fn`` probably\n requires looser constraints.\n\n* volume\n\n The volume (in mm\u00b3) that the model is supposed to have.\n\n* skip\n\n Skip this test when auto-running.\n\n* no\\_add\n\n When set to `True`, do not add the various volumes. This is a workaround\n for an OCC bug which causes an endless loop.\n\n Setting this flag causes this testcase to only compare volumes and bounding\n boxes, which is not as accurate.\n\n* trace\n\n Log (some) calls to build123.\n\nIf the Python part only contains constants, it must declare `work=None`.\nOtherwise the test code assumes that you wrote e.g. ``Sphere(42)`` without\nassigning the result to anything, and thus refuses to accept the testcase.\n\nIf you want to test a functional result against OpenSCAD, the best way is\nto create a `Box(result,1,1)` object.\n\n\n### Viewing tests\n\n``examples/test_viewer.py`` can be opened with CQ-Editor to compare models\nvisually.\n\n### Test Traces\n\nIf the testcase sets ``tracing=True``, the actual `build123d` calls will be\nlogged and the STL file from OpenSCAD will not be deleted.\n\nThis is mainly useful for generating a test case for bug reports that\ndoesn't depend on this code.\n\nTrace support is still somewhat incomplete.\n\n## TODO\n\nTo fix:\n* linear\\_extrude with scaling\n* linear\\_extrude with scaling and twist\n* polyhedrons\n* use/include from a library (via envvar OPENSCADPATH)\n\nImplement a lot of functions.\n\nImprove error reporting.\n\nTest working with 2D.\n\nAn option to generate a build123d script instead of the actual objects would\nbe nice.\n",
"bugtrack_url": null,
"license": "All files in this repository are are licensed under the LGPL V3, as published by the FSF at https://www.gnu.org/licenses/lgpl-3.0.html . In addition to the LGPL's terms, the author(s) respectfully ask all users of this code to contribute any bug fixes or enhancements. Thank you. Copyright \u00a9 2024 Matthias Urlichs <matthias@urlichs.de> ",
"summary": "An interpreter for OpenSCAD that renders to build123d objects",
"version": "0.4.1",
"project_urls": {
"homepage": "https://github.org/smurfix/buildscad",
"repository": "https://github.com/smurfix/buildscad.git"
},
"split_keywords": [
"buildscad",
" cadquery",
" build123d"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "abec67d394b4960854587c9785c1b6ee8605c509a4ea08b3dcb28aeec93f3763",
"md5": "233f780ca1e170a834ceb0107b2daefa",
"sha256": "9d887c535bb07e729c91341943c35bfb477d49ce3bd6f5a8b3a4bfa0c0238fd7"
},
"downloads": -1,
"filename": "buildscad-0.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "233f780ca1e170a834ceb0107b2daefa",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 26264,
"upload_time": "2024-10-29T16:11:47",
"upload_time_iso_8601": "2024-10-29T16:11:47.215264Z",
"url": "https://files.pythonhosted.org/packages/ab/ec/67d394b4960854587c9785c1b6ee8605c509a4ea08b3dcb28aeec93f3763/buildscad-0.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "7762fbc4d8f8ef8953cd267182ec726dd31977831c145eadab9c7e77e1023742",
"md5": "a3ad6cb4ef7626fb1cc07e95a454d7ee",
"sha256": "36101fc36fafcd76df725fb811f7591db2836fb8e034424bd761160e7736ac57"
},
"downloads": -1,
"filename": "buildscad-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "a3ad6cb4ef7626fb1cc07e95a454d7ee",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 30998,
"upload_time": "2024-10-29T16:11:48",
"upload_time_iso_8601": "2024-10-29T16:11:48.738062Z",
"url": "https://files.pythonhosted.org/packages/77/62/fbc4d8f8ef8953cd267182ec726dd31977831c145eadab9c7e77e1023742/buildscad-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-29 16:11:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "smurfix",
"github_project": "buildscad",
"github_not_found": true,
"lcname": "buildscad"
}