Skip to content

Releases: alfu32/k3d

android, object picking and DXF fixes

Choose a tag to compare

@github-actions github-actions released this 02 Apr 20:09

Patched the three regressions.

  • Android Ctrl/copy mode
    • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolController.kt
    • Android now syncs copyMode from the live Ctrl modifier every frame for tools that support copy mode.
    • This avoids relying on libGDX receiving raw Ctrl key events, which Android was intercepting.
  • Android render save
    • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • core/src/main/kotlin/com/github/alfu32/sketch/render/RenderController.kt
    • Save on Android now opens the system ACTION_CREATE_DOCUMENT picker and writes the rendered PNG through SAF.
    • It no longer silently saves to app-local storage instead of showing the dialog.
  • Object picking inside larger object bounds
    • core/src/main/kotlin/com/github/alfu32/sketch/tools/SelectTool.kt
    • Removed the coarse AABB fallback from click-picking.
    • Object click-pick now requires an actual face or line hit, so an outer object no longer wins just because the ray passes through its bounds.

DXF import/export is fixed at the core path.

  • core/src/main/kotlin/com/github/alfu32/sketch/export/MeshIo.kt
    - DXF import now parses:
    - LINE
    - LWPOLYLINE
    - POLYLINE / VERTEX / SEQEND
    - 3DFACE
    - SOLID
    - TRACE
    - DXF export now writes both:
    - LINE
    - 3DFACE
    - added DXF-specific geometry APIs so lines are no longer lost on import/export

    • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
      • added MeshSegment
      • added createImportedPrototype(...) so imported objects can contain both faces and explicit linework
      • existing createMeshPrototype(...) now delegates to it
    • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
      • DXF import now places both imported faces and imported lines into the created prototype
      • DXF export now exports both world triangles and world segments
      • selected export works for line segments too
      • export label changed from DXF 3DFACE (.dxf) to DXF LINE + 3DFACE (.dxf)
      • export status text is now generic enough for non-triangle DXF entities

    Checked:

    • GRADLE_USER_HOME=.gradle-user ./gradlew :core:compileKotlin -q

    Current behavior:

    • DXF import still follows the existing mesh-import flow:
      • create prototype
      • click to place object
    • DXF export emits explicit lines plus triangle faces
    • if a DXF has faces but no explicit lines, triangle edges are generated only when no DXF line entities were imported

    Remaining limitation:

    • exporter writes LINE + 3DFACE only; it does not try to recreate original DXF higher-level entities like LWPOLYLINE on export.

Global Illumination/Raytracing

Choose a tag to compare

@github-actions github-actions released this 31 Mar 08:02
image

changelog from 4.8.9 to 4.9.1:

4.9.1
tutorial 02_rendering gi 2

  • Improved the new offline renderer preview and output stability.
  • Fixed saved render images being vertically flipped.
  • Fixed render framing/camera mapping so the offline render matches the current view much more closely.
  • Fixed directional/sun light contribution in offline rendering.
  • Fixed path-tracing striping/banding artefacts.
  • Fixed stale previous-pass/block artefacts in progressive rendering.
  • Fixed render-window preview sizing so the preview no longer grows to the full internal buffer size.
  • Added render size presets while keeping the preview window at a manageable fixed display size.
  • Added a global render light level control for both raytrace and GI/path-trace.
  • Added camera light intensity control.
  • Added an option to disable tile pruning, with pruning now off by default.
  • Improved transparent-material rendering so transmitted rays:
    • pass through transparent surfaces,
    • are tinted by material color,
    • and are dimmed according to alpha.

4.9.0
octodraw 7 gi

  • Added a new Rendering toolbar and render window.
  • Added two offline rendering modes:
    • Raytrace
    • GI / Pathtrace
  • Added progressive rendering passes from coarse to fine, ordered from image center toward the borders.
  • Added Stop and Save controls for offline rendering.
  • Added live compositing of the offline render over the captured GPU framebuffer.
  • Added blur and blend controls for the render overlay.
  • Added simple glass transmission/refraction support.
  • Added desktop/Android parallel tile rendering with worker pool support.
  • Kept web rendering on the single-threaded fallback path.
  • Added worker-count control in the render window.
  • Added resolution display in the render window.

Shorter store/update-note version:
another-house gi octd

  • Introduced a new offline rendering window with Raytrace and GI/Pathtrace modes.
  • Added progressive center-out rendering, save/stop controls, worker-count control, size presets, blur/blend controls, and adjustable lighting.
  • Improved transparency handling for glass-like materials.
  • Fixed multiple offline renderer issues including framing, lighting, vertical save flip, striping, and progressive pass artefacts.
big-building 01 gi

UX/jar plugins/dimension bounds

Choose a tag to compare

@github-actions github-actions released this 28 Mar 10:40

4.8.9

