perf: reuse clean room areas in PDF

Issue: #53
User-Visible: no
This commit is contained in:
Matysh
2026-09-07 04:46:20 +03:00
parent 008efbe920
commit 137616fa62
41 changed files with 330 additions and 303 deletions
+5
View File
@@ -10690,6 +10690,7 @@ export class HouseplanCard extends LitElement {
}
const sharedWallGeometry = this._wallUnionGeometry();
const openCuts = this._openCuts();
const roomsById = new Map(space.rooms.flatMap((room) => room.id ? [[room.id, room]] : []));
return runtime.render({
config: this._serverCfg,
rawSpace,
@@ -10705,6 +10706,10 @@ export class HouseplanCard extends LitElement {
resolveInnerContour: (roomId) => this._innerRoomContour(
space, roomId, openCuts, sharedWallGeometry?.roomGeom, sharedWallGeometry?.multiWallNodes,
),
resolveRoomArea: (roomId, contour) => {
const room = roomsById.get(roomId);
return room ? this._cleanFloor(room, contour, space).area : undefined;
},
t: (key, vars) => this._t(key as I18nKey, vars),
toast: (message) => this._showToast(message),
close: () => { this._pdfDialog = false; this.requestUpdate(); },
+1
View File
@@ -19,6 +19,7 @@ export interface PdfDialogContext {
decorAssets: ReadonlyMap<string, PdfAssetReference>;
sharedWallGeometry?: PdfSharedWallGeometry | null;
resolveInnerContour?: (roomId: string) => number[][] | null | undefined;
resolveRoomArea?: (roomId: string, contour: number[][]) => number | undefined;
t: (key: string, vars?: Record<string, string | number>) => string;
toast: (message: string) => void;
close: () => void;
+9 -3
View File
@@ -70,6 +70,8 @@ export interface PdfSceneInput {
sharedWallGeometry?: PdfSharedWallGeometry | null;
/** The visible card's per-room clean-floor cache, resolved only when dimensions are requested. */
resolveInnerContour?: (roomId: string) => number[][] | null | undefined;
/** Area in render units from the same clean-floor cache used by the visible card. */
resolveRoomArea?: (roomId: string, contour: number[][]) => number | undefined;
}
const MM = 72 / 25.4;
@@ -383,11 +385,15 @@ export function buildPdfPage(input: PdfSceneInput): PdfPage & { scale: number }
const original = roomPoly(room);
if (!original) continue;
const contour = dimensionContours.get(room) || original;
const localBodies = input.options.dimensions
const cachedArea = input.options.dimensions && room.id
? input.resolveRoomArea?.(room.id, contour) : undefined;
const localBodies = input.options.dimensions && !Number.isFinite(cachedArea)
? bodiesOverlappingRing(contour, built.extras) : [];
const candidates = localBodies.length ? floorMinusBodies(contour, localBodies) : null;
const areaUnits = candidates ? geometryArea(candidates) : Math.abs(
contour.reduce((sum, p, i) => { const q = contour[(i + 1) % contour.length]; return sum + p[0] * q[1] - q[0] * p[1]; }, 0) / 2);
const areaUnits = Number.isFinite(cachedArea) && (cachedArea as number) >= 0
? cachedArea as number
: candidates ? geometryArea(candidates) : Math.abs(
contour.reduce((sum, p, i) => { const q = contour[(i + 1) % contour.length]; return sum + p[0] * q[1] - q[0] * p[1]; }, 0) / 2);
const label = labelPos(room, input.space.id, input.layout, input.config);
const [labelX, labelY] = pt([label.x, label.y]);
const pageContour = contour.map(pt);