Fix corner split exterior walls

Issue: #123
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-08-13 18:55:49 +00:00
committed by claude[bot]
parent 7af4146614
commit 955de3e69c
18 changed files with 1234 additions and 647 deletions
+14
View File
@@ -326,6 +326,20 @@ its types declare named exports — breaking either tsc or the runtime): merge a
when the union collapses into one hole-free outline; split cuts wall-to-wall with a chord, the
bigger part keeps the room identity (name/area/devices).
`wallBodiesGeometry()` is the canonical physical masonry for flat full/static
rendering, hidden isometric projection and Glow/sun occlusion. Its exterior
shell is derived from the union of room centrelines plus the surviving `outer`
atomic intervals; internal/shared interval bodies are clipped to that union
before the shell is restored. Consequently a Split edge ending at an exterior
vertex cannot contribute a child-room mitre to the facade. Per-room rings remain
an interior join/nested-room representation, and atomic quads provide a safe
physical interval when an acute child ring cannot be subtracted. Paper and
masonry paths are emitted by that same geometry pass. The full card retains the
pair in `_wallUnionCache`; static cards retain it in a weak server-snapshot
cache guarded by a structural geometry fingerprint. This is computed render
state only: it never rewrites rooms or wall entries, and an HA state tick does
not rebuild topology.
## Markup editor (v1.4.0+)
State inside the card: `_markup` (mode), `_tool` (draw/partition/column/merge/split/resize/opening/
+6
View File
@@ -2,6 +2,12 @@
## Unreleased
- Splitting a room from an existing corner no longer deforms the exterior wall
or pulls a thick internal divider through the facade. Plan, View, kiosk,
static cards, hidden isometric rendering and light obstacles now use the same
preserved exterior geometry, including already saved plans
([#123](https://github.com/Matysh/houseplan-card/issues/123)).
## v1.63.0-beta.1 — 2026-08-13
- Deleting a standalone sensor or lock marker no longer breaks its explicit
+6
View File
@@ -8,6 +8,12 @@
## Unreleased
- Split из существующего угла комнаты больше не деформирует наружную стену и
не вытягивает толстый внутренний разделитель сквозь фасад. Редактор плана,
View, киоск, статичная карточка, скрытая изометрия и световые препятствия
используют одну сохранённую наружную геометрию, в том числе для уже
сохранённых планов ([#123](https://github.com/Matysh/houseplan-card/issues/123)).
## v1.63.0-beta.1 — 2026-08-13
- Удаление самостоятельного маркера датчика или замка больше не разрывает его
+1 -1
View File
@@ -22,7 +22,7 @@ metadata). Only an explicit owner-approved emergency hotfix may skip this gate.
| Item | State |
|---|---|
| Version | **v1.63.0-beta.1** everywhere (manifest, const.py, package.json, CARD_VERSION) — prerelease candidate |
| Current local cycle | v1.63.0-beta.1 fixes the empty-plan crash (#111) and preserves explicit opening sensor/lock references after standalone marker deletion (#104). It also carries the reviewed process automation work #105 and #118–#121. |
| Current local cycle | v1.63.0-beta.1 fixes the empty-plan crash (#111) and preserves explicit opening sensor/lock references after standalone marker deletion (#104). Development after that beta preserves the exterior facade when Split starts or ends at a room corner (#123), using one wall geometry for flat/static/isometric rendering and light. The line also carries the reviewed process automation work #105 and #118–#121. |
| Hidden Labs Stage | #89 Stage 1 ships in v1.63.0-beta.1 as a hidden, expiring `iso` Labs experiment: a fixed near-top orthographic volumetric View. Flat remains default; editors and `houseplan-space-card` remain flat; all existing floor live effects and HA actions are preserved. This is internal, not a public feature. |
| Workflow | Owner's rule since 2026-08-07: ordinary fixes/features are made **locally, without tests and without commits**. A requested pre-release gets a production build plus the smallest targeted unit/smoke set covering the changed surfaces, one tested `dev` commit/tag and a GitHub Release with `prerelease=true`; `main` stays untouched. The complete local frontend/backend/smoke gate runs only before a stable release, after which `main` is fast-forwarded to the exact tested `dev` SHA and the GitHub Release uses `prerelease=false`. Release bodies are short and bilingual (Russian first): only significant user changes get individual bullets, while minor/code-only work is grouped as `Мелкие исправления и улучшения` / `Small fixes and improvements`; every body ends with separate links to the Russian and English changelogs. Detailed RU/EN changelog bullets may link the corresponding closed GitHub Issues; open or partially delivered issues are never presented as shipped. Telegram announcements are sent only for stable releases; beta and RC publication is silent. `docs/RELEASE-NOTES.md` is the current canonical body instance; `npm run release:prerelease -- <tag> --issues=… --yes` is the primary local publication path and the manual `Publish prerelease` workflow is its GitHub-only equivalent once present on `main`. Nothing is copied to the home instance by hand |
| GitHub | https://github.com/Matysh/houseplan-card — [Issues](https://github.com/Matysh/houseplan-card/issues) are the canonical task records and the linked [Project v2](https://github.com/users/Matysh/projects/1) is the canonical priority/status view; both must stay current. `main` carries stable releases; pre-release tags may point directly at `dev`. Work lands on `dev` and is merged into `main` for a stable release, so `dev` is normally equal to or ahead of `main`, never behind. Push via SSH key `ha_jb` (remote git@github.com:…); API releases via the fine-grained PAT in `~/.git-credentials` (Contents R/W, issued 2026-07-23) |
+3
View File
@@ -304,6 +304,9 @@ desktop: для точного рисования, Resize, модификато
- Промежуточные точки должны идти внутри комнаты и не пересекать контур или сам разрез.
- Большая по площади часть сохраняет исходную комнату и устройства.
- Для меньшей части открывается диалог новой комнаты.
- Разрез можно начать или закончить точно в существующем углу. Наружная форма
дома при этом не меняется: общая стена двух новых комнат примыкает к фасаду
только изнутри, даже если она толще наружной стены.
### Resize
+16 -2
View File
@@ -42,6 +42,17 @@ Every thick wall grows **half outward and half inward** from the polygon edge
(outer and shared alike). Silhouette is wider than the polygon by `cm/2` on
outer walls. Paper and the content frame grow under that outer half.
The exterior silhouette is generated from the boolean union of room
centrelines and its surviving `outer` atomic intervals. A shared Split edge
therefore disappears before exterior mitres are built. When Split ends at an
existing corner, its divider is clipped to the interior side of this envelope:
the real exterior mitre/bevel and unequal arm depths stay unchanged, while any
divider thickness remains inside the facade. The same computed geometry is
used for the full/static/hidden-isometric renderers and light occlusion. The
paper and masonry paths come from one cached structural pass in flat renderers;
live HA state ticks do not repeat the boolean topology. Saved room and wall data
is not migrated or rewritten.
## 3. Body render
Production body is the **ring** `outset(poly, half) − inset(poly, half)` per
@@ -132,14 +143,17 @@ virtual-T mitre; angle-aware opening; 45° wall; T-junction; detached parallel
room; nested-room tie; partially out-of-span legacy opening; overlapping
opening de-duplication; shared symbol/cut/tunnel rejection; thick-door tunnel
clipping and room-side colour ownership; whole and
atomic rekey after edge/scale.
atomic rekey after edge/scale; corner Split exterior equality across
0/1/15/100 cm, unequal arms, both windings and convex/concave endpoints.
Browser: seamless frame; fill not in hatch; m² drops with thickness; a partial
virtual stretch, its solid thick remainders and Undo move as one real resize;
the virtual rubber band paints above the real body; sun starts at the room-side
opening corners; nav mode restores after `can_write`; a 1 cm body uses
solid-only in both full and static cards while a 20 cm body keeps its hatch;
door/window/gate tunnels repeat outer/shared room fills without an axis seam
(`demo/smoke_opening_tunnel_fill.mjs`).
(`demo/smoke_opening_tunnel_fill.mjs`); corner Split keeps the same facade in
Plan/View/kiosk/static/isometric surfaces and the light barrier
(`demo/smoke_split_corner_wall.mjs`).
## 9. Independent partitions, drafts and columns
+4 -3
View File
@@ -290,9 +290,10 @@ View и киоск полностью поддерживаются: исправ
- **AC10 (`unit`):** обычный Split от середины стены, wall materialisation,
partial shared intervals, virtual-T mitre, openings и independent partitions
сохраняют действующее поведение.
- **AC11 (`performance` + ревью кода):** новый exterior/shared расчёт использует
существующее geometry caching; HA state tick не пересчитывает topology, а
общий pre-beta performance gate остаётся зелёным.
- **AC11 (ревью кода):** новый exterior/shared расчёт использует существующее
geometry caching; HA state tick не пересчитывает topology. Существующие
`performance_smoke` и large-house benchmark остаются общим предрелизным
подтверждением, а не отдельным типом доказательства AC.
- **AC12 (`typecheck` + `unit` + `build`):** быстрые гейты зелёные; три bundle
snapshot побайтно совпадают.
- **AC13 (ревью документации):** RU/EN changelog и пользовательские документы