In Short:

  • Hotspot dragging now previews the resulting geometry in wireframe and shows live movement measurements.
  • Array tool previews now show far more copies.
  • Desktop now supports precompiled jar plugins.
  • Plugin loading is disabled on unsupported Web/Android runtimes.
  • Dimension selection bounds are now tight and correct.
image image image image image

TLDR

  • Added live hotspot drag feedback:
    • shows the hotspot movement line
    • shows measurement feedback while dragging
    • shows a wireframe preview of the future geometry driven by the hotspot
  • Increased array/multiplier preview capacity:
    • ghost/wireframe preview limit raised from 32 to 10000
  • Added desktop support for precompiled plugin jars:
    • plugin manager can now load .jar plugins in addition to Groovy script plugins
    • jar plugins can expose their entry point through:
      • META-INF/services/com.github.alfu32.sketch.plugin.Plugin
      • or manifest Plugin-Class / K3D-Plugin-Class / Octodraw-Plugin-Class
  • Restricted plugins to supported runtimes:
    • plugin loading is now disabled on Web and Android
    • avoids unsupported runtime/classloading paths on those targets
  • Fixed dimension bounding boxes:
    • selection/frame bounds now use the actual rendered dimension geometry
    • extension lines, dimension line, and slash markers are all accounted for
    • bounds are now tight instead of oversized/wrong

staged loading/fixes/maintenance

Choose a tag to compare

@github-actions github-actions released this 28 Mar 07:49

4.8.8
image

  • Added staged model loading with visible progress instead of a long blind startup stall.
  • File loading now initializes the app scene first, then loads the model in steps.
  • Added a modal load dialog with progress feedback and an Abort button.
  • Scene application during load is now chunked across frames, so the UI stays responsive while loading.
  • Opening a file now creates a .bak copy as part of the staged load flow.
  • Aborting a load no longer overwrites the target file or the previously opened file.
  • Camera is reset to a valid default position immediately when a load starts.
  • Added Edit Selected Object action for entering object edit mode more directly.
  • Fixed object click-picking regression where objects were not selected correctly by direct click.
  • Fixed orbit camera target auto-glue on faces, including root faces and object faces.
  • Fixed hotspot-driven object geometry refresh so stale face shells are no longer left visible after deformation.

4.8.7

  • Added a numeric Circle segments setting to Model Settings.
  • Circle preview and generated geometry now use the configured segment count.
  • Default circle segment count is now 24.
  • Added internal optimizations for model delete/change handling.
  • Added asynchronous/background spatial indexing work for model/query structures.
  • Reduced excessive render/status feedback caused by indexing progress spam.
  • Fixed linear/multiple translate array multiplication spacing faults.
  • Disabled Snap bundle generation from the default desktop bundle pipeline to stop unrelated desktop builds from failing on Snap packaging.

4.8.6 -> 4.8.8 overall

  • Major work on model loading, scene application, and persistence safety.
  • Better responsiveness and feedback when opening large files.
  • Safer cancel behavior during load.
  • Better object editing workflow.
  • Fixes for object picking, camera face snapping, and hotspot-driven geometry updates.
image

array tools

Choose a tag to compare

@github-actions github-actions released this 26 Mar 12:38

feat(tools): arrays and array hotspots
image

image

implemented the array tools and fixed the existing translate-multiple behavior.

What changed

  • core/src/main/kotlin/com/github/alfu32/sketch/tools/MultipleCopyTools.kt
    • fixed CopyMultipleTool
      • step direction now comes from a - o
      • copy count now comes from the span of b - o projected onto that step direction
      • the old tool was using the final span direction and projecting the measure onto it, which was the wrong geometry
    • added PlanarTranslateMultipleTool
      • repeats in the xoz plane
      • offsets are built from the measured step components on x and z
    • added VolumetricTranslateMultipleTool
      • repeats in x, y, and z
      • offsets are built from the measured step components on all three axes
    • added proper preview rendering for planar/volumetric translated arrays
  • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
    • fixed hotspot multiplier behavior to match the same semantics
    • for hotspots:
      • o = referencePosition
      • a = hotspot definition position
      • b = runtime target / instance value
    • MULTIPLY_LINEAR now uses the measured step vector from o -> a
    • MULTIPLY_VOLUMETRIC now uses per-axis step ratios from o -> a and o -> b
    • I did not invent a new planar hotspot operation; planar hotspot behavior is the ny = 0 case of volumetric multiplication
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolId.kt
    • added:
      • PLANAR_TRANSLATE_MULTIPLE
      • VOLUMETRIC_TRANSLATE_MULTIPLE
  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • registered both new tools
    • added them to the built-in tool command palette list
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
    • added both tools to the modification toolbar
    • added icon-name/color mapping fallbacks
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolInputProcessor.kt
    • added both tools to the M-cycle with the other transform tools

feat(tools): arrays and array hotspots

implemented the array tools and fixed the existing translate-multiple behavior.

