EzyCad embeds script consoles that drive the live document through a public Python-first API under ezy. Lua mirrors the same namespaces (required for WebAssembly). Remote --listen clients use the same Python tree.
Use ezy.help() (or help()) in a console for a short built-in summary.
| Lua | Python | |
|---|---|---|
| Desktop (Windows) | Always (built-in Lua library) | Only if the app was built with Python enabled (EZYCAD_HAVE_PYTHON in CMake; needs Python development libraries). If the View -> Python Console item appears and works, your build includes it. |
| WebAssembly | Yes | No (not shipped in the browser build). |
- View -> Lua Console - Toggles the Lua console and script editor tabs.
- View -> Python Console - Same layout for Python when the feature is compiled in.
Visibility is remembered with other panes (see usage.md -> Help and Settings).
- Output / history - Results and errors from executed lines.
- Input line - Enter a fragment and run it (same as a one-off at the interactive prompt).
- Script tabs - Files under
res/scripts/lua(*.lua) orres/scripts/python(*.py) are loaded as editable buffers; Lua scripts are also run on startup so you can define helpers (seebasic.lua/basic.py).
Paths are relative to the app working directory on desktop; on WASM, Lua scripts are under the preloaded /res/scripts/lua tree.
Canonical surface (also available in Lua with the same names):
ezy.log / ezy.msg / ezy.help / ezy.get_mode / ezy.set_mode
ezy.save_occt_view_settings / ezy.occt_view_settings_json
ezy.view.*
ezy.view.curr_sketch.* # same object as ezy.sketch
ezy.Shp
Aliases (compatibility): global view is ezy.view; global Shp is ezy.Shp; help() is ezy.help(). ezy.view.curr_sketch is the same object as ezy.sketch. Flat view.add_sketch / add_edge / finish_sketch_edges forward to view.curr_sketch.*.
print is redirected to ezy.log in both consoles.
| Method | Purpose |
|---|---|
ezy.log(msg) |
Print to the console and the main Log pane |
ezy.msg(text [, kind]) |
Status toast and Log; optional kind (see below) |
ezy.get_mode() |
Current application mode name (string) |
ezy.set_mode(name) |
Switch mode by name (Design_inspection, Design_move, Design_shaft_align, Workbench_move, Scale, ...). Retired names Normal / Sketch_inspection_mode / Move (Design move) / Rotate (Design rotate) / Workbench_scale / Shape_shaft_align (Design shaft align) still work. |
ezy.save_occt_view_settings() |
Write settings JSON (including view colors) |
ezy.occt_view_settings_json() |
Settings JSON string |
ezy.help() |
Print binding summary |
Optional kind for ezy.msg is success, info (default), constraint, warning, or error. Unknown names use info. Toast color follows the kind.
| Method | Purpose |
|---|---|
ezy.view.sketch_count() |
Number of sketches |
ezy.view.shape_count() |
Number of 3D shapes |
ezy.view.add_box(ox, oy, oz, w, l, h) |
Add a box; returns Shp |
ezy.view.add_sphere(ox, oy, oz, r) |
Add a sphere; returns Shp |
ezy.view.fuse(s1, s2, ...) |
Boolean union of two or more Shp; returns Shp |
ezy.view.cut(body, tool, ...) |
Subtract tools from body; returns Shp |
ezy.view.common(s1, s2, ...) |
Boolean intersection; returns Shp |
ezy.view.delete(s1, ...) |
Remove one or more Shp from the document |
ezy.view.get_shape(i) |
Shape by 0-based index (raises IndexError) |
ezy.view.get_selected() |
List of selected document Shp (empty if none) |
ezy.view.set_selected(s1, ...) |
Replace the selection; accepts a list; no args clears |
ezy.view.get_selected_indices() |
0-based indices of selected document shapes |
ezy.view.get_camera() |
Camera vectors: eye, center, up |
ezy.view.set_camera(ex, ey, ez, cx, cy, cz, ux, uy, uz) |
Set camera vectors |
ezy.view.curr_sketch |
Current sketch API (same as ezy.sketch) |
Indices are 0-based in Python. Prefer view.curr_sketch for inspection; ezy.sketch is the same object and also used for creation helpers.
| Method | Purpose |
|---|---|
view.curr_sketch.name() |
Name of the current sketch (curr_name() alias on ezy.sketch) |
view.curr_sketch.node_count() / view.curr_sketch.node(i) |
Read nodes (x, y) on the current sketch plane |
view.curr_sketch.dim_count() / view.curr_sketch.dim(i) |
Read length dimensions (distance in project display units) |
view.curr_sketch.add(plane, offset, base_name) |
New sketch on XY, XZ, or YZ (offset in project display units; optional name) |
view.curr_sketch.add_edge(x1, y1, x2, y2) |
Add a linear edge to the current sketch |
view.curr_sketch.finish_edges() |
Rebuild closed-face topology after bulk edge import |
| Method | Purpose |
|---|---|
s.name() / s.set_name(s) |
Shape name |
s.visible() / s.set_visible(b) |
Visibility |
Lua exposes the same ezy / ezy.view / ezy.sketch layout. Differences:
| Topic | Lua | Python |
|---|---|---|
| Shape index | 1-based; out of range returns nil |
0-based; raises IndexError |
| Selected idx | 1-based in get_selected_indices() |
0-based |
| Sketch index | 1-based for node / dim |
0-based |
| Methods | Prefer s:name() style on userdata |
s.name() |
| WASM | Available | Not built |
res/scripts/python/basic.py-dump_view()usingezy.view(and a legacyviewalias line).res/scripts/python/sierpinski.py- Sierpinski triangle; callcreate_sierpinski_sketch().res/scripts/lua/basic.lua-kv(obj)helper viaezy.log.res/scripts/lua/sierpinski.lua- Same idea for Lua; callcreate_sierpinski_sketch().
- The API is small and may change between versions; prefer
ezy.help()after upgrades. - Scripting is for automation and inspection, not a full replacement for the GUI workflow.
- Heavy work on the UI thread can block the app; keep snippets short.
- Only APIs under
ezy(and documented aliases) are the supported public scripting contract.
Desktop builds with embedded Python can accept console snippets over TCP while the GUI runs. The remote client talks to the same ezy tree as the in-app console.
Launch (default host is localhost when you pass only a port):
EzyCad.exe --listen 8765
EzyCad.exe --listen 127.0.0.1:8765
Bind 0.0.0.0 only if you intentionally expose the port on the network (no authentication).
If scripts/ is already on your Python path (as in many IPython setups), just import ezycad. Otherwise::
import sys
sys.path.insert(0, r"C:\src\EzyCad\scripts")
import ezycadThen (keep the connection open — avoid with in IPython if you will call app again later)::
import ezycad
app = ezycad.connect() # 127.0.0.1:8765; EzyCad must be running with --listen
app.ezy.log("hello from remote")
print(app.view.sketch_count())
print(app.view.curr_sketch.node_count())
print(app.ezy.get_mode())
# app.close() when doneIf you see a connection / socket error, EzyCad was closed or app was already closed — call ezycad.connect() again.
python scripts/ezycad_remote.py --port 8765
python scripts/ezycad_remote.py -c "ezy.log('hello')"
With scripts/ on PYTHONPATH, python -m ezycad works the same way.
Raw execute / eval still return a Result (ok / output / result / error). Typed methods raise ezycad.EzyCadError on failure and unwrap simple values (ints, tuples, dicts) from the remote repr.
For general application behavior, see usage.md.