@pascal-app/core 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/agent-operations/__fixtures__/cases.d.ts +3 -2
  2. package/dist/agent-operations/__fixtures__/cases.d.ts.map +1 -1
  3. package/dist/agent-operations/__fixtures__/place-items-cases.d.ts.map +1 -1
  4. package/dist/agent-operations/__fixtures__/place-items-cases.js +28 -0
  5. package/dist/agent-operations/__fixtures__/roof-bearing-cases.d.ts +2618 -2618
  6. package/dist/agent-operations/asset-catalog.d.ts +21 -11
  7. package/dist/agent-operations/asset-catalog.d.ts.map +1 -1
  8. package/dist/agent-operations/asset-catalog.js +28 -10
  9. package/dist/agent-operations/asset-views.d.ts +8 -3
  10. package/dist/agent-operations/asset-views.d.ts.map +1 -1
  11. package/dist/agent-operations/asset-views.js +19 -3
  12. package/dist/agent-operations/batch.d.ts +4 -2
  13. package/dist/agent-operations/batch.d.ts.map +1 -1
  14. package/dist/agent-operations/batch.js +9 -6
  15. package/dist/agent-operations/catalog-asset.d.ts +15 -0
  16. package/dist/agent-operations/catalog-asset.d.ts.map +1 -0
  17. package/dist/agent-operations/catalog-asset.js +4 -0
  18. package/dist/agent-operations/circulation-spaces.d.ts +585 -585
  19. package/dist/agent-operations/design-brief.d.ts.map +1 -1
  20. package/dist/agent-operations/design-brief.js +2 -0
  21. package/dist/agent-operations/furnish-room.d.ts.map +1 -1
  22. package/dist/agent-operations/furnish-room.js +2 -1
  23. package/dist/agent-operations/index.d.ts +5716 -7
  24. package/dist/agent-operations/index.d.ts.map +1 -1
  25. package/dist/agent-operations/index.js +17 -3
  26. package/dist/agent-operations/level-reads.d.ts.map +1 -1
  27. package/dist/agent-operations/level-reads.js +4 -1
  28. package/dist/agent-operations/place-in-room.d.ts.map +1 -1
  29. package/dist/agent-operations/place-in-room.js +2 -1
  30. package/dist/agent-operations/place-items.d.ts.map +1 -1
  31. package/dist/agent-operations/place-items.js +2 -1
  32. package/dist/agent-operations/scene-queries.d.ts +3818 -3818
  33. package/dist/agent-operations/scene-view.d.ts.map +1 -1
  34. package/dist/agent-operations/scene-view.js +38 -13
  35. package/dist/agent-operations/search-assets.d.ts.map +1 -1
  36. package/dist/agent-operations/search-assets.js +6 -0
  37. package/dist/agent-operations/types.d.ts +10 -2
  38. package/dist/agent-operations/types.d.ts.map +1 -1
  39. package/dist/agent-operations/usage-checks.js +18 -3
  40. package/dist/agent-operations/verify-scene.d.ts +7 -3
  41. package/dist/agent-operations/verify-scene.d.ts.map +1 -1
  42. package/dist/agent-operations/verify-scene.js +15 -7
  43. package/dist/agent-tools/assets.js +1 -1
  44. package/dist/building/__fixtures__/wall-opening-cases.d.ts +30 -30
  45. package/dist/building/level-duplication.d.ts +3409 -3409
  46. package/dist/building/level-duplication.d.ts.map +1 -1
  47. package/dist/building/level-duplication.js +3 -1
  48. package/dist/building/wall-openings.d.ts +75 -75
  49. package/dist/commands/structure/shared.d.ts +3407 -3407
  50. package/dist/commands/structure/zone-wall-merge.d.ts +652 -652
  51. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +3818 -3818
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -0
  55. package/dist/lib/__fixtures__/mezzanine.d.ts +2003 -2003
  56. package/dist/lib/absorb-wall-separators.d.ts +1032 -1032
  57. package/dist/lib/asset-storage.d.ts.map +1 -1
  58. package/dist/lib/asset-storage.js +3 -0
  59. package/dist/lib/floor-foundation-datum.d.ts.map +1 -1
  60. package/dist/lib/floor-foundation-datum.js +5 -1
  61. package/dist/lib/floorplan/context.d.ts +95 -0
  62. package/dist/lib/floorplan/context.d.ts.map +1 -0
  63. package/dist/lib/floorplan/context.js +155 -0
  64. package/dist/lib/floorplan/index.d.ts +6 -0
  65. package/dist/lib/floorplan/index.d.ts.map +1 -0
  66. package/dist/lib/floorplan/index.js +5 -0
  67. package/dist/lib/floorplan/marks.d.ts +71 -0
  68. package/dist/lib/floorplan/marks.d.ts.map +1 -0
  69. package/dist/lib/floorplan/marks.js +157 -0
  70. package/dist/lib/floorplan/plan-math.d.ts +18 -0
  71. package/dist/lib/floorplan/plan-math.d.ts.map +1 -0
  72. package/dist/lib/floorplan/plan-math.js +82 -0
  73. package/dist/lib/floorplan/svg-paths.d.ts +17 -0
  74. package/dist/lib/floorplan/svg-paths.d.ts.map +1 -0
  75. package/dist/lib/floorplan/svg-paths.js +92 -0
  76. package/dist/lib/floorplan/wall-affordances.d.ts +31 -0
  77. package/dist/lib/floorplan/wall-affordances.d.ts.map +1 -0
  78. package/dist/lib/floorplan/wall-affordances.js +24 -0
  79. package/dist/lib/steps.d.ts +8 -0
  80. package/dist/lib/steps.d.ts.map +1 -0
  81. package/dist/lib/steps.js +7 -0
  82. package/dist/registry/__fixtures__/roof-planes.d.ts +69 -0
  83. package/dist/registry/__fixtures__/roof-planes.d.ts.map +1 -0
  84. package/dist/registry/__fixtures__/roof-planes.js +59 -0
  85. package/dist/registry/index.d.ts +2 -1
  86. package/dist/registry/index.d.ts.map +1 -1
  87. package/dist/registry/index.js +1 -0
  88. package/dist/registry/roofs.d.ts +34 -0
  89. package/dist/registry/roofs.d.ts.map +1 -0
  90. package/dist/registry/roofs.js +61 -0
  91. package/dist/registry/types.d.ts +30 -0
  92. package/dist/registry/types.d.ts.map +1 -1
  93. package/dist/registry/validate-relations.d.ts +5 -1
  94. package/dist/registry/validate-relations.d.ts.map +1 -1
  95. package/dist/registry/validate-relations.js +6 -2
  96. package/dist/schema/asset-url.d.ts +8 -0
  97. package/dist/schema/asset-url.d.ts.map +1 -1
  98. package/dist/schema/asset-url.js +17 -0
  99. package/dist/schema/nodes/roof.d.ts +1 -1
  100. package/dist/schema/nodes/roof.d.ts.map +1 -1
  101. package/dist/schema/nodes/roof.js +13 -8
  102. package/dist/schema/types.d.ts +1 -1
  103. package/dist/services/roof-level.d.ts.map +1 -1
  104. package/dist/services/roof-level.js +12 -2
  105. package/dist/services/roof-move.d.ts +4 -2
  106. package/dist/services/roof-move.d.ts.map +1 -1
  107. package/dist/services/roof-move.js +21 -9
  108. package/dist/spatial/usage-field/findings.d.ts +10 -1
  109. package/dist/spatial/usage-field/findings.d.ts.map +1 -1
  110. package/dist/spatial/usage-field/findings.js +56 -12
  111. package/dist/spatial/usage-field/measure.d.ts +3 -1
  112. package/dist/spatial/usage-field/measure.d.ts.map +1 -1
  113. package/dist/spatial/usage-field/measure.js +7 -2
  114. package/dist/spatial/usage-field/path.d.ts.map +1 -1
  115. package/dist/spatial/usage-field/path.js +28 -18
  116. package/dist/store/actions/node-actions.d.ts +2380 -2380
  117. package/dist/store/scene-annotations.d.ts +1279 -1279
  118. package/dist/systems/document-reconcile.d.ts.map +1 -1
  119. package/dist/systems/document-reconcile.js +1 -2
  120. package/dist/systems/roof/roof-elevation.d.ts +11 -6
  121. package/dist/systems/roof/roof-elevation.d.ts.map +1 -1
  122. package/dist/systems/roof/roof-elevation.js +24 -11
  123. package/dist/systems/slab/__fixtures__/floor-step.d.ts +2381 -2381
  124. package/dist/systems/slab/__fixtures__/raised-room.d.ts +3818 -3818
  125. package/dist/systems/stair/stair-opening-preview.d.ts +900 -900
  126. package/dist/utils/ensure-scene-openings.d.ts +4815 -4815
  127. package/dist/utils/floor-plate-migration.d.ts +1032 -1032
  128. package/dist/utils/owned-floor-opening-migration.d.ts +1032 -1032
  129. package/dist/utils/reconcile-structure-on-load.d.ts +2380 -2380
  130. package/dist/utils/scene-bounds.d.ts +32 -0
  131. package/dist/utils/scene-bounds.d.ts.map +1 -0
  132. package/dist/utils/scene-bounds.js +201 -0
  133. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"document-reconcile.d.ts","sourceRoot":"","sources":["../../src/systems/document-reconcile.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,kBAAkB,EAGxB,MAAM,4CAA4C,CAAA;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,WAAW,CAAA;AAKnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAWpD,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAStE;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAQzE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,KAAK,OAAO,EAC/C,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C,OAAO,CAST;AAYD,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,CAAA;IACxC,qGAAqG;IACrG,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,kBAAkB,CAAA;CAChC,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,wBAA6B,GACrC,IAAI,CA0FN"}