What changed

  • core/src/main/kotlin/com/github/alfu32/sketch/tools/MultipleCopyTools.kt
    • fixed CopyMultipleTool
      • step direction now comes from a - o
      • copy count now comes from the span of b - o projected onto that step direction
      • the old tool was using the final span direction and projecting the measure onto it, which was the wrong geometry
    • added PlanarTranslateMultipleTool
      • repeats in the xoz plane
      • offsets are built from the measured step components on x and z
    • added VolumetricTranslateMultipleTool
      • repeats in x, y, and z
      • offsets are built from the measured step components on all three axes
    • added proper preview rendering for planar/volumetric translated arrays
  • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
    • fixed hotspot multiplier behavior to match the same semantics
    • for hotspots:
      • o = referencePosition
      • a = hotspot definition position
      • b = runtime target / instance value
    • MULTIPLY_LINEAR now uses the measured step vector from o -> a
    • MULTIPLY_VOLUMETRIC now uses per-axis step ratios from o -> a and o -> b
    • I did not invent a new planar hotspot operation; planar hotspot behavior is the ny = 0 case of volumetric multiplication
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolId.kt
    • added:
      • PLANAR_TRANSLATE_MULTIPLE
      • VOLUMETRIC_TRANSLATE_MULTIPLE
  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • registered both new tools
    • added them to the built-in tool command palette list
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
    • added both tools to the modification toolbar
    • added icon-name/color mapping fallbacks
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolInputProcessor.kt
    • added both tools to the M-cycle with the other transform tools

fix(tools): arrays and array hotspots

  • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:5987
    - PLANAR_TRANSLATE_MULTIPLE now maps to multiple-copy-translate-planar
    - VOLUMETRIC_TRANSLATE_MULTIPLE now maps to multiple-copy-translate-volumetric

fix(snapcraft): release

  • Moved the Snapcraft project file to the repo root:
    - snapcraft.yaml

    • Removed the old nested config:
      • snap/snapcraft.yaml
    • Kept the GUI assets under:
      • snap/gui/octodraw.desktop
      • snap/gui/icon.png

    Gradle change

    • lwjgl3/build.gradle
      • bundleLinuxSnap now copies:
        • root snapcraft.yaml into the Snapcraft project root
        • snap/ into the staged snap/ directory
      • local Snap build still uses Snapcraft, not mksquashfs

    CI change

    • .github/workflows/release.yml
      • Linux CI no longer installs Snapcraft
      • Linux CI no longer runs :lwjgl3:bundleLinuxSnap
      • Linux CI no longer uploads *.snap

extra array tools

Choose a tag to compare

@github-actions github-actions released this 23 Mar 23:27

feat(tools): arrays and array hotspots

img_18

implemented the array tools and fixed the existing translate-multiple behavior.

What changed

  • core/src/main/kotlin/com/github/alfu32/sketch/tools/MultipleCopyTools.kt
    • fixed CopyMultipleTool
      • step direction now comes from a - o
      • copy count now comes from the span of b - o projected onto that step direction
      • the old tool was using the final span direction and projecting the measure onto it, which was the wrong geometry
    • added PlanarTranslateMultipleTool
      • repeats in the xoz plane
      • offsets are built from the measured step components on x and z
    • added VolumetricTranslateMultipleTool
      • repeats in x, y, and z
      • offsets are built from the measured step components on all three axes
    • added proper preview rendering for planar/volumetric translated arrays
  • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
    • fixed hotspot multiplier behavior to match the same semantics
    • for hotspots:
      • o = referencePosition
      • a = hotspot definition position
      • b = runtime target / instance value
    • MULTIPLY_LINEAR now uses the measured step vector from o -> a
    • MULTIPLY_VOLUMETRIC now uses per-axis step ratios from o -> a and o -> b
    • I did not invent a new planar hotspot operation; planar hotspot behavior is the ny = 0 case of volumetric multiplication
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolId.kt
    • added:
      • PLANAR_TRANSLATE_MULTIPLE
      • VOLUMETRIC_TRANSLATE_MULTIPLE
  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • registered both new tools
    • added them to the built-in tool command palette list
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
    • added both tools to the modification toolbar
    • added icon-name/color mapping fallbacks
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolInputProcessor.kt
    • added both tools to the M-cycle with the other transform tools

feat(tools): arrays and array hotspots

implemented the array tools and fixed the existing translate-multiple behavior.

