Releases: alfu32/k3d
Release list
4.5.6-improvements
• Patched the window tool and frame model.
- Supports L/C/A modes like the polyline tools.
- Enter finishes the contour.
- If the user entered only 2 points, it falls back to a rectangular frame from those 2 points.
- Preview lines are routed through the thick feedback overlay via feedbackLines().
- Added tool feedback line export so tools can draw thick 2D overlay previews, not just thin ShapeRenderer lines.
- Frames now store an optional contour, not just cornerA/cornerB.
- Frame geometry now supports contour-based windows.
- Rectangular frames still work as before.
- Arbitrary window contours are inset by frame width and extruded by depth.
- Resizing frame handles rescales the stored contour instead of destroying it.
- Frame contours are persisted; model version bumped to 16.
• Patched the frame issues.
- Flipped the front/back frame ring normals, so the
ventral/dorsal faces now render with the opposite winding.
- Made contour-based frames actually follow transforms by transforming frame.contour together with cornerA/corner. This is the
main reason move/rotate had appeared inert.
- Restored frame scaling through the standard scale tool by wiring architecture/HVAC transforms into.
- Fixed architecture handle dragging to use the stored world-space endpoints directly instead of reapplying the group transform. That removes the double-transform bug on wall/slab/
frame endpoint handles.
• Added thick feedback-line coverage for the requested tools.
- Added shared feedback-line helpers
- Polyline and double-line/ribbon now export their full preview paths to the thick overlay, including arc previews and ribbon perimeter
- Rectangle, surface-rect, quad, and circle now export full closed-loop previews
- Line offset, push/pull, and extrude-swipe now export the full preview wireframe/path geometry instead of only a partial guide line
- Architecture slab and add-hole now export their full rectangle previews to the same thick overlay.

4.5.5
added a format-selection step before opening the system dialog.
What changed in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
- Added a small native desktop format picker via JOptionPane:
- DesktopFileDialogOption
- chooseDesktopFileDialogOption(...)
- Kept the actual file picking native/system via FileDialog
- Added replaceFileExtension(...) so save defaults match the chosen format
Now these desktop flows show the available extensions before the system dialog opens:
- Open
- options:
- All supported (*.octd, *.k3d)
- Octodraw (*.octd)
- Legacy K3D (*.k3d)
- options:
- Save As
- options:
- Octodraw (*.octd)
- Legacy K3D (*.k3d)
- options:
- Import Mesh
- options:
- All supported (...)
- plus one option per supported mesh format
- options:
- Export Mesh
- one option per export format
- Load Vector Glyph Catalog
- options:
- Vector Glyph Catalog (*.octd)
- Fonts (*.ttf, *.otf)
- options:
This keeps the system file dialog, but makes the permitted extensions explicit first.
Fixed the CI failure mode.
Cause:
- prepareWebComponentBundle declared concrete inputs under web/build/dist/webapp/:
- assets/
- scripts/
- octodraw-.js
- Those paths are generated later by buildWebRuntime, so on GitHub Actions Gradle validates them before execution and fails if they do not exist yet.
What I changed in web/build.gradle:
- kept the explicit dependency:
- prepareWebComponentBundle.dependsOn(prepareWebDocs)
- removed the eager generated-path input declarations:
- inputs.dir(webRuntimeDir/assets)
- inputs.dir(webRuntimeDir/scripts)
- inputs.file(webRuntimeDir/)
Why this is correct:
- those are produced artifacts, not static source inputs
- the task graph already guarantees they exist through the dependency chain
- the previous declarations were what made CI fail validation
4.5.0: fix(file-dialog): win
These four desktop flows now use the native AWT file dialog path instead of VisUI FileChooser:

