Phase 5 Stage D slab: port placement + move + boundary/hole editors
Replicates the fence Stage D recipe for slab — three drag affordances
+ one placement tool, all routed through the registry:
affordanceTools:
'boundary-edit' → thin <PolygonEditor> wrapper (vertex/edge drag)
'hole-edit' → same for a single hole polygon
move → DragAction with single-undo dance
tool: () => placement (multi-click polygon with axis/45° snap)
`PolygonEditor` + `PolygonEditorProps` exported from
`@pascal-app/editor` as Stage D transitional surface (Stage F cleanup
moves them into `@pascal-app/nodes`).
ToolManager mount sites for SlabBoundaryEditor / SlabHoleEditor now
route through `getRegistryAffordanceTool` with legacy fallback.
Slab move action does not use the live-drag exception (polygon CSG
rebuild every tick) — matches legacy behavior; optimization is a
separate task once we measure.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
7b5a1c607a
commit
b2e5d84986
@@ -179,10 +179,31 @@ export const ToolManager: React.FC = () => {
|
||||
rotation={buildingRotation as [number, number, number]}
|
||||
>
|
||||
{showZoneBoundaryEditor && selectedZoneId && <ZoneBoundaryEditor zoneId={selectedZoneId} />}
|
||||
{showSlabBoundaryEditor && selectedSlabId && <SlabBoundaryEditor slabId={selectedSlabId} />}
|
||||
{showSlabHoleEditor && selectedSlabId && editingHole && (
|
||||
<SlabHoleEditor holeIndex={editingHole.holeIndex} slabId={selectedSlabId} />
|
||||
)}
|
||||
{showSlabBoundaryEditor &&
|
||||
selectedSlabId &&
|
||||
(() => {
|
||||
const Registry = getRegistryAffordanceTool('slab', 'boundary-edit')
|
||||
return Registry ? (
|
||||
<Suspense fallback={null}>
|
||||
<Registry slabId={selectedSlabId} />
|
||||
</Suspense>
|
||||
) : (
|
||||
<SlabBoundaryEditor slabId={selectedSlabId} />
|
||||
)
|
||||
})()}
|
||||
{showSlabHoleEditor &&
|
||||
selectedSlabId &&
|
||||
editingHole &&
|
||||
(() => {
|
||||
const Registry = getRegistryAffordanceTool('slab', 'hole-edit')
|
||||
return Registry ? (
|
||||
<Suspense fallback={null}>
|
||||
<Registry holeIndex={editingHole.holeIndex} slabId={selectedSlabId} />
|
||||
</Suspense>
|
||||
) : (
|
||||
<SlabHoleEditor holeIndex={editingHole.holeIndex} slabId={selectedSlabId} />
|
||||
)
|
||||
})()}
|
||||
{showCeilingBoundaryEditor && selectedCeilingId && (
|
||||
<CeilingBoundaryEditor ceilingId={selectedCeilingId} />
|
||||
)}
|
||||
|
||||
@@ -14,6 +14,11 @@ export {
|
||||
snapFenceDraftPoint,
|
||||
} from './components/tools/fence/fence-drafting'
|
||||
export { CursorSphere } from './components/tools/shared/cursor-sphere'
|
||||
// Phase 5 Stage D — PolygonEditor for slab/ceiling boundary + hole editors.
|
||||
export {
|
||||
PolygonEditor,
|
||||
type PolygonEditorProps,
|
||||
} from './components/tools/shared/polygon-editor'
|
||||
export {
|
||||
formatAngleRadians,
|
||||
getAngleToSegmentReference,
|
||||
|
||||
Reference in New Issue
Block a user