What changed

  • core/src/main/kotlin/com/github/alfu32/sketch/tools/MultipleCopyTools.kt
    • fixed CopyMultipleTool
      • step direction now comes from a - o
      • copy count now comes from the span of b - o projected onto that step direction
      • the old tool was using the final span direction and projecting the measure onto it, which was the wrong geometry
    • added PlanarTranslateMultipleTool
      • repeats in the xoz plane
      • offsets are built from the measured step components on x and z
    • added VolumetricTranslateMultipleTool
      • repeats in x, y, and z
      • offsets are built from the measured step components on all three axes
    • added proper preview rendering for planar/volumetric translated arrays
  • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
    • fixed hotspot multiplier behavior to match the same semantics
    • for hotspots:
      • o = referencePosition
      • a = hotspot definition position
      • b = runtime target / instance value
    • MULTIPLY_LINEAR now uses the measured step vector from o -> a
    • MULTIPLY_VOLUMETRIC now uses per-axis step ratios from o -> a and o -> b
    • I did not invent a new planar hotspot operation; planar hotspot behavior is the ny = 0 case of volumetric multiplication
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolId.kt
    • added:
      • PLANAR_TRANSLATE_MULTIPLE
      • VOLUMETRIC_TRANSLATE_MULTIPLE
  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • registered both new tools
    • added them to the built-in tool command palette list
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
    • added both tools to the modification toolbar
    • added icon-name/color mapping fallbacks
  • core/src/main/kotlin/com/github/alfu32/sketch/ui/ToolInputProcessor.kt
    • added both tools to the M-cycle with the other transform tools

fix(tools): arrays and array hotspots

  • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:5987
    - PLANAR_TRANSLATE_MULTIPLE now maps to multiple-copy-translate-planar
    - VOLUMETRIC_TRANSLATE_MULTIPLE now maps to multiple-copy-translate-volumetric

fix(snapcraft): release

  • Moved the Snapcraft project file to the repo root:
    - snapcraft.yaml

    • Removed the old nested config:
      • snap/snapcraft.yaml
    • Kept the GUI assets under:
      • snap/gui/octodraw.desktop
      • snap/gui/icon.png

    Gradle change

    • lwjgl3/build.gradle
      • bundleLinuxSnap now copies:
        • root snapcraft.yaml into the Snapcraft project root
        • snap/ into the staged snap/ directory
      • local Snap build still uses Snapcraft, not mksquashfs

    CI change

    • .github/workflows/release.yml
      • Linux CI no longer installs Snapcraft
      • Linux CI no longer runs :lwjgl3:bundleLinuxSnap
      • Linux CI no longer uploads *.snap

performance improvements

Choose a tag to compare

@github-actions github-actions released this 22 Mar 11:19
image
  • 34f88e2 fix(model): indexing
  • b269c60 feat(model): indexing
  • 88d7c5b fix(snap): platform detection failure
  • 9e73f83 improve(model): pick handling, line-to-line intersect
  • c0db7bd fix(snap-build): snap package faults
  • 62623f4 fix(snap-build): snap package faults
  • 86b3461 fix(snap-build): snap package faults

fix(model): indexing

  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    - computeGroupFaceMeshVisualStamp(...) already now includes the group world transform, so moved instances invalidate correctly
    - I also added syncGroupFaceBundles() on every render pass, not only during root face-mesh rebuild
    - that forces dead/deleted child-group mesh bundles to be dropped even when the root face mesh itself did not need rebuilding
  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    - computeGroupFaceMeshVisualStamp(...) already now includes the group world transform, so moved instances invalidate correctly
    - I also added syncGroupFaceBundles() on every render pass, not only during root face-mesh rebuild
    - that forces dead/deleted child-group mesh bundles to be dropped even when the root face mesh itself did not need rebuilding

fix(snap): permissions

feat(model): indexing

  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt

    • computeGroupFaceMeshVisualStamp(...) already now includes the group world transform, so moved instances invalidate correctly
    • I also added syncGroupFaceBundles() on every render pass, not only during root face-mesh rebuild
    • that forces dead/deleted child-group mesh bundles to be dropped even when the root face mesh itself did not need rebuilding
      relevant fixes are:
  • no per-frame frustum/index render path

  • no mutation-path index rebuild while drawing lines

  • no indexed prefilter on group volume selection

  • group face bundles now invalidate on transform changes

  • deleted group bundles are synced out every frame

fix(snap): platform detection failure

patched lwjgl3/build.gradle.

What changed

  • Snap app command now goes through a wrapper:
    • command: bin/octodraw-launch
  • The build now generates bin/octodraw-launch inside the snap
  • The wrapper sets pragmatic desktop env fallbacks before execing the real launcher:
    • XDG_RUNTIME_DIR=/run/user/$(id -u) if missing
    • WAYLAND_DISPLAY=wayland-0 if that socket exists
    • DISPLAY=:0 if /tmp/.X11-unix/X0 exists
    • then exec "$SNAP/octodraw-jre" "$@"

improve(model): pick handling, line-to-line intersect