- Open → core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3089
- Save As → core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3120
- Export Mesh → core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3736
- Load Vector Glyph Catalog → core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:7992
Shared desktop dialog helper:
- core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3038
Also patched while in there:
- SVG export
- IFC export
And the packaged Windows MCP autostart guard is here:
rel 4.4.9
4.4.8
rel-4.4.7 webapp
-
Kept MCP generic: use /scene/console to run automation scripts.
-
vector text can be moved, scaled, rotated, exploded
-
vector text is a real text entity instead of dumping geometry into model lines/faces.
What changed:
- text, size, normal/axisU anchor plane - tracking, line spacing, glyph source path - files: core/src/main/kotlin/com/github/alfu32/sketch/model/DraftTextStore.kt- VectorTextTool now places a vector text entity (not raw segments/faces):
- file: core/src/main/kotlin/com/github/alfu32/sketch/tools/VectorTextTool.kt
- Selection/editing:
- You can select vector text like other text entities.
- Vector Text panel now switches to selected-entity editing when exactly one vector text is selected.
- Tracking and line spacing edits are applied to the selected entity.
- file: core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
- file: core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
- Rendering:
- Vector text is rendered from glyph catalog at draw time as vector geometry in 3D (entity-driven, not persisted as regular model edges/faces).
- file: core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
- Persistence:
- Vector text metadata (kind/tracking/lineSpacing/glyphSourcePath) is saved/loaded.
- clone/group/ungroup/copy preserve vector text properties.
- files:
- core/src/main/kotlin/com/github/alfu32/sketch/model/ModelPersistence.kt
- core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
- Tool split preserved:
- Old text tool remains ToolId.TEXT.
- Vector text is separate ToolId.VECTOR_TEXT.
- file: core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolId.kt
- VectorTextTool now places a vector text entity (not raw segments/faces):
feat(webapp): webapp bundle ( docs + working app ) WIP
4.3.0: feat(export-import):
Implemented. STL/OBJ are now core features (no plugin required), with desktop + Android dialogs and extension-based dispatch.
-
Added core mesh IO engine in core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:
- OBJ import/export
- STL import: auto (.stl), forced ASCII (.stla), forced binary (.stlb)
- STL export: binary for .stl/.stlb, ASCII for .stla
-
Added mesh prototype creation in core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt:664:
- Builds an object prototype from imported triangles
- Adds edges from triangle borders
-
Wired core UI/commands in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:
- Commands: import.mesh, export.mesh
- Desktop VisUI file dialogs for import/export with extension filters
- Android SAF import/export flow (system picker/activity)
- Import creates a named object prototype from filename and switches to object placement tool
- Export uses selected mesh triangles when available, otherwise full model
-
Added action toolbar buttons in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:
- Import Mesh
- Export Mesh
Implemented. I continued the format expansion and wired FBX/IFC into the same mesh import/export flow.
-
Added FBX + IFC support in the core mesh IO enums/dispatch in core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:26 and core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:41.
-
Added FBX ASCII import/export in core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:231 and core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:1090.
-
Added IFC import (STEP subset) in core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:313 with entity parsing in core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt:471.
-
Updated command labels/tags to reflect expanded formats in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:1015 and core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:1030.
-
Updated dialogs and routing so FBX/IFC are treated as supported import/export targets in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3155, core/src/main/kotlin/com/github/alfu32/sketch/
Main.kt:3224, and core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3545.
feedback improvements
changed feedback entities to be thicker and have more contrast against the light/white background.
-
Added Android SAF bridge in core:
- core/src/main/kotlin/com/github/alfu32/sketch/AndroidSafBridge.kt- Implemented bridge in Android launcher:
- android/src/main/kotlin/com/github/alfu32/sketch/android/AndroidLauncher.kt
- Uses ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT
- Reads/writes via ContentResolver
- Returns URI + display name back to core
- Wired Main to SAF on Android:
- core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
- showOpenModelDialog() -> SAF open
- showSaveAsModelDialog() -> SAF create/save
- Keeps previous custom Android chooser as fallback
Cross-system/path safety (your requirement)
- No SAF URI/path is persisted inside .octd.
- On SAF open:
- file bytes are copied to app-local working file first
- model is loaded from local working file
- On SAF save-as:
- writes to selected SAF destination
- also mirrors a local working copy (best effort)
- This avoids crashes when a model moves between systems/storage providers.
- Implemented bridge in Android launcher:
4.0.0: feat(prod-name):
3.3.0
feat: UI dock/selection controls, Android runtime fixes, performance passes, mesh tool, and slab holes
Detailed log (commit body / release changelog)
- Added a right-side docked panel system (DockSection accordion-style docklets) and moved major panels into the dock.
- Replaced unstable nested VisWindow docking with lightweight dock sections (stable vertical stacking + scroll behavior).
- Added docklet title/header styling with distinct header vs body colors and different open/closed visuals.
- Added sticky/min-width behavior for dock width to reduce width “wiggle”.
- Moved Selection, Object, and Objects panels into the dock as docklets.
- Split Architecture Settings into 4 docklets:
- Architecture - Walls
- Architecture - Slabs
- Architecture - Stairs
- Architecture - Frames
- Added a new UI Settings docklet for toolbar icon/button sizing.
- User-selectable toolbar/icon size: 32x32 (default), 48x48, 64x64.
- Added runtime toolbar rebuild when size changes (built-in + plugin toolbars).
- Persisted selected UI icon size in UI preferences.
- Updated icon loading to use size-specific atlases and mapping columns from assets/icons.mapping.csv.
- Updated icon atlases/assets (icons.png, icons.48.png, icons.64.png, icons.svg, mapping CSV).
- Reworked construction toolbars and added mesh construction tool.
- Split construction into:
- Point Construction
- Entity Construction
- Moved Hotspot from Actions -> Point Construction.
- Moved Push/Pull from Modification -> Entity Construction.
- Added Mesh tool to point construction toolbar (with mesh icon).
- Mesh tool behavior:
- user picks variable number of points
- after point #2, it creates triangles using previous/current + nearest prior point
- shows construction feedback
- Esc exits tool / returns to Select
- Fixed icon usage:
- Construction Line button now uses construction_line icon
- Face Outline button uses face_outline icon
- Split construction into:
- Added file operations in toolbar: Open and Save As.
- Added action buttons with dedicated icons (file_open, file_save).
- Implemented open/save-as dialogs and wiring.
- Save As auto-appends .k3d if missing.
- Open/Save As now update active model file + window title.
- Fixed file chooser “freeze” UX by forcing pack/center/front/fade-in on open.
- Added and persisted walkthrough movement speed.
- New Walk move speed control in Model Settings.
- Wired to walkthrough camera controller move speed.
- Persisted walkthrough tuning values:
- move speed
- jump velocity
- gravity
- height-adjust speed
- Added Android runtime input usability fixes.
- Android now catches Back and Escape (prevents app being backgrounded on Esc).
- Added Android hardware-keyboard Ctrl meta tracking (dispatchKeyEvent / dispatchKeyShortcutEvent) and shared modifier helper (InputModifiers).
- Restored pointer feedback behavior after Android cursor update regression (kept event-driven movement semantics).
- Android launcher keeps app-private plugins/ folder semantics and app-local default model file path.
- Added Android UX messaging / help integration.
- Added Android first-run hardware input notice (external keyboard/mouse recommended).
- Added Help / About panel/docklet and command entry.
- Included Android input guidance in-app (Tap OK to continue wording on first-run dialog).
- Large selection panel upgrade (counts + per-category display/modify/wireframe controls).
- Added T (total) and S (selected) columns.
- Added D (draw/visible), M (modifiable/unlocked), W (wireframe) columns.
- Added rows and controls for base categories:
- Edges
- Faces
- Voxels
- Hotspots
- Objects
- Added rows and controls for architecture categories:
- Walls
- Slabs
- Stairs
- Frames
- Semantics:
- D=false hides category and auto-forces M=false
- restoring D=true auto-restores M=true
- turning off D or M clears selection in that category
- invisible categories do not snap
- visible-but-locked categories still snap
- W=true skips face rendering for face/voxel/architecture categories
- Counts are cached and recomputed only on model changes (avoid per-frame recount cost).
- Improved selection behavior and entity ownership selection.
- Parametric architecture/HVAC entities now select by hit-testing generated geometry ownership (faces/edges -> owning entity), not only by heuristic endpoint/handle proximity.
- Click selection and window selection use generated geometry ownership for architecture/HVAC.
- Window selection no longer selects objects behind the camera (screen projection validity/depth filtering).
- Architecture/HVAC selection order was refined to prioritize geometry hits before some hotspot paths.
- Improved architecture hole workflows and fixed regressions.
- Wall hole handles reduced to only 2 resize handles (top-left and bottom-right).
- Fixed wall-hole selection/delete regression:
- selecting a hole sub-entity no longer deletes the whole wall
- delete order now prioritizes selected hole sub-entities
- Added direct wall-hole sub-entity selection (no contour-line selection dependency).
- Restored wall-hole resize behavior after selection-order changes.
- Added slab holes (new feature) with wall-like workflow.
- Architectural slabs now support rectangular holes defined in slab main plane (horizontal/planar to slab basis).
- Slab geometry generation now cuts holes through slab thickness and rebuilds:
- top/bottom faces with openings
- inner hole side walls
- outer slab side walls
- hole contour guide lines (with diagonals)
- Add Hole tool now supports slabs:
- if a slab is selected, hole is added to that slab
- fallback can target nearest wall/slab
- Added slab hole handle markers (2 handles) and resize-by-drag.
- Added slab-hole sub-entity selection and delete (same UX pattern as wall holes).
- Added slab hole persistence (save/load) and copy behavior (copy slab copies its holes too).
- Dimension editing improvement.
- Dimensions now participate in Stretch operations:
- selected dimensions move as whole
- unselected dimensions stretch when attached endpoints/offset coincide with stretched geometry vertices
- Added notifyExternalChange() support path for external in-place dimension edits.
- Dimensions now participate in Stretch operations:
- Rendering / overlay improvements.
- Disabled platform-dependent line-width API calls (glLineWidth) and replaced with no-op wrapper for consistency across desktop/Android.
- Added dedicated 2D over-render for selected segments:
- thicker screen-space dashed overlay
- restored dashing (5px dash / 3px gap)
- larger endpoint dots (blue, primary blue, ~3.5px radius)
- This improves selected edge visibility independently of 3D line rendering thickness.
- Orbit camera zoom behavior improvements.
- Orbit zoom now slides both camera position and orbit target (dolly-like behavior) instead of only moving the camera.
- Target can “glue” to first model surface hit under the target ray.
- Glue behavior is distance-gated:
- zoom in glue threshold: 1
- zoom out glue threshold: 30
- Prevents overly sticky targeting at close range while keeping useful lock-on behavior at distance.
- Shadow camera / shadow bounds improvements.
- Shadow camera volume now tracks model bounds using a bounding sphere and centers shadow target on sphere center.
- Shadow volume size uses padded diameter and tuned near/far span to avoid clipping.
- Shadow bounds updates were moved to piggyback on face mesh traversal instead of separate heavy scene scans.
- Shadow pass rendering is now dirty-only (no full shadow redraw every frame on camera-only interaction).
- Performance / responsiveness work for large models.
- Stopped rebuilding face mesh every frame (dirty/stamp-based rebuild only).
- Stopped recomputing all object-instance prototype-derived runtime geometry every frame (dirty-only).
- Reduced undo queue length to 20 items.
- Autosave is now throttled/debounced (trailing debounce) instead of save-on-every-change.
- Autosave now uses fast snapshot capture + async background write to disk.
- Explicit saves remain synchronous and coordinate with async autosave to avoid races.
- Autosave snapshots omit undo history (smaller/faster).
- Plugin update performance improved:
- cached plugin model snapshot for PluginHost update context
- avoids rebuilding full ModelPersistence.snapshot(...) every frame on large models
- Additional runtime throttling/change-awareness added for cursor/snap status recomputation.
- Selection + rendering + snapping filters integrated throughout runtime.
- Render paths now respect category D/M/W flags for basic entities and architecture categories.
- Snapper respects visibility (including wireframe face suppression).
- Selected-segment overlay and highlights skip hidden categories.
- Clearing filters removes selected items in affected categories, including architecture hole sub-s...



