Releases: alfu32/k3d
Release list
3.2.8: feat(ui): file ops, ui refinment, resizable button icons and logo
UI / Dock
- Added UI Settings docklet in the right-side dock.
- Added user-selectable toolbar icon/button size: 32x32 (default), 48x48, 64x64.
- Persisted the selected toolbar/icon size in UI preferences.
- Rebuilt toolbars at runtime when size changes (built-in + plugin toolbars refresh).
- Updated icon loading to use size-specific atlas coordinates from assets/icons.mapping.csv and the matching atlas image (icons.png, icons.48.png, icons.64.png).
- Improved docklet title bars:
- visually distinct from docklet content
- different appearance when collapsed vs expanded
- Added Walk move speed control to the Model Settings docklet.
- Wired it to WalkthroughCameraController.moveSpeed.
- Added persistence for walkthrough tuning values:
- move speed
- jump velocity
- gravity
- height-adjust speed
- Restores walkthrough tuning on startup and saves on change / shutdown.
- Implemented Open action (toolbar button) with mapped icon (file_open).
- Implemented Save As action (toolbar button) with mapped icon (file_save).
- Added K3D file dialogs for Open / Save As (.k3d filter).
- Save As appends .k3d automatically if missing.
- Open updates the active model file and window title (and saves current model first).
- Save As updates the active model file and window title.
Fix
- Fixed the “freeze” behavior after clicking Open / Save As (file chooser now explicitly packs, centers, comes to front, and fades in).
ui docking panel
fix(android): inputs
fix(ui): panel layout bugs
I removed the guest panels from the dock and restored them as regular panels.
What changed
- core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
- Panels are added back to the stage individually (not inside the Panels dock container)
- positionPanels() is back to independent right-side vertical stacking using the existing panel stack layout
- I kept the “force visible when not in automation-hide mode” behavior so the panels stay on
What stays improved
- Scroll-wheel separation fix is still in place:
- panel scrolling should no longer zoom the scene
- scene zoom should no longer scroll panels
ui refactoring
-
Split the old Construction toolbar into two:
- Point Construction (...:784, ...:832)
- Entity Construction (...:795, ...:845)- Moved Push/Pull out of Modification and into Entity Construction.
- Moved Add Hotspot out of Actions and into Point Construction as the first button (...:841).
- Removed Hotspot from the Actions toolbar button list (...:1004).
- Face Outline now uses the face_outline icon mapping (...:3748).
- Construction Line still uses the dedicated construction_line icon (...:3734).
- Bumped toolbar layout version to reset persisted toolbar positions after the split (...:184).
Toolbar layout version reset was intentional so existing saved positions don’t conflict with the new toolbar set.
dynamic objects
feature(hotspots):
SPEC:
more hotspot features
1/ lets add 2 more types of hotspot operations:
- multiply linear : ( will multiply(copy) the attached geometry alongside the hotspot segment the number of times it fits in its length/
- multiply volumetric : ( multiply the attached geometry to fill the extended volume designated by the per-instance hotspot position.
- multiply-rotate-2d : multiply the attached geometry alongside the designated circle arc ( the center being the ref point and the radius being the initial
hotspot position). - multiply-rotate-3d : multiply the attached geometry alongside the designated spiral arc ( the center being the ref point and the radius being the initial
hotspot position, the height of the spiral being the height difference between the reference point and the per-instance hospot).
2/ lets let the user choose the shape of the hotspot between triangle ( pointing up),square,circle, diamond and upside triangle ( pointing down ).
3/ lets let the user pick the color of the hotspot.
IMPLEMENTATION:
- Added 4 new hotspot operations in core/src/main/kotlin/com/github/alfu32/sketch/model/HotspotStore.kt:9:
- MULTIPLY_LINEAR
- MULTIPLY_VOLUMETRIC
- MULTIPLY_ROTATE_2D
- MULTIPLY_ROTATE_3D- Implemented runtime geometry generation for those ops in core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt:1287 (copy-based multiplier
behavior, with a safety cap). - Added hotspot shape + color model support in core/src/main/kotlin/com/github/alfu32/sketch/model/HotspotStore.kt:20 and wiring in scene updates
(updateHotspotShape / updateHotspotColor) in core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt:2372. - Added UI controls for hotspot shape and color (including picker), plus default persistence, in core/src/main/kotlin/com/github/alfu32/sketch/ui/
SketchUiOverlay.kt:216, core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:2185, core/src/main/kotlin/com/github/alfu32/sketch/ui/
SketchUiOverlay.kt:2242. - Added rendering of hotspot shapes (triangle/square/circle/diamond/inverted triangle) and per-hotspot color in core/src/main/kotlin/com/github/alfu32/sketch/
Main.kt:3152 and helpers at core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:3206. - New hotspots now use default operation+shape+color at creation in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:973 and defaults in core/src/main/
kotlin/com/github/alfu32/sketch/tools/HotspotSettings.kt:8. - Save/load updated for hotspot shape/color/dependencies in core/src/main/kotlin/com/github/alfu32/sketch/model/ModelPersistence.kt:15, core/src/main/kotlin/
com/github/alfu32/sketch/model/ModelPersistence.kt:678.
- Implemented runtime geometry generation for those ops in core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt:1287 (copy-based multiplier
feature(hotspots-objects):
SPECIFICATION:
› there are 2 entities participating in the system of graphical objects : object definition ( or prototype ) and object instance.
an object definition aggregates geometry ( lines, faces, hotspots and other objects instances ).
an object instance has its own collection of instance lines, faces, hotspots and other object instances and a reference to its object prototype. the instance
lines faces hotspots and other object instances are the result of calculations performed on their prototype correspondent by employing the instance hotspots
positions and the vertices of the prototype geometry. the recalculation of the instance geometry will be performed upon initialisation of the object instance,
the modification of hotspot positioning or on prototype change.
in order for the object instance to be able to perform calculations that will reflect on geometry, the prototype will have to map at definition time links
between the position of each hotspot and geometry, once a hotspot is assigned geometry ( lines, faces, other hotspots and/or objects ) during the object
definition it should update an inner table of bindings.
on instantiation of the prototype, the object instance will hold an own copy of hotspot positions and present the transformed geometry and hotspots on a per-
instance basis.
when an object prototype is updated all instances should be redrawn, probably it should be usefull to materialise the link between a prototype and its
instances somwhere in such a way that when adding an instance to or removing an instance from the model is reflected.
i think this object-model is sufficient so that object instances are represented correctly according to the set of per-instance hotspot values.
PLAN:
this model is coherent and sufficient.
To make it implementable without ambiguity, rules locked:
- Instance stores only:
- transform,
- per-instance hotspot positions,
- derived/runtime geometry cache (recomputed, not authoritative).
- Prototype entities must have stable IDs: vertexId, edgeId, faceId, hotspotId, childRefId.
- Hotspot bindings in prototype must target IDs (not coordinates), e.g. hotspotId -> affectedVertexIds / childRefIds.
Recompute contract:
- Recompute instance runtime geometry from prototype baseline on:
- instance creation,
- instance hotspot move,
- prototype topology/binding/parameter change.
- Recompute is deterministic and full (no partial in-place drift): baseline copy -> apply hotspot operators -> rebuild runtime edges/faces.
- Prototype change invalidates all instances of that prototype (fan-out via prototype→instances index).
Editor behavior:
- In object edit mode, selection/add/delete edits prototype only.
- In normal mode, selecting an instance manipulates per-instance hotspot values only (topology locked unless explicit “edit prototype”).
What is still missing in current implementation (and causes the symptoms):
- Direct mutation paths still exist on instance geometry stores.
- No strict “full recompute from prototype baseline” pipeline per instance.
- Bindings are not fully vertex-ID-based yet (still partly geometric matching/fallback).
We’ll implement this in phases:
- introduce explicit prototype topology with stable vertex IDs,
- add per-instance runtime cache + dirty/recompute pipeline,
- route all edit-mode tools strictly to prototype store,
- remove instance topology edits except explode/convert workflows.
IMPLEMENTATION:
core runtime model to match the improved spec and moved behavior away from mutating instance geometry directly.
What is now in code:
- Prototype-edit mode is explicit on group nodes (editPrototypeMode), so when editing an object, geometry operations hit prototype stores directly:
- core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
- Instance geometry is now recomputed from prototype on every frame update:
- scene.recomputeAllInstanceGeometryFromPrototypes() is called in render():
- core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
- Recompute pipeline now does:
- clone prototype lines/faces/dims/texts,
- apply each hotspot operation using per-instance hotspot positions,
- install rebuilt runtime stores as instance overrides.
- Hotspot drag now updates hotspot position state only (prototype position in edit mode, override position in instance mode), not geometry-in-place:
- core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
- Attachment resolution during recompute is ID-aware (segment/face IDs), with fallback to vertex-key matching.
Build check:
- ./gradlew :core:compileKotlin passes.
Important remaining gap (for full strictness):
- Stable prototype vertex IDs and bindings at vertex-level. Current implementation is stable at segment/face ID level (plus vertex-key fallback),
not a full explicit vertex-ID topology table yet.
next step is exactly that: introduce prototype vertex entities with stable IDs and rewire hotspot bindings to vertex IDs first (then optional
hotspot→hotspot and hotspot→child-object bindings).
PHASE 2:
• Implemented next phase toward the model as specified.
changed in core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt:
- Added stable per-primitive vertex handles (primitiveId + vertex slot) for hotspot-driven deformation targeting.
- Updated hotspot deformation logic to use those stable handles first (instead of only coordinate-key matching), for both:
- STRETCH
- no-explicit-attachment fallback behavior (hotspot on geometry vertex).
- Kept coordinate-key fallback as safety net for legacy/unbound cases.
This makes per-instance recompute more stable and closer to the “stable prototype vertex id” requirement without replacing topology objects yet.
Validation:
- ./gradlew :core:compileKotlin passes.
Current state vs spec:
- Prototype is now the authoritative editable geometry in edit mode.
- Instances are recomputed from prototype + per-instance hotspot values on update.
- Vertex targeting now uses stable IDs derived from primitive IDs + slots.
Still to finish for full strict model:
- explicit standalone prototype vertex entities (not primitive-slot derived),
- explicit binding table for hotspot -> vertices/hotspots/child-objects,
- persistence of that binding graph.
PHASE 3:
implemented the next chunk toward the full prototype/instance model.
changed:
- Added persistent prototype vertex identity map (prototypeVertexIds) and refresh logic from prototype geometry:
- core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
- Extended hotspots with explicit vertex bindings (attachedVertexIds) in addition to segment/triangle refs:
- core/src/main/kotlin/com/...
☄️ Hotspots ☄️
added a dedicated Add Hotspot toolbar button using the hotspot icon mapping.
What changed:
- Added new action callback to UI overlay constructor and wired it to Main:
- core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
- core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
- Added a new Actions toolbar button:
- Label: Add Hotspot
- Icon key: hotspot (from icons.mapping.csv)
- Click behavior: calls existing hotspot creation flow (addHotspotAtCursor())
rel 2.12.1
- Ventilation auto-join now resolves by construction order and snaps new shaft endpoints to older shaft endpoints/segments before meshing.
- Crossings now create a local hump segment (not a full-duct shift):
- Detect crossings against older shafts.
- Build local raised intervals around crossings.
- Generate a bent path with up/down ramps.
- Ventilation geometry now sweeps along that resolved path (supports bent hump path), with start/end cap suppression on joined ends:
- HVAC pick/bounds use resolved geometry path (so interaction matches displayed shaft shape):
- Explode behavior kept: selected HVAC elements can still be exploded into model lines/faces.
- Crossings now create a local hump segment (not a full-duct shift):

rel 2.11.5 Architecture improvements
- architecture entities live in the main model now and behave like groups but also display handles at their construction points enabling quick editing
- architecture panel is on by default alongside model settings.
- fixed bug that prevented picking the colors for various parts of the architecture elements.
- fix walking camera : looking up-down was reversed
- the window frame has an optional glazing panel

2.11.4 swpe -extrude
- Extrude Swipe path p now supports the same arc input modes as polyline:
- A = 3-point arc (mid then end)
- C = center arc (center then end)
- L = line mode
- Arc preview is rendered while hovering, same interaction style as polyline.
- Backspace now clears pending arc pick (center/mid) first, then removes last path point.
- Arc tessellation uses PolylineSettings.arcMaxLength so segmentation behavior matches polyline.
Extrude Swipe path p now supports the same arc input modes as polyline:
- A = 3-point arc (mid then end)
- C = center arc (center then end)
- L = line mode
- Arc preview is rendered while hovering, same interaction style as polyline.
- Backspace now clears pending arc pick (center/mid) first, then removes last path point.
- Arc tessellation uses PolylineSettings.arcMaxLength so segmentation behavior matches polyline.
rel 2.11.3
MCP / MCP automation
Implemented a first-class self-describing MCP contract endpoint: GET /mcp/contract.
What changed
- Added new route and handler in core/src/main/kotlin/com/github/alfu32/sketch/mcp/McpHttpServer.kt:44 and core/src/
main/kotlin/com/github/alfu32/sketch/mcp/McpHttpServer.kt:106. - Wired server construction to provide contract payload in core/src/main/kotlin/com/github/alfu32/sketch/
Main.kt:1123. - Added contract generator in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt:1175 with:
- endpoint specs and request/response shapes,
- error/status semantics,
- execution/threading boundary (app.run { ... }),
- Groovy binding surface (app, scene, selection, cameraCtl, unit, save, etc.),
- dynamic live command catalog from /scene/listCommands,
- your 4 business use-case playbooks.
- Added endpoint mention in console help at core/src/main/kotlin/com/github/alfu32/sketch/tui/ConsoleTui.kt:294.
Implemented the first documentation pass in docs/ using the agreed order (Chapter 06, Chapter 05, Chapter 09), with scene cleanup + practical MCP operations +
screenshots for each documented step.

What I added
- Updated TOC with signature + progress links: docs/USER_MANUAL_TOC.md
- New chapter docs (signed):
- docs/chapters/CH06_TOOLBAR_BUTTON_REFERENCE.md
- docs/chapters/CH05_INTERACTION_FUNDAMENTALS.md
- docs/chapters/CH09_COMMANDS_REFERENCE.md
- docs/chapters/README.md
- New screenshots for these chapters:
- docs/images/ch06_*.png (7 images)
- docs/images/ch05_*.png (7 images)
- docs/images/ch09_*.png (5 images)
Execution notes
- I reset/cleaned scene state before each chapter using MCP console (scene.resetScene()).
- I performed practical steps through MCP commands/pointer events and captured screenshots after each operation.
- Keyboard interaction coverage is documented from source + visual outcomes; MCP currently has pointer/command/console endpoints but no dedicated keyboard-event
endpoint.
rel 2.10.6 Architecture Plugin
Release Notes 2.10.6
Scope
These notes cover changes from 2.9.2 to 2.10.6 (inclusive of all 2.10.x releases).
- Start tag:
2.9.2(6f763d8) - End tag:
2.10.6(036d304) - Commit span: 15 commits (
2.9.2..2.10.6)
Highlights
- Introduced an internal Architecture plugin stack:
- parametric
Wall,Slab,Stair,Add Hole,Window Frame,Door Frame, - architecture data model/store and persistence,
- architecture toolbar and settings panel integration.
- parametric
- Added IFC export support (
Export> IFC (Model)) with architecture/mesh/line serialization. - Upgraded snapping and selection for architecture workflows:
- snapping to visible faces across groups,
- snapping to triangle-border edges and edge midpoints,
- architecture-aware picking/selection behavior.
- Implemented architecture editing UX:
- wall endpoint drag handles,
- hole markers/handles and drag updates,
- direct architecture element selection from scene picking.
- Reworked stair generation into contour + thread-line driven construction with progressive refinements and optional rail grids.
- Improved wall join behavior for slanted walls with better 3D clipping/intersection continuity.
Version-by-Version
2.10.0
- Added core architecture feature set:
- new architecture tool IDs and toolbar entries,
- architecture settings model,
- architecture tools and scene/model integration,
- architecture parameter panel wiring.
- Added architecture persistence wiring and baseline docs updates (
docs/SHORTCUTS.md,docs/USER_MANUAL.md).
2.10.1
- Added IFC exporter (
IfcExporter) and command-palette export action:Export> IFC (Model). - Expanded architecture integration in scene/model flow and persistence.
- Improved snapping base behavior:
- face snapping beyond active group,
- better candidate scoring/prioritization.
2.10.2
- Major stair-tool workflow update:
- stair definition based on picked contour + picked thread polyline,
- improved polyline/component picking logic,
- stronger integration with architecture groups.
- Extended architecture selection/edit handling in
SelectTool.
2.10.3
- Wall geometry/join improvements in scene reconstruction:
- improved handling at segment transitions and joins,
- better clipping behavior in generated wall mesh.
2.10.4
- Additional wall-tool refinements:
- improved interaction behavior in wall editing flows,
- further join/selection integration updates.
2.10.6
- Stair-tool refinements:
- improved step/support generation behavior,
- support for left/right rail options in architecture settings and persistence,
- icon mapping updates for architecture/stair-related controls.
- Architecture panel/state integration refinements for stair parameters.
Consolidated Change List
Features
- New architecture plugin domain (store, tools, UI, persistence):
- wall/slab/stair/frame creation,
- wall holes and hole editing handles,
- architecture-focused selection logic.
- IFC export pipeline for model geometry and architecture content.
- Stair rail options (
left/right) added to architecture settings and stair generation.
Improvements
- Snapping:
- face snapping across non-active groups,
- snap targets for face-edge points and face-edge midpoints.
- Selection and edit UX:
- architecture element picking by face/edge context,
- wall endpoint drag editing,
- hole handle drag editing.
- Geometry generation:
- wall join clipping quality improvements for slanted configurations,
- iterative stair meshing/support quality improvements.
Fixes
- Multiple fixes in stair face/support generation and orientation behavior.
- Multiple fixes in wall join continuity/intersection handling.
- Multiple fixes in architecture selection/update paths to keep model and UI state consistent.
Files of Interest
Main implementation files in this release range:
core/src/main/kotlin/com/github/alfu32/sketch/model/ArchitectureStore.ktcore/src/main/kotlin/com/github/alfu32/sketch/tools/ArchitectureTools.ktcore/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.ktcore/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.ktcore/src/main/kotlin/com/github/alfu32/sketch/tools/SelectTool.ktcore/src/main/kotlin/com/github/alfu32/sketch/input/Snapper.ktcore/src/main/kotlin/com/github/alfu32/sketch/export/IfcExporter.ktcore/src/main/kotlin/com/github/alfu32/sketch/model/ModelPersistence.kt
feature(mesh-operations):
Implemented both internal solid-intersection tools and wired them into the app/toolbars/icons.
- Added new internal tools:
- Plane Section (ToolId.PLANE_SECTION): click a point (and snap normal if available), it intersects that plane with the full model triangle set, creates section edges, and isolates result
into a new group named Plane Section. - Mesh Intersection (ToolId.MESH_INTERSECTION): uses exactly 2 selected mesh groups, computes triangle/triangle intersection segments, isolates the resulting lines into a new group named
Mesh Intersection, and slices both groups’ faces along each intersection segment.
- Plane Section (ToolId.PLANE_SECTION): click a point (and snap normal if available), it intersects that plane with the full model triangle set, creates section edges, and isolates result
- Added shared geometry helper MeshIntersectionMath for:
- triangle/plane intersection segment extraction,
- triangle/triangle intersection segment extraction (non-coplanar),
- segment deduplication.
- Wired tool lifecycle and registration in Main:
- tool creation,
- command palette activation entries.
- Wired UI:
- toolbar includes both tools,
- icon mapping uses your provided keys plane_section and mesh_intersection,
- distinct fallback tint colors added.