plan:

  • Replace the current category-based pick arbitration with a unified nearest-geometry pick path.
    • Test active-group faces/edges and child object instance faces/edges in the same hit pass.
    • Choose the nearest geometric hit in world space.
    • Only then resolve what it belongs to: object, wall, slab, frame, etc.
    • This avoids both failure modes:
      • walls/slabs behind objects winning
      • objects behind walls/slabs winning
  • Wire the line spatial index into segment insertion and auto-split.
    • Compute the new segment AABB.
    • Query indexed candidate segments from that AABB.
    • Run exact intersectSegments(...) only on those candidates.
    • Do the same for endpoint snapping using a small point-radius AABB.
  • Add coarse render culling at scene/group level.
    • Frustum-test world AABBs of groups/objects before drawing.
    • Use this as the first render optimization pass before any chunked cubic culling.

Implemented the three changes.

  • Geometry-first object picking:
    • core/src/main/kotlin/com/github/alfu32/sketch/tools/SelectTool.kt
    • basic pick resolution now uses a unified nearest-hit pool for voxels/faces/edges/dimensions/texts/child objects instead of category arbitration
    • architecture/HVAC root picks are now gated so a nearer child object instance can win over walls/slabs behind it
    • I did not switch category priority; the decision is still based on geometric hit distance
  • Indexed segment insertion / auto-split:
    • core/src/main/kotlin/com/github/alfu32/sketch/model/DraftLineStore.kt
    • endpoint snapping now queries a small indexed AABB around the point
    • segment insertion now queries indexed candidate segments from the new segment AABB before running exact intersectSegments(...)
    • that removes the full-scan path from the normal insertion/split workflow
  • Coarse render culling:
    • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
    • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • added queryGroupsByFrustum(...) using the group spatial index plus frustum/AABB filtering
    • child object/group faces are now rendered through per-group mesh bundles and only submitted when in view
    • child group draft lines are also culled by the same visible-group set

Important scope note:

  • this is scene/group-level culling, not cubic chunk culling
  • root geometry is still rendered as one root mesh; the culling now applies to child object/group geometry first, which is what we agreed to do before any finer chunking

fix(snap-build): snap package faults

  • added install badges

fix(snap-build): snap package faults

  • added install badges

fix(snap-build): snap package faults

  • added install badges

4.8.2: fix(snap-store): snap package pipelines

Choose a tag to compare

@github-actions github-actions released this 22 Mar 11:08
image
  • 34f88e2 fix(model): indexing
  • b269c60 feat(model): indexing
  • 88d7c5b fix(snap): platform detection failure
  • 9e73f83 improve(model): pick handling, line-to-line intersect
  • c0db7bd fix(snap-build): snap package faults
  • 62623f4 fix(snap-build): snap package faults
  • 86b3461 fix(snap-build): snap package faults

fix(model): indexing

  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    - computeGroupFaceMeshVisualStamp(...) already now includes the group world transform, so moved instances invalidate correctly
    - I also added syncGroupFaceBundles() on every render pass, not only during root face-mesh rebuild
    - that forces dead/deleted child-group mesh bundles to be dropped even when the root face mesh itself did not need rebuilding
  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    - computeGroupFaceMeshVisualStamp(...) already now includes the group world transform, so moved instances invalidate correctly
    - I also added syncGroupFaceBundles() on every render pass, not only during root face-mesh rebuild
    - that forces dead/deleted child-group mesh bundles to be dropped even when the root face mesh itself did not need rebuilding

fix(snap): permissions

feat(model): indexing

  • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt

    • computeGroupFaceMeshVisualStamp(...) already now includes the group world transform, so moved instances invalidate correctly
    • I also added syncGroupFaceBundles() on every render pass, not only during root face-mesh rebuild
    • that forces dead/deleted child-group mesh bundles to be dropped even when the root face mesh itself did not need rebuilding
      relevant fixes are:
  • no per-frame frustum/index render path

  • no mutation-path index rebuild while drawing lines

  • no indexed prefilter on group volume selection

  • group face bundles now invalidate on transform changes

  • deleted group bundles are synced out every frame

fix(snap): platform detection failure

patched lwjgl3/build.gradle.

What changed

  • Snap app command now goes through a wrapper:
    • command: bin/octodraw-launch
  • The build now generates bin/octodraw-launch inside the snap
  • The wrapper sets pragmatic desktop env fallbacks before execing the real launcher:
    • XDG_RUNTIME_DIR=/run/user/$(id -u) if missing
    • WAYLAND_DISPLAY=wayland-0 if that socket exists
    • DISPLAY=:0 if /tmp/.X11-unix/X0 exists
    • then exec "$SNAP/octodraw-jre" "$@"

improve(model): pick handling, line-to-line intersect

plan:

  • Replace the current category-based pick arbitration with a unified nearest-geometry pick path.
    • Test active-group faces/edges and child object instance faces/edges in the same hit pass.
    • Choose the nearest geometric hit in world space.
    • Only then resolve what it belongs to: object, wall, slab, frame, etc.
    • This avoids both failure modes:
      • walls/slabs behind objects winning
      • objects behind walls/slabs winning
  • Wire the line spatial index into segment insertion and auto-split.
    • Compute the new segment AABB.
    • Query indexed candidate segments from that AABB.
    • Run exact intersectSegments(...) only on those candidates.
    • Do the same for endpoint snapping using a small point-radius AABB.
  • Add coarse render culling at scene/group level.
    • Frustum-test world AABBs of groups/objects before drawing.
    • Use this as the first render optimization pass before any chunked cubic culling.