1
+ {"version":3,"file":"document-reconcile.d.ts","sourceRoot":"","sources":["../../src/systems/document-reconcile.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,kBAAkB,EAGxB,MAAM,4CAA4C,CAAA;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,WAAW,CAAA;AAKnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAWpD,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAStE;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAQzE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,KAAK,OAAO,EAC/C,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C,OAAO,CAST;AAYD,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,CAAA;IACxC,qGAAqG;IACrG,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,kBAAkB,CAAA;CAChC,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,wBAA6B,GACrC,IAAI,CA4FN"}
@@ -142,8 +142,7 @@ export function reconcileDocument(store, before, options = {}) {
142
142
  for (const id in roofsFrom)
143
143
  if (!(id in current))
144
144
  changed.push(id);
145
- const roofInput = (node) => isRoofElevationInput(node) || node?.type === 'roof-segment';
146
- if (changed.some((id) => roofInput(roofsFrom[id]) || roofInput(current[id]))) {
145
+ if (changed.some((id) => isRoofElevationInput(roofsFrom[id]) || isRoofElevationInput(current[id]))) {
147
146
  const roofs = [
148
147
  ...roofsKeptOverStorey(roofsFrom, view()),
149
148
  ...planRoofElevationUpdates(view(), roofsAffectedBy(roofsFrom, current, changed)),
@@ -3,10 +3,14 @@ export declare function resolveRoofWallTopElevation(targetLevelId: LevelNode['id
3
3
  export declare function resolveRoofElevation(roof: RoofNode, nodes: Readonly<Record<string, AnyNode>>): number;
4
4
  /**
5
5
  * The tallest top of `levelId`'s walls a roof stands on, from the floor of the level holding the
6
- * roof (m); null when it stands on none of them, or has no segments to stand with.
6
+ * roof (m); null when it stands on none of them, or has neither segments nor faces to stand with.
7
7
  */
8
8
  export declare function roofWallTop(roof: RoofNode, nodes: Readonly<Record<string, AnyNode>>, levelId: string): number | null;
9
- /** Kinds whose change can move a wall-supported roof. */
9
+ /**
10
+ * Nodes whose change can move a wall-supported roof: the roof, what it is made of (its segments and
11
+ * its faces, `capabilities.roofs`, whose footprints find its walls) and what it stands on. The one
12
+ * test the live sync and `reconcileDocument` both go by.
13
+ */
10
14
  export declare function isRoofElevationInput(node: AnyNode | undefined): boolean;
11
15
  /** Wall-supported roofs whose stored Y no longer sits on their walls, and where it should. */
12
16
  export declare function planRoofElevationUpdates(nodes: Readonly<Record<string, AnyNode>>, only?: ReadonlySet<string> | null): Array<{
@@ -15,10 +19,11 @@ export declare function planRoofElevationUpdates(nodes: Readonly<Record<string,
15
19
  }>;
16
20
  /**
17
21
  * The roofs an edit can move, from the nodes it changed. A roof rests on the walls of its own level
18
- * or the level below, so: a changed roof (or segment); for a changed wall, the roofs on its level
19
- * and the level above; for a changed slab, the levels whose walls it touches (its own, which it
20
- * carries, and the one below, whose plane-bound tops it caps) and every level above it in its
21
- * building (a base plate lifts them). Null, for every roof, when a level, building or site changed.
22
+ * or the level below, so: a changed roof (or segment, or face); for a changed wall, the roofs on
23
+ * its level and the level above; for a changed slab, the levels whose walls it touches (its own,
24
+ * which it carries, and the one below, whose plane-bound tops it caps) and every level above it in
25
+ * its building (a base plate lifts them). Null, for every roof, when a level, building or site
26
+ * changed.
22
27
  */
23
28
  export declare function roofsAffectedBy(before: Readonly<Record<string, AnyNode>>, after: Readonly<Record<string, AnyNode>>, changedIds: Iterable<string>): Set<string> | null;
24
29
  //# sourceMappingURL=roof-elevation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"roof-elevation.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-elevation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,QAAQ,EAER,QAAQ,EACT,MAAM,cAAc,CAAA;AAarB,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,EAC9B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,UAAU,8CAA4B,GACrC,MAAM,CAUR;AAwFD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACvC,MAAM,CAiCR;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAQf;AAID,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CASvE;AAED,8FAA8F;AAC9F,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,KAAK,CAAC;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAYlD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAkCpB"}
1
+ {"version":3,"file":"roof-elevation.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-elevation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,QAAQ,EAER,QAAQ,EACT,MAAM,cAAc,CAAA;AAarB,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,EAC9B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,UAAU,8CAA4B,GACrC,MAAM,CAUR;AA2FD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACvC,MAAM,CAiCR;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAQf;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAWvE;AAED,8FAA8F;AAC9F,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,KAAK,CAAC;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAYlD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAuCpB"}
@@ -1,5 +1,6 @@
1
1
  import { findLevelAncestorId, resolveLevelId } from '../../lib/node-ancestry.js';
2
2
  import { wallSupportForNodes } from '../../lib/opening-floor-datum.js';
3
+ import { roofFaceOf, roofFaceShapes } from '../../registry/roofs.js';
3
4
  import { queryNodes } from '../../runtime/node-queries.js';
4
5
  import { isRailingWall } from '../../schema/nodes/railing-wall.js';
5
6
  import { coveredStoreyId, servesAsRoofLevel } from '../../services/roof-level.js';
@@ -16,15 +17,17 @@ export function resolveRoofWallTopElevation(targetLevelId, wall, nodes, elevatio
16
17
  return sourceLevelY + top - targetLevelY;
17
18
  }
18
19
  /**
19
- * The walls among `wallIds` a roof stands on: those under its segments' footprints, closed room or
20
- * not (a room missing a wall, an L-shaped room whose centre falls outside, or a redrawn enclosure
21
- * all still hold the roof up); a cone's, its round wall. Null for a roof with no segments yet.
20
+ * The walls among `wallIds` a roof stands on: those under its segments' footprints and its faces'
21
+ * outlines (`capabilities.roofs`), closed room or not (a room missing a wall, an L-shaped room whose
22
+ * centre falls outside, or a redrawn enclosure all still hold the roof up); a cone's, its round
23
+ * wall. Null for a roof with neither segments nor faces yet.
22
24
  */
23
25
  function wallsUnderRoof(roof, nodes, wallIds) {
24
26
  const segments = roof.children
25
27
  .map((id) => nodes[id])
26
28
  .filter((node) => node?.type === 'roof-segment');
27
- if (segments.length === 0)
29
+ const faces = roofFaceShapes(roof, nodes).map((face) => face.outline);
30
+ if (segments.length === 0 && faces.length === 0)
28
31
  return null;
29
32
  const cos = Math.cos(roof.rotation);
30
33
  const sin = Math.sin(roof.rotation);
@@ -62,6 +65,7 @@ function wallsUnderRoof(roof, nodes, wallIds) {
62
65
  ];
63
66
  return corners.map(([x, z]) => toLevel(segment.position[0] + x * c + z * s, segment.position[2] - x * s + z * c));
64
67
  });
68
+ footprints.push(...faces);
65
69
  return wallIds.filter((id) => {
66
70
  const wall = nodes[id];
67
71
  return (wall?.type === 'wall' &&
@@ -117,7 +121,7 @@ export function resolveRoofElevation(roof, nodes) {
117
121
  }
118
122
  /**
119
123
  * The tallest top of `levelId`'s walls a roof stands on, from the floor of the level holding the
120
- * roof (m); null when it stands on none of them, or has no segments to stand with.
124
+ * roof (m); null when it stands on none of them, or has neither segments nor faces to stand with.
121
125
  */
122
126
  export function roofWallTop(roof, nodes, levelId) {
123
127
  const level = nodes[levelId];
@@ -129,9 +133,15 @@ export function roofWallTop(roof, nodes, levelId) {
129
133
  return (highestWallTop(resolveLevelId(roof, nodes), wallIds, nodes, getLevelElevations(nodes)) ?? null);
130
134
  }
131
135
  const ROOF_ELEVATION_EPSILON = 1e-4;
132
- /** Kinds whose change can move a wall-supported roof. */
136
+ /**
137
+ * Nodes whose change can move a wall-supported roof: the roof, what it is made of (its segments and
138
+ * its faces, `capabilities.roofs`, whose footprints find its walls) and what it stands on. The one
139
+ * test the live sync and `reconcileDocument` both go by.
140
+ */
133
141
  export function isRoofElevationInput(node) {
134
142
  return (node?.type === 'roof' ||
143
+ node?.type === 'roof-segment' ||
144
+ roofFaceOf(node) !== undefined ||
135
145
  node?.type === 'wall' ||
136
146
  node?.type === 'slab' ||
137
147
  node?.type === 'level' ||
@@ -156,10 +166,11 @@ export function planRoofElevationUpdates(nodes, only) {
156
166
  }
157
167
  /**
158
168
  * The roofs an edit can move, from the nodes it changed. A roof rests on the walls of its own level
159
- * or the level below, so: a changed roof (or segment); for a changed wall, the roofs on its level
160
- * and the level above; for a changed slab, the levels whose walls it touches (its own, which it
161
- * carries, and the one below, whose plane-bound tops it caps) and every level above it in its
162
- * building (a base plate lifts them). Null, for every roof, when a level, building or site changed.
169
+ * or the level below, so: a changed roof (or segment, or face); for a changed wall, the roofs on
170
+ * its level and the level above; for a changed slab, the levels whose walls it touches (its own,
171
+ * which it carries, and the one below, whose plane-bound tops it caps) and every level above it in
172
+ * its building (a base plate lifts them). Null, for every roof, when a level, building or site
173
+ * changed.
163
174
  */
164
175
  export function roofsAffectedBy(before, after, changedIds) {
165
176
  const roofs = new Set();
@@ -173,7 +184,9 @@ export function roofsAffectedBy(before, after, changedIds) {
173
184
  return null;
174
185
  if (node.type === 'roof')
175
186
  roofs.add(id);
176
- else if (node.type === 'roof-segment' && node.parentId)
187
+ else if (node.parentId &&
188
+ (node.type === 'roof-segment' ||
189
+ (roofFaceOf(node) && nodes[node.parentId]?.type === 'roof')))
177
190
  roofs.add(node.parentId);
178
191
  else if (node.type === 'wall' || node.type === 'slab') {
179
192
  const levelId = findLevelAncestorId(id, nodes);