mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 22:49:16 +00:00
committed by
claude[bot]
parent
b860ef4c43
commit
087f7cf381
+14
-1
@@ -318,6 +318,16 @@ physical bodies are unioned with room walls for rendering and light occlusion,
|
||||
and subtracted from clean room floor area. Openings (doors, windows and gates)
|
||||
still belong only to derived room walls and never cut an independent object.
|
||||
|
||||
Independent linear objects have two deliberate projections. Raw flat-capped
|
||||
quads preserve source identity for hit/selection/drag/properties/delete/history
|
||||
and furniture magnet behaviour. `physicalBodySet()` also derives exact
|
||||
endpoint↔endpoint and endpoint↔line topology, adds bounded mitre/bevel patches
|
||||
without persisted nodes or segment splits, and exposes the joined geometry to
|
||||
presentation and physics. Degree-one caps remain flat; an interior X crossing
|
||||
is only a boolean overlap. The full card caches this structural frame by
|
||||
space/config geometry, while static cards use a weak server-snapshot cache;
|
||||
cursor and HA state updates do not repeat the saved O(N²) node search.
|
||||
|
||||
Rooms may not overlap
|
||||
(`pointStrictlyInside` + `roomsOverlap`; being ON a shared wall is legal — real neighbouring
|
||||
walls overlap collinearly rather than match exactly). **Merge/Split** use boolean geometry from
|
||||
@@ -334,7 +344,10 @@ 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
|
||||
masonry paths are emitted by that same geometry pass. Computed independent
|
||||
junction patches enter as extras only after room opening cuts, so an opening
|
||||
cannot cut a coincident partition and room exterior authority remains intact.
|
||||
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
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Connected Room outline and Partition segments now form one seamless thick
|
||||
wall immediately, including the live rubber-band. Right and oblique corners
|
||||
use bounded mitre/bevel joins, T-connections have no visible butt face, each
|
||||
segment keeps its own thickness, and free ends remain flat consistently in
|
||||
Plan, View, static cards, hidden isometric, clean-floor and light geometry
|
||||
([#141](https://github.com/Matysh/houseplan-card/issues/141)).
|
||||
- Room outline and Partition drawing now shows wall centre lines and exact
|
||||
endpoints above existing walls. The enlarged target previews whether the
|
||||
next click will join an endpoint or create a wall-bound T-connection, while
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Соединённые отрезки «Контура комнаты» и «Перегородки» теперь сразу, включая
|
||||
активный rubber-band, образуют одну бесшовную толстую стену. Прямые и косые
|
||||
углы получают ограниченный mitre/bevel, T-соединение не показывает торец,
|
||||
каждый отрезок сохраняет свою толщину, а свободные концы остаются плоскими в
|
||||
Plan, View, статичной карточке, скрытой изометрии, чистой площади и световой
|
||||
геометрии ([#141](https://github.com/Matysh/houseplan-card/issues/141)).
|
||||
- При рисовании инструментами «Контур комнаты» и «Перегородка» поверх
|
||||
существующих стен теперь видны их осевые линии и точные конечные узлы.
|
||||
Увеличенная точка заранее показывает соединение с концом стены или создание
|
||||
|
||||
@@ -53,6 +53,11 @@ physical bodies have been resolved. It normalizes outer/hole winding, builds one
|
||||
evenodd top path and at most one visible side per ring edge, then uses a stable
|
||||
depth/order tie-break. Complexity is O(E) in canonical ring edges.
|
||||
|
||||
For connected drafts and partitions those extras already contain computed
|
||||
bounded junction patches. Isometric wall tops/sides therefore use the same
|
||||
seamless L/T footprint as flat full/static cards; raw per-record rectangles are
|
||||
reserved for editor identity and never projected as competing wall faces.
|
||||
|
||||
The content fingerprint includes rooms, wall geometry/thickness, open cuts,
|
||||
openings, partitions, drafts, columns, scale/grid inputs, camera, wall height and
|
||||
algorithm version. It deliberately excludes `_cfgEpoch`, HA state, hover and
|
||||
|
||||
+9
-1
@@ -26,7 +26,9 @@ plan geometry and shares it between every lamp in the space.
|
||||
|
||||
- the wall bodies exactly as the plan draws them (`wallBodiesGeometry`), with
|
||||
their real thickness and mitred junctions;
|
||||
- independent bodies: partitions, columns, room drafts;
|
||||
- independent bodies: partitions, columns and room drafts. Exact connected
|
||||
draft/partition segments enter as one joined volume, not as raw rectangles
|
||||
whose former butt faces could become false barriers;
|
||||
- the bare outline of any room edge that carries no thickness — a wall is still
|
||||
a wall when it is drawn as a line.
|
||||
|
||||
@@ -107,6 +109,12 @@ set is invisible — the plan simply keeps lighting through a wall that now
|
||||
exists. The same fingerprint, plus position and radius, keys the per-source
|
||||
region cache (`_glowClipCache`).
|
||||
|
||||
The masonry boolean receives room walls after passage cuts plus the cached
|
||||
joined independent body set. Its outer/hole rings are the authoritative
|
||||
barriers for both visibility and the fail-dark source guard. A boolean failure
|
||||
falls back to the raw independent bodies as opaque obstacles; it never turns a
|
||||
malformed wall transparent.
|
||||
|
||||
## Source, state and service identity
|
||||
|
||||
The geometry above consumes `resolvedLightSources()`; it never discovers light
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ metadata). Only an explicit owner-approved emergency hotfix may skip this gate.
|
||||
| Item | State |
|
||||
|---|---|
|
||||
| Version | **v1.64.0-beta.1** everywhere (manifest, const.py, package.json, CARD_VERSION) — prerelease candidate on the v1.63.0 stable base |
|
||||
| Current local cycle | v1.64.0-beta.1 packages the merged #122 hidden isometric Stage 2, #131 read-only cold-start fix and #107 persistent virtual-light toggles. The independent #124 exact-SHA view-toggle performance debt remains open under the owner's accepted exception. |
|
||||
| Current local cycle | v1.64.0-beta.1 packages the merged #122 hidden isometric Stage 2, #131 read-only cold-start fix and #107 persistent virtual-light toggles. Issue #141 is in implementation on its issue branch: connected draft/partition L and T nodes now use one computed joined wall volume across flat/static/hidden-iso, clean-floor and light consumers while raw objects retain editor identity; Linux smoke/golden/performance remain pre-release gates. The independent #124 exact-SHA view-toggle performance debt remains open under the owner's accepted exception. |
|
||||
| Hidden Labs Stage | #89 Stage 1 ships in v1.63.0-beta.1. #122 Stage 2 is included in the v1.64.0-beta.1 candidate and evolves the same hidden, expiring `iso` experiment with matte walls, a low exterior floor edge, restrained shared shadows and live vertical door/window/gate panels. Flat remains default; editors and `houseplan-space-card` remain flat; live floor effects and HA actions remain unchanged. Public activation is explicitly a separate task. |
|
||||
| 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; their labels carry priority and workflow status (`PROCESS.md` §9). GitHub Projects is no longer used. `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) |
|
||||
|
||||
@@ -2089,6 +2089,16 @@ require hands on real hardware — they remain for the human pass.
|
||||
source inside masonry lights nothing. Window rays are blocked by the same
|
||||
bodies. `show_borders: false` changes paint only [auto:
|
||||
physical-geometry.test; manual visual].
|
||||
- [ ] **Seamless junctions**: saved draft/partition L corners (right, acute and
|
||||
obtuse), unequal thickness, endpoint-on-line T and a branch touching a
|
||||
room wall use one bounded joined body; near-miss, X crossing, malformed
|
||||
segments and flat free caps keep their documented semantics. The active
|
||||
rubber-band has the same contour before and after commit, target records
|
||||
are not split, Plan/View/static/hidden-iso paths agree, clean floor and
|
||||
light use the joined corner, and preview/render never writes config
|
||||
[auto: wall-thickness.test, physical-geometry.test,
|
||||
smoke_wall_junctions, wall-junctions golden scenarios; manual golden
|
||||
artifact review].
|
||||
- [ ] **Lifecycle/performance**: an external config revision cancels live
|
||||
move/rotate state before replacing geometry. Drag preview performs no
|
||||
polygon boolean work; clean floor and Glow clips are reused until the
|
||||
|
||||
@@ -275,6 +275,13 @@ desktop: для точного рисования, Resize, модификато
|
||||
предпросмотра рекомендуется редактор на компьютере; tap на сенсорном экране
|
||||
тоже выполняет привязку, но отдельный hover до касания не показывается.
|
||||
|
||||
Толстые отрезки, соединённые в такой точке, сразу показываются как одна стена:
|
||||
прямые и косые углы получают ограниченный mitre/bevel без зуба или щели, а
|
||||
T-соединение входит в проходящую стену без видимого торца. Это действует уже у
|
||||
активного rubber-band до клика и сохраняется после клика, в View и на статичной
|
||||
карточке. Толщина каждого ранее поставленного отрезка остаётся своей; свободный
|
||||
конец незамкнутой стены остаётся плоским.
|
||||
|
||||
Каждый законченный отрезок незамкнутого контура сохраняется сразу. В той же
|
||||
сессии инструмент продолжит его автоматически; после перезагрузки выберите
|
||||
кликом один из концов. Замкнутый контур можно сохранить как комнату или выбрать
|
||||
@@ -345,6 +352,7 @@ Glow и солнечные лучи, но при Resize комнаты оста
|
||||
| Общая стена | Одна физическая стена между комнатами |
|
||||
| Чистая площадь | Считается по внутренней грани стен |
|
||||
| Углы | Соседние тела стен соединяются; на малом масштабе штриховка скрывается, тело остаётся |
|
||||
| Независимые стыки | Контуры и перегородки с точным общим узлом образуют один ограниченный mitre/bevel; T-стык не дробит исходную стену |
|
||||
| Соседние одинаковые участки | Нормализуются в один участок при редактировании/оптимизации |
|
||||
| Виртуальный участок | Не имеет тела и толщины; реальные остатки сохраняют свою толщину |
|
||||
|
||||
|
||||
@@ -65,6 +65,15 @@ thinner than 3 CSS px on screen, the shared full/static render policy suppresses
|
||||
only the hatch so it does not collapse into noise; the solid fill remains. Mitre
|
||||
joins; bevel when the mitre spike exceeds `MITRE_LIMIT × thickness`.
|
||||
|
||||
Independent draft/partition segments keep flat raw quads for editor identity,
|
||||
but exact endpoint↔endpoint and endpoint↔line nodes add computed join patches
|
||||
before the presentation union. Each incident ray keeps its own half-depth;
|
||||
ordinary corners use the same bounded `MITRE_LIMIT = 4` rule and excessive
|
||||
spikes become bevels. A degree-one endpoint receives no patch and therefore
|
||||
keeps its flat cap. This topology is render-only: a T does not split or rewrite
|
||||
the saved target segment. The live open-outline/rubber-band preview calls the
|
||||
same primitive with saved per-segment thicknesses plus the current field value.
|
||||
|
||||
Openings cut the body full-depth; jambs cap the cut; window glass mid-tunnel;
|
||||
door swing from the **inner face**. Association uses wall direction ≈ opening
|
||||
angle (mod 180°), then nearest span — never a perpendicular neighbour at a T.
|
||||
@@ -167,3 +176,13 @@ occlusion even when borders are hidden. A source inside/on a physical body is
|
||||
fully occluded instead of leaking around its own masonry. The same fail-dark
|
||||
placement rule applies to window tunnels and exterior door/gate openings;
|
||||
interior passages remain valid source positions (#92).
|
||||
|
||||
`physicalBodySet()` separates raw draft/partition/column bodies from computed
|
||||
junction patches and their joined geometry. Raw bodies remain authoritative for
|
||||
hit testing, selection, drag, properties, deletion, history and furniture
|
||||
magnet semantics. Flat full/static render, hidden isometric, clean floor, Glow,
|
||||
sun and source placement consume the joined set through the canonical masonry
|
||||
pass, so an old butt face cannot become a visible seam or a false light barrier.
|
||||
Exact near-misses remain separate, an interior↔interior X crossing keeps normal
|
||||
boolean-union semantics, and malformed legacy segments fall back opaque without
|
||||
writing configuration.
|
||||
|
||||
Reference in New Issue
Block a user