Implemented the three changes.

  • Geometry-first object picking:
    • core/src/main/kotlin/com/github/alfu32/sketch/tools/SelectTool.kt
    • basic pick resolution now uses a unified nearest-hit pool for voxels/faces/edges/dimensions/texts/child objects instead of category arbitration
    • architecture/HVAC root picks are now gated so a nearer child object instance can win over walls/slabs behind it
    • I did not switch category priority; the decision is still based on geometric hit distance
  • Indexed segment insertion / auto-split:
    • core/src/main/kotlin/com/github/alfu32/sketch/model/DraftLineStore.kt
    • endpoint snapping now queries a small indexed AABB around the point
    • segment insertion now queries indexed candidate segments from the new segment AABB before running exact intersectSegments(...)
    • that removes the full-scan path from the normal insertion/split workflow
  • Coarse render culling:
    • core/src/main/kotlin/com/github/alfu32/sketch/model/GroupScene.kt
    • core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • added queryGroupsByFrustum(...) using the group spatial index plus frustum/AABB filtering
    • child object/group faces are now rendered through per-group mesh bundles and only submitted when in view
    • child group draft lines are also culled by the same visible-group set

Important scope note:

  • this is scene/group-level culling, not cubic chunk culling
  • root geometry is still rendered as one root mesh; the culling now applies to child object/group geometry first, which is what we agreed to do before any finer chunking

fix(snap-build): snap package faults

  • added install badges

fix(snap-build): snap package faults

  • added install badges

fix(snap-build): snap package faults

  • added install badges

4.8.1: feat(ui): topdown and leftright layout,png export

Choose a tag to compare

@github-actions github-actions released this 21 Mar 11:15

fix(android): ctrl key

Android Ctrl handling is now stateful instead of relying only on transient meta flags:
- core/src/main/kotlin/com/github/alfu32/sketch/InputModifiers.kt:11
- android/src/main/kotlin/com/github/alfu32/sketch/android/AndroidLauncher.kt:30
- this keeps Ctrl active while dragging for move-copy / rotate-copy, and clears it on focus loss/destroy
fix(ui-toolbars): auto resizing issue

  • Non-resizable toolbars now ignore stale saved width/height and repack from content:
    • core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:5029
    • so changing toolbar button size now resizes the toolbar windows correctly

feat(ui): resizable text

  • Added UI text scaling presets:
    • 1x, 1.5x, 2x
    • wired in UI Settings
    • persisted in prefs
    • applied to VisUI skin fonts and relaid out live

fix(ui): resize effect propagation failure

patched the UI scale refresh path in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt.

  • rebuildToolbarsForUiScaleChange() now finishes with a full UI refresh instead of only marking layout dirty, so icon-size changes reflow immediately too: core/src/main/kotlin/com/
    github/alfu32/sketch/ui/SketchUiOverlay.kt:4523
  • Added recursive layout invalidation/validation for the full actor tree, not just top-level widgets: core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:4550
  • Rebuilds the right dock scroll container on scale changes, resets the cached dock width, and immediately repositions/revalidates panels and toolbars: core/src/main/kotlin/com/
    github/alfu32/sketch/ui/SketchUiOverlay.kt:4568
  • refreshUiForTextScaleChange() now forces an immediate full relayout/repack of dock panels, input widgets, toolbars, and floating UI instead of waiting for a later collapse/expand or
    frame pass: core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:4592

fix(ui): resize effect propagation failure

patched the UI scale refresh path in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt.

  • rebuildToolbarsForUiScaleChange() now finishes with a full UI refresh instead of only marking layout dirty, so icon-size changes reflow immediately too: core/src/main/kotlin/com/
    github/alfu32/sketch/ui/SketchUiOverlay.kt:4523
  • Added recursive layout invalidation/validation for the full actor tree, not just top-level widgets: core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:4550
  • Rebuilds the right dock scroll container on scale changes, resets the cached dock width, and immediately repositions/revalidates panels and toolbars: core/src/main/kotlin/com/
    github/alfu32/sketch/ui/SketchUiOverlay.kt:4568
  • refreshUiForTextScaleChange() now forces an immediate full relayout/repack of dock panels, input widgets, toolbars, and floating UI instead of waiting for a later collapse/expand or
    frame pass: core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:4592

fix(ui): resize effect toolbars failure

The remaining bug was exactly where the toolbar windows are positioned.

  • positionTopFlowToolbars() was still reapplying saved width/height even for non-resizable toolbars, so after icon-size changes the rebuilt toolbar content grew but the host window
    got forced back to the old size and clipped the buttons.
  • I fixed that in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:4997 so non-resizable toolbars always use current prefWidth/prefHeight, same as
    applyToolbarState() already did.

