feat(editor): preset placement polish — params, move tool, shadows, isolation (#357)

* feat(editor): preset placement polish — params, move tool, shadows

- wall/slab/ceiling/roof create paths consume `toolDefaults` so template
  presets build with their saved params; cleared on tool unmount
- wall draw preview reflects the preset's height/thickness (+ HUD labels)
- box-select picks up registry-selectable kinds (shelf) via bbox
- registry + column move tools: snap to the active grid step, R/T rotation,
  and ignore the stray trailing click that armed the move (no double-place)
- shelf geometry casts + receives shadows like fence/slab

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(viewer): expose isIsolationActive() for isolation-aware consumers

Tracks whether an isolation filter is currently applied and exposes it so
hosts can avoid acting on the partial view — e.g. skipping project-thumbnail
autosave while a single subtree is isolated (preset capture).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-06-02 10:17:15 -04:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 8abfc94b99
commit f7ff60561e
11 changed files with 277 additions and 46 deletions
+6 -1
View File
@@ -37,7 +37,12 @@ export {
SUBTRACTION,
} from './lib/csg-utils'
export type { EdgeMode } from './lib/edge-style'
export { applyIsolation, clearIsolation, collectIsolationSubtree } from './lib/isolation'
export {
applyIsolation,
clearIsolation,
collectIsolationSubtree,
isIsolationActive,
} from './lib/isolation'
export { GRID_LAYER, OVERLAY_LAYER, SCENE_LAYER, ZONE_LAYER } from './lib/layers'
export {
applyMaterialPresetToMaterials,
+13
View File
@@ -12,6 +12,17 @@ const ORIGINAL_LAYERS = Symbol('isolation:original-layers')
type IsolationCarrier = Object3D & { [ORIGINAL_LAYERS]?: number }
// Whether a subtree is currently isolated (some objects have SCENE_LAYER
// disabled). Read by consumers that must not act on the partial view — e.g.
// the project-thumbnail autosave skips capturing while isolated so it never
// snapshots a single focused item as the whole project's thumbnail.
let isolationActive = false
/** True while an isolation filter is applied (see {@link applyIsolation}). */
export function isIsolationActive(): boolean {
return isolationActive
}
/**
* Compute the union of every isolated subtree's `Object3D` descendants.
*
@@ -71,6 +82,7 @@ export function applyIsolation(ids: ReadonlyArray<AnyNodeId> | null): void {
if (keep.has(obj)) continue
hideRecursive(obj, keep)
}
isolationActive = true
}
function hideRecursive(obj: Object3D, keep: Set<Object3D>): void {
@@ -98,4 +110,5 @@ export function clearIsolation(): void {
}
})
}
isolationActive = false
}