516 Commits

Author SHA1 Message Date
sudhir
0effda29fe Support duplicating and moving new walls 2026-04-17 11:08:01 +05:30
sudhir
096f4c161a Respect active grid snap for wall dragging and angle 2026-04-17 10:56:34 +05:30
sudhir
4edf45f7c9 Add auto ceilings and simplify ceiling selection affordances 2026-04-16 17:56:54 +05:30
sudhir
cb2ceba566 Add grid snap dropdown to viewer toolbar 2026-04-16 17:05:34 +05:30
sudhir
0e5a4d9fea Improve ceiling selection and move preview visibility 2026-04-16 15:04:52 +05:30
sudhir
5010013701 Reorder toolbar toggles to group wall mode before grid snap 2026-04-16 14:08:32 +05:30
sudhir
162c5806a7 Add cycling grid snap control to the viewer toolbar 2026-04-16 13:34:42 +05:30
sudhir
b1d8180f62 Fix opening remounts after merged wall reparenting 2026-04-16 13:22:33 +05:30
sudhir
ecb97aba8c Merge split wall segments when deleting dividers 2026-04-16 13:03:31 +05:30
sudhir
ae68d69f77 Simplify auto slab polygons for curved wall rooms 2026-04-16 12:39:52 +05:30
sudhir
a7b97caeb0 Add Alt-detach hints to wall endpoint move controls 2026-04-16 12:27:58 +05:30
sudhir
1cd71630bc Add 3D wall endpoint move controls 2026-04-16 11:50:40 +05:30
sudhir
f563dd9763 Keep connected walls joined during endpoint drags 2026-04-16 11:43:24 +05:30
sudhir
dee086545d Fix sharp edges on auto slabs for curved walls 2026-04-16 11:30:43 +05:30
sudhir
5c92d071f7 Fix slab updates for curved wall changes 2026-04-16 11:21:28 +05:30
sudhir
b4bf196d31 Merge branch 'main' of github.com:sudhir9297/editor into feat/wall-room-creation 2026-04-16 09:49:29 +05:30
Huy Hoang
3d1005847b
fix: prevent crash when duplicating elements (#239)
- Guard _buildCache in merged-outline-node against stale/disposed
  Object3D refs that cause TypeError on .id access during render
- Reset children array when duplicating roofs to prevent inconsistent
  parent-child relationships (matching existing stair behavior)
- Use obj?.parent check in EditorOutlinerSync to ensure objects are
  still in the scene graph before adding to outliner arrays
- Resume temporal state on parse failure to prevent undo/redo freeze

Closes #232
2026-04-15 17:25:03 -04:00
Roshan Warrier
e3ba4ab921
fix editor furnish item initialization (#237)
Co-authored-by: txhno <198242577+txhno@users.noreply.github.com>
2026-04-15 17:25:01 -04:00
billy
341725b37a
fix(viewer): await renderer.init() in Canvas gl factory (#233)
The WebGPURenderer needs its backend initialized before any direct
`.render(scene, camera)` call. The commented-out `// renderer.init()`
said "Only use when using <DebugRenderer />", but the non-debug path
also calls direct render from the post-processing fallback
(post-processing.tsx:318), which throws "Renderer: .render() called
before the backend is initialized" on any browser that falls back to
the WebGL2 backend.

Switching the gl factory to an async function and awaiting init()
before returning is safe in both backends (init() is idempotent and
the async factory is a supported @react-three/fiber v9+ pattern), and
prevents the error in WebGL2 fallback.
2026-04-15 17:23:27 -04:00
billy
93d9d68e19
fix(viewer): skip post-processing pipeline when WebGPU is unavailable (#234)
`RenderPipeline`, SSGI, and the denoise TSL node imported from
`three/webgpu` and `three/tsl` are all WebGPU-only. On a browser
without `navigator.gpu`, the WebGPURenderer falls back to WebGL2, and
attempting to build the TSL post-processing pipeline either throws or
produces broken output — the scene renders for a few frames, then
goes black as the 3-attempt retry loop fights the direct-render
fallback path in `useFrame`.

This sets `hasPipelineErrorRef.current = true` at pipeline setup time
when `navigator.gpu` is undefined, so `useFrame` takes the existing
direct `renderer.render(scene, camera)` path exclusively and never
tries to build the broken TSL pipeline.

No behavioural change in WebGPU mode — the guard only fires when the
WebGPU API is literally not exposed by the browser. The rare edge
case of `navigator.gpu` being defined but device creation failing at
runtime still falls through the existing try/catch unchanged.
2026-04-15 17:23:25 -04:00
sudhir
95f4c4e610 Merge branch 'main' of github.com:sudhir9297/editor into feat/wall-room-creation 2026-04-15 22:59:36 +05:30
Sudhir Yadav
b1709de44a
feat: curved wall and fixes (#236)
* feat: add polygon movement support to editor and implement dedicated move tools for walls, slabs, and ceilings

* feat: add uv2 attribute to ceiling and slab geometries for lightmap support

* Fix curved wall miters and align roof position sliders

* Fix wall measurement label and extension anchors

* Fix WebGPU renderer initialization order

* fix(editor): scope wall movement to the selected level

---------

Co-authored-by: Pascal <open@pascal.app>
2026-04-15 12:41:16 -04:00
Sudhir Yadav
57df224948
feat: Add catalog-based material presets across structural nodes (#231)
* Add catalog-based material presets across structural nodes

* Fix material picker fallback and wall visible highlights

* Preserve wall materials in selection highlights
2026-04-15 12:16:35 -04:00
sudhir
d1bef22701 Handle wall split attachment migration and child ids 2026-04-15 14:49:58 +05:30
sudhir
6190ba4bdc feat: implement automatic wall-splitting and slab generation from closed wall loops 2026-04-15 14:18:09 +05:30
sudhir
3ac26bf635 Fix WebGPU renderer initialization order 2026-04-15 10:49:51 +05:30
Pascal
f25806ee8f release: v0.5.1 2026-04-14 05:01:30 +00:00
Pascal
cf7493985f
fix: guard null selected item during item tool placement (#229) 2026-04-14 00:48:59 -04:00
Pascal
3afa1cea8b
fix: recover post-processing after duplicate scene mutations (#228) 2026-04-13 23:49:45 -04:00
Sudhir Yadav
a205e4f778
Feat/stairs fence update (#226)
* feat: railing on the straight stairs and new fence

* feat: added spiral and curved stairs with bug fix for fence

* feat:fence are linked to each other ... so moving one move the other sharing the same coordinate

* fix: update stair railing logic to include front-side attachments for terminal landings

* Integrate fence rendering into the fence system

* fix: pass nodeId instead of undefined node to WallTreeNode and FenceTreeNode

TreeNode was passing `node` (undefined variable) instead of `nodeId` to
WallTreeNode and FenceTreeNode, causing a runtime ReferenceError.
Updated FenceTreeNode to accept nodeId and look up the node from the
scene store internally, consistent with all other tree node components.

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

* feat: update fence icon with new isometric design

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

---------

Co-authored-by: Aymeric Rabot <aymeric@pascal.app>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 23:31:57 -04:00
Pascal
682e2a1a12
sync: backport monorepo PRs #240 #251 #253 (#225) 2026-04-13 11:24:13 -04:00
Pascal
b25be8227a
feat(editor): add cut-out button to floating action menu for slabs and ceilings (#224)
When selecting a floor slab or ceiling node, the floating UI buttons now
include a cut-out icon (carbon:cut-out) that directly creates a hole and
enters edit mode. Much more intuitive than navigating to the side panel.

Changes:
- NodeActionMenu: add onAddHole prop with carbon:cut-out icon
- FloatingActionMenu: wire up handleAddHole for slab/ceiling types
- Add ceiling to ALLOWED_TYPES so the floating menu appears for ceilings too
- Separate HOLE_TYPES from DELETE_ONLY_TYPES for cleaner type gating
2026-04-13 11:12:24 -04:00
github-actions[bot]
384eab819c release: @pascal-app/core@0.5.0 @pascal-app/viewer@0.5.0 2026-04-09 19:07:59 +00:00
Pascal
fab9077f65 fix: update lockfile for v0.5.0 release 2026-04-09 19:07:05 +00:00
Pascal
00b8f42899
feat: move/rotate building + relative positioning for all tools (#220)
Sync monorepo PRs #243 and #248 to the open-source editor.

Move/Rotate Building:
- New move-building-tool with grid snapping, R/T rotation, and Esc cancel
- Floating building action menu with move button
- Building helper with keyboard shortcut hints
- BuildingRenderer now applies position and rotation from node data

Building-Relative Coordinate System:
- GridEvent gains localPosition (building-local coords)
- use-grid-events computes building-local intersection from building mesh
- ToolManager wraps building-relative tools in a building-local <group>
- All tools (wall, slab, ceiling, stair, roof, zone, polygon-editor,
  placement coordinator) updated to use event.localPosition
- Placement coordinator adds worldToBuildingLocal helper for cursor
  position conversion

2D Floorplan Fix:
- SVG layers wrapped in <g transform=rotate(...)> for building rotation
- Pointer-to-plan conversion un-rotates when building is rotated
- Grid events from 2D include localPosition

Store Changes:
- useEditor movingNode union includes BuildingNode
- NodeActionMenu onDelete is now optional (buildings can move but not delete)
2026-04-09 14:36:34 -04:00
Pascal
6c3ac3e030 fix(editor): auto-switch to structure phase when interacting with nodes in floorplan
Two fixes for stair selection in 2D floorplan not working:

1. floorplan-panel: remove level > 0 restriction on auto-switch to structure
   phase. When viewing ANY level in the floorplan while in site phase, auto-enter
   structure mode so structural nodes (stairs, walls, slabs) become selectable.

2. selection-manager: expand auto-switch to also cover site phase. Clicking a
   structural or furnish element now auto-switches from site → structure/furnish,
   just like it already did between structure ↔ furnish ↔ zones.

This fixes the issue where stairs couldn't be selected in 2D and the floating
action menu (move/duplicate/delete) wouldn't appear.
2026-04-08 01:18:37 +00:00
Pascal
11104bc512 chore: bump version to 0.4.0 2026-04-07 23:22:46 +00:00
Pascal
0a46a9deb4
sync: comprehensive monorepo → editor parity (2D/3D decoupling, UX polish, crash fixes)
Squash merge of 3 commits:
1. useLiveTransforms store for 2D/3D decoupling + floorplan overhaul + Sentry crash fixes
2. Comprehensive 59-file sync bringing editor to full monorepo parity (selection highlights, delete tool, furnish/zone modes, keyboard shortcuts, all panels)
3. Missing files fix (materials.ts, merged-outline-node.ts, type fix)

75 files changed, ~6K additions.
2026-04-07 19:21:10 -04:00
Pascal
e8ad92592d
fix(viewer): suppress THREE.Clock deprecation warning from R3F 9.x (#215)
three.js r183 deprecated THREE.Clock, but @react-three/fiber 9.x still
uses it internally per <Canvas> mount. This floods the dev console with
noise on every page load and HMR reload.

Uses three's setConsoleFunction hook to surgically suppress only the
exact Clock deprecation message. All other three.js logs pass through
untouched, including TSL stack-trace warnings.

Safe to remove once R3F v10 stable ships (which replaces Clock with
Timer). Removal condition documented in file header.

Closes #213
2026-04-07 10:17:00 -04:00
Pascal
d9965f487c
fix: sync stair elevations with floor slabs (#216)
Mark stair nodes as dirty when slabs change so stairs properly stack on
top of floor slabs. StairSystem now computes slab-driven elevation by
sampling segment centers against the spatial grid.

Changes:
- spatial-grid-sync: mark stair nodes dirty on slab changes (same level)
- stair-system: syncStairGroupElevation + getStairSlabElevation compute
  Y offset from slab data; rotateXZ helper for world-space transforms
- stair-renderer: use position-x/position-z so the system controls Y
2026-04-06 12:02:57 -04:00
geopenta
ed6ed3f018
fix(editor): release scene singletons on Editor unmount (#214)
The spatial-grid manager, scene-store subscriptions, and the viewer
outliner's Object3D arrays are module-level singletons that previously
lived for the whole page lifetime. When an app unmounted the Editor
(e.g. navigating away from the 3D editor and back in an SPA host) they
retained references to the disposed Three.js scene graph, which caused
the app to freeze on re-entry as the stale data was replayed against a
fresh scene.

- initSpatialGridSync now returns the unsubscribe handle from its
  scene-store subscription so callers can detach it.
- initializeEditorRuntime becomes reversible: it wires up the spatial
  grid, space detection and SFX bus on mount and returns a teardown
  closure that detaches both store subscriptions, clears the spatial
  grid manager, and truncates the viewer outliner's selected/hovered
  arrays in place.
- The Editor component's runtime-init effect now returns that teardown,
  so the singletons are reset cleanly every time the Editor unmounts.
- initSFXBus is now idempotent via an internal guard so repeated
  Editor mounts do not stack duplicate mitt listeners.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-05 23:37:30 -04:00
Pascal
0bd0cab533
feat: stair system, scene graph utilities, read-only mode, viewer state improvements (#210)
Stair system (full stack):
- New StairNode + StairSegmentNode schemas with flights, landings, L/U-shapes
- StairSystem: geometry generation with throttled per-frame updates
- Stair tool, edit system, panels, tree node, and renderers
- Event bus types, scene registry, and command palette entries

Scene graph utilities:
- cloneLevelSubtree: deep-clone a level with remapped IDs
- forkSceneGraph: clone + strip scan/guide nodes for project forking

Core improvements:
- Read-only mode on scene store (blocks create/update/delete when locked)
- readOnly guards on node-actions and collection actions
- Upload store for scan/guide file upload handling

Viewer state:
- previewSelectedIds for box-select live preview
- hoverHighlightMode (default/delete) for delete-mode hover outline
2026-04-05 01:20:43 -04:00
Clay
08f93f527a
feat(slider): implement infinity dragging using PointerLock API (#206)
Slider controls now use the Pointer Lock API for drag interactions. When dragging a slider label, the cursor locks and movement continues infinitely past the screen edge, matching Unity3D and other professional 3D editors.

- requestPointerLock on drag start, movementX accumulation, exitPointerLock on release
- Falls back to setPointerCapture if PointerLock unavailable
- ESC during drag handled via pointerlockchange listener
- Shift/Ctrl step multipliers preserved
- Undo/redo temporal state correctly managed on all exit paths

Closes #204
2026-04-02 11:26:23 -04:00
Pascal
50eca057ca
feat: editor layout redesign v2 + 3D box select (#207)
Major layout redesign introducing v2 editor layout:

**New Features**
- V2 two-column layout (resizable sidebar + viewer panel with toolbar slots)
- 3D box select tool with marquee selection (561 lines pure Three.js geometry)
- View mode system (3D/2D/Split) replacing old floorplan toggle
- Floating level selector on viewer panel
- Viewer toolbar: level mode, wall mode, units, theme, camera, walkthrough, preview
- Horizontal tab bar for sidebar panels

**Layout Changes**
- Fixed 5-button control bar: Select, Box Select, Site Edit, Build, Delete
- Simplified view toggles (scans/guides only)
- Always-mounted viewers (display:none) to preserve WebGL context
- First-person walkthrough forces 3D view, restores on exit
- Site edit as permanent control (phase='site' is sole signal)

**Technical**
- layoutVersion prop: 'v1' (default) or 'v2'
- New exports: FloatingLevelSelector, SettingsPanel, SidebarTab, ViewMode, ViewerToolbarLeft/Right
- isCollapsed/setIsCollapsed added to sidebar store
- isFirstPersonMode restored for walkthrough support

19 files changed, +3230/-1898
Built and verified: bun run build passes (all tasks, 0 errors)
2026-04-02 11:24:19 -04:00
Pascal
b4d9f3fbf6 fix: resolve type errors in export-system for tsc --build
- Cast scene.clone() to Scene for GLTFExporter compatibility
- Cast DataView.buffer to ArrayBuffer for STL Blob construction
- Add THREE import for Object3D type in traverse callback
2026-03-31 20:54:46 +00:00
Pascal
f2f362eda9 release: @pascal-app/core@0.3.3 @pascal-app/viewer@0.3.3 2026-03-31 20:52:13 +00:00
Pascal
3e05e5aa43
Merge pull request #203 from thiago-lopes-dev/main
feat: implement export scene system (GLB, STL, OBJ)
2026-03-31 16:51:51 -04:00
Pascal
c77a8070e1
Merge pull request #205 from pascalorg/fix/ceiling-transparent-fallback
fix: ceiling transparent by default when no material is set
2026-03-31 16:51:19 -04:00
Pascal
b6636c179b fix: ceiling transparent by default when no material is set
The ceiling renderer was falling back to DEFAULT_CEILING_MATERIAL (an
opaque MeshStandardMaterial) when no material was set on the node.
This made ceilings fully opaque instead of using the intended
transparent grid pattern for scenes created before v0.3.2.

Now uses resolveMaterial() to extract the color from whatever material
config exists (preset, custom, or default white), then always creates
the proper transparent ceiling materials for both faces.
2026-03-31 19:31:46 +00:00
Pascal
e84e870248 release: @pascal-app/core@0.3.2 @pascal-app/viewer@0.3.2 2026-03-30 21:10:55 +00:00