fix(ui): resize effect toolbars failure

The remaining bug was exactly where the toolbar windows are positioned.

  • positionTopFlowToolbars() was still reapplying saved width/height even for non-resizable toolbars, so after icon-size changes the rebuilt toolbar content grew but the host window
    got forced back to the old size and clipped the buttons.
  • I fixed that in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt:4997 so non-resizable toolbars always use current prefWidth/prefHeight, same as
    applyToolbarState() already did.

fix(ui): toolbar relayout bug

Fixed in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt.

  • Hover expand/collapse no longer marks all toolbars for global re-layout, so moving the mouse does not snap toolbars back to their saved positions.
  • Toggling Auto-collapse toolbars no longer calls positionPanels(), so manual toolbar placement is preserved.
  • Collapsed toolbars now force their width from the visible button/content width instead of the title width, so plugin toolbars collapse to button-sized hosts too.

fix(ui): toolbar persistence bug

• The problem was in the persistence trigger.

  • Toolbar state was only being saved from the window touchUp listener.
  • With auto-collapse enabled, that is not reliable enough:
    • collapse/expand changes happen without a drag save
    • collapsed toolbars can end up with state changes that never hit that listener
  • Result: the runtime layout looked correct, but the stored x/y stayed stale, so after restart you got old positions.

patched core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt.

feat(ui): linewidth and UI layout helpers

  • UI Settings now has a Normal line width slider in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
    • wired to core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    • it drives the non-thick 2D ShapeRenderer.ShapeType.Line overlay batches: selection rect, tutorial arrow, hotspot outlines
    • this is best-effort on Android/Desktop because glLineWidth support is driver-dependent
  • Toolbar padding and layout spacing were reduced in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
    • button cell padding: 0
    • toolbar content padding: 0
    • toolbar layout margin/gap reduced to 4f
  • Added two toolbar arrangement buttons in UI Settings:
    • Flow L->R
      • lays toolbars left-to-right, wraps top-to-down, and stops before the right dock
    • Flow T->D
      • lays toolbars top-to-down, wraps left-to-right from the left edge
    • both save the resulting positions immediately
  • Existing toolbar persistence stays active
    • toolbar positions are continuously persisted in act(...), so explicit arrangement and manual repositioning both survive restart

fix(ui): toolbars collapsed width glitch

  • The collapsed toolbar width logic was already shrinking the content area.
  • But the VisWindow title label still kept its full text, so the window pref width stayed title-driven on initial render and in auto-collapse mode.

I fixed it in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt.

  • CollapsibleWindow now stores its base title and can switch to a compact-title mode
  • when a toolbar is auto-collapsed:
    • the title text is set to ""
  • when expanded:
    • the full title is restored

That makes the collapsed window width depend on the visible button, not on the title text.

fix(ui): toolbars collapsed width glitch

  • Collapsed toolbars no longer use an empty title.
  • They now use the first 4 characters of the original title:
    - baseTitle.take(4)

feat(ui): topdown and leftright layout,png export

improve the layout l-r procedure:

  • the toolbars should be sorted in such a way that they fill a maximum of space on each line
    and layout t-d procedure:
  • the toolbars should be sorted by width : the largest on top to the smallest on the bottom

the png exporter will export a screenshot of the rendering buffer without the UI

  • Added PNG Screenshot (*.png) to the exporter list in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
    - desktop, web, and Android export flows now accept PNG
    - PNG export captures the rendered scene before UI/2D overlay drawing
    - desktop save, web download, and Android SAF write are all wired through the same pending export path
    • Fixed the desktop export dialog integration in core/src/main/kotlin/com/github/alfu32/sketch/Main.kt
      • it now maps the selected desktop dialog option back to the real export option
      • dialog wording is generic now, not mesh-only
      • direct file export also handles .png correctly
    • Improved toolbar L->R layout in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
      • uses first-fit decreasing row packing
      • fills each row more tightly instead of naive sequential wrap
      • the default top-flow placement for unsaved toolbars uses the same strategy now
    • Kept T->D width-driven in core/src/main/kotlin/com/github/alfu32/sketch/ui/SketchUiOverlay.kt
      • visible toolbars are sorted by width descending
      • largest go first/top, then wrap to the next column

feat(snap-store): snap package pipelines

