`Implement new geometry node "Geometry As Code"
. WORK IN PROGRESS: USABLE, BUT NOT POLISHED
. Demo of the feature: https://www.youtube.com/watch?v=aZq8ZlmqHJo
. Who did this:
dev name: Emmanuel Mogenet
email: emogenet@gmail.com
blender chat: @Emmanuel-Mogenet
github: https://github.com/emogenet
LinkedIn: https://www.linkedin.com/in/emmanuel-mogenet-1010282
. Who will maintain this in the future: see above
. User level feature:
Category: Nodes:Geometry:Mesh Primitive:Geometry As Code
TL;DR:
- A new mesh primitive geometry node that reads code from either
an internal text block or an external file.
- When node is polled, it executes the code to produce a mesh
- Integrates with the native Blender text editor.
. Advantage of the feature:
- fully parametric workflow for hard surfaces/CAD/archi meshes
- new OpenSCAD objects can be created entirely within Blender
- use large existing body of SCAD models on the net directly
- once polished, likely to attract a new community of users
- good fit for the non-destructive workflow of geometry nodes
- does not overlap (AFAICT) with existing Blender features
- example of things now directly usable in Blender:
https://www.thingiverse.com/thing:1604369
https://github.com/KitWallace/openscad
. Motivations:
- OpenSCAD is a nice tool / paradigm, but the UI is very limited
In particular, 3D navigation, rendering, taking measurements,
inspecting the object, etc.. is vastly inferior to what Blender
has to offer. I want to be able to build new OpenSCAD models
without ever having to leave the Blender UI.
- Fully parametric modeling within Blender, where large categories
of hard surface type objects can be created almost instantly
by only changing a few parameters in a piece of code.
- Being able to directly re-use in Blender the large number of
existing OpenSCAD models and libraries available on the net.
- For a certain category of people (coders) and a certain category
of models (hard surface, Archi, CAD-like), writing code to
describe the geometry of an object is what comes most natural and
what is most efficient. In particular it can be used to generate
very complex geometry with very little “manual”
(read: point-and-click) work.
- The traditional Blender user community (SFX folks, artists) can
also benefit from the feature in the same way - say - an OSL shader
can be created by a coder type person, integrated in the
production pipeline, and used and tweaked by artists to produce
the desired effect.
. Quality checklist
. backward compatible with existing .blend files: yes (AFAICT)
. naming of UI level feature consistent: I believe it is
. can it be made more efficient / easier: yes, planned
. negative impact on performance: not on any existing feature
. refactoring required: probably not, unless there is generic LRU
cache code somewhere in Blender that can be re-used
. comments: yes
. clang-format: yes, all changes
. automated test still pass: yes
. Architecture / code changes
- Bulk of the work lives inside a new geometry node type (one file
in source/blender/nodes/geometry/nodes)
- Some mildly intrusive changes have been made to the text block
and text editor code, notably an "error" field has been added
to the TextLine structure.
- While OpenSCAD (https://openscad.org/) is the main engine right
now, the feature has been designed to be mostly agnostic to the
underlying code-to-geometry rendering engine.
- Other engines (e.g. CadQuery) or languages (e.g. SolidPython) can
and likely will be added in the future.
- The way I got the node to talk to the text editors when it
executes is not ideal (calls WM_main_add_notifier which accesses
a global variable)
- The code changes fall in two categories that are almost orthogonal
- code added to support the new node type
- code added to add features to the text editor
This is refelected in the commit history.
- Two colors were added to the themes (text line in err / warning)
- There aren't any tests yet
- Inspiration for the work:
- Shader Script Node
- Ico Sphere Geom Node Mesh primitive
- Run python script in editor feature
- The new node currently executes an external program to compute
the mesh from the code. This will likely change in the future.
- The external binary is executed using a direct call to the
embedded python interpreter from C++ (avoids portability
headaches of fine-grained execution of an external binary:
python has solved making this platform-agnostic).
- Haven't tested the new feature on windows or OSX yet, will
do this in next iteration.
- Caching of computed geometry is totally naive right now, needs
to get better.
- Unclear what is the "clean/elegant" way of Interacting with
the Blender UI directly from a geometry node.
. Limitations / downsides
- Main limitation right now is initial evaluation speed when the
model gets complex / hirez
- Partly addressed by caching, but not ideal especially in the
following cases:
- On loading the .blend file, the model may take very long to
build, which freezes the load. I plan to address this in short
order by caching the mesh inside the .blend file.
- When in the code->run->view->code->run->view->... modeling
loop, we do not have (yet) the OpenGL CSG rendering facility
that standalone OpenSCAD offers, we instead compute a full
model, which is expensive. I plan to address this, but I
anticipate that it will be tricky.
- When an evaluation takes too long, there is no way to interrupt it
this will be addressed in the future.
- This feature drags in a large dependency: the geometry rendering
engine, currently OpenSCAD, and as an external binary.
. Planned additional changes
. Short term
. Add tests
. Make this an add-on
. Make computation interruptible
. Add computation progress indicator
. Add "load in editor" button on node
. Auto-recompute when code file changes on disk
. Better caching, including saving cached objects to .blend
. Better error message feedback in the text editor (tooltip)
. Add a proper OpenSCAD syntax highlighter in the text editor
. Text editor default "Load File" filter needs to learn about .scad
. Medium term
. Import OpenSCAD colors
. Add OpenL CSG rendering mode for speed
. Support OpenSCAD "rendered debug" operators such as # and !
. Extract parametric leaves of the OpenSCAD AST to expose as
sockets and/or parameters
. Do external geometry computation asynchronously with ersatz model
. Add sockets / params to node from code, like the OSL node does
and with possibility to sync params back to the code text
. Long term
. Add support for other geom-as-code languages: SolidPython, CadQuery
. Ideas to explore:
. Convert OpenSCAD CSG tree to actual Blender tree of geometry nodes`