What changed

  • lwjgl3/build.gradle
    • added bundleLinuxSnap
    • it builds from dist/octodraw-dist--linux
    • generates:
      • meta/snap.yaml
      • meta/gui/octodraw.desktop
      • meta/gui/icon.png
    • packs the snap with mksquashfs to:
      • dist/octodraw-dist--linux.snap
    • Linux local pipelines now include it:
      • :lwjgl3:bundleLocal depends on bundleLinuxSnap on Linux
      • :lwjgl3:dev depends on bundleLinuxSnap on Linux
  • .github/workflows/release.yml
    • Linux CI now installs squashfs-tools
    • Linux build job now runs:
      • :lwjgl3:bundleLinuxTar
      • :lwjgl3:bundleLinuxSnap
      • :lwjgl3:jarLinux
      • :core:pluginApiJar
    • uploaded Linux artifacts now include:
      • dist/*.snap
    • release upload now includes *.snap

fix(snap-store): snap package pipelines

Fixed.

Cause:

...

Read more

UI improvements

Choose a tag to compare

@github-actions github-actions released this 20 Mar 23:02

changelog short

image
  • ui settings improvements:
  • settings for thin and thick line width
  • font size selection (1x,1.5x,2x)
  • ui improvements:
  • toolbars autocollapse into a single button-width toolbar, autoexpands when hovered, optional through ui settings
  • autoalign toolbars left-to right/top-down or top-to-down/left-to-right
  • set selection color directly in the selection panel
  • fix android control key
image

changelog detailed

image

fix(android): ctrl key

Android Ctrl handling is now stateful instead of relying only on transient meta flags
- this keeps Ctrl active while dragging for move-copy / rotate-copy, and clears it on focus loss/destroy
fix(ui-toolbars): auto resizing issue

  • Non-resizable toolbars now ignore stale saved width/height and repack from content
    • changing toolbar button size now resizes the toolbar windows correctly

feat(ui): resizable text
image

  • Added UI text scaling presets:
    • 1x, 1.5x, 2x
    • wired in UI Settings
    • persisted in prefs
    • applied to VisUI skin fonts and relaid out live

fix(ui): resize effect propagation failure

  • rebuildToolbarsForUiScaleChange() now finishes with a full UI refresh instead of only marking layout dirty, so icon-size changes reflow immediately too
  • Added recursive layout invalidation/validation for the full actor tree, not just top-level widgets
  • Rebuilds the right dock scroll container on scale changes, resets the cached dock width, and immediately repositions/revalidates panels and toolbars
  • refreshUiForTextScaleChange() now forces an immediate full relayout/repack of dock panels, input widgets, toolbars, and floating UI instead of waiting for a later collapse/expand or frame pass

fix(ui): resize effect toolbars failure

The remaining bug was exactly where the toolbar windows are positioned.

  • positionTopFlowToolbars() was still reapplying saved width/height even for non-resizable toolbars, so after icon-size changes the rebuilt toolbar content grew but the host window
    got forced back to the old size and clipped the buttons.
  • I fixed that so non-resizable toolbars always use current prefWidth/prefHeight, same as
    applyToolbarState() already did.

fix(ui): toolbar relayout bug

  • Hover expand/collapse no longer marks all toolbars for global re-layout, so moving the mouse does not snap toolbars back to their saved positions.
  • Toggling Auto-collapse toolbars no longer calls positionPanels(), so manual toolbar placement is preserved.
  • Collapsed toolbars now force their width from the visible button/content width instead of the title width, so plugin toolbars collapse to button-sized hosts too.

fix(ui): toolbar persistence bug

• The problem was in the persistence trigger.

  • Toolbar state was only being saved from the window touchUp listener.
  • With auto-collapse enabled, that is not reliable enough:
    • collapse/expand changes happen without a drag save
    • collapsed toolbars can end up with state changes that never hit that listener
  • Result: the runtime layout looked correct, but the stored x/y stayed stale, so after restart you got old positions.

feat(ui): linewidth and UI layout helpers

  • UI Settings now has a Normal line width slider
    • drives the non-thick 2D ShapeRenderer.ShapeType.Line overlay batches: selection rect, tutorial arrow, hotspot outlines
    • this is best-effort on Android/Desktop because glLineWidth support is driver-dependent
  • Toolbar padding and layout spacing were reduced
    • button cell padding: 0
    • toolbar content padding: 0
    • toolbar layout margin/gap reduced to 4f
  • Added two toolbar arrangement buttons in UI Settings:
    • Flow L->R
      • lays toolbars left-to-right, wraps top-to-down, and stops before the right dock
    • Flow T->D
      • lays toolbars top-to-down, wraps left-to-right from the left edge
    • both save the resulting positions immediately
  • Existing toolbar persistence stays active
    • toolbar positions are continuously persisted in act(...), so explicit arrangement and manual repositioning both survive restart

fix(ui): toolbars collapsed width glitch

  • The collapsed toolbar width logic was already shrinking the content area.

  • But the VisWindow title label still kept its full text, so the window pref width stayed title-driven on initial render and in auto-collapse mode.

  • CollapsibleWindow now stores its base title and can switch to a compact-title mode

  • when a toolbar is auto-collapsed:

    • the title text is set to ""
  • when expanded:

    • the full title is restored

That makes the collapsed window width depend on the visible button, not